fix(home): move dialog out of 9:16 canvas so it stays screen-fixed

The home dialog used bottom-[15.8%] inside the 9:16 canvas, whose height scales with width (h = w*16/9), so the dialog drifted vertically as viewport width changed. Moved the dialog block to the screen-container layer beside the tab bar, so it now shares the tab's screen-relative anchoring and no longer moves with width.
This commit is contained in:
km2023
2026-06-30 15:15:46 +08:00
parent ab230d6cfb
commit cd83c358cf

View File

@@ -488,82 +488,6 @@ export function HomePage({
</button>
) : null}
{activeDialog ? (
<div
className={`absolute inset-x-[4%] bottom-[15.8%] z-40 ${
activeDialog.kind === 'idle'
? 'pointer-events-auto'
: 'pointer-events-none'
}`}
key={`${activeDialog.kind}-${activeDialog.text}`}
>
{activeDialog.kind === 'idle' ? (
<button
className="absolute right-[13%] top-0 z-30 border-0 bg-transparent p-0 text-[10px] font-normal leading-none text-white drop-shadow-[0_1px_4px_rgba(8,22,64,0.82)] transition hover:text-white active:scale-[0.98]"
onClick={(event) => {
event.stopPropagation()
setActiveDialog(null)
}}
type="button"
>
</button>
) : null}
<div
className={`relative min-h-[128px] overflow-hidden rounded-[10px] px-7 pb-5 pt-7 text-left [font-family:'Microsoft_YaHei_UI','Microsoft_YaHei',sans-serif] ${
activeDialog.kind === 'idle'
? 'animate-[home-idle-dialog-enter_360ms_cubic-bezier(0.2,0.82,0.24,1)]'
: 'animate-[home-dialog-float_2500ms_ease-out_both]'
}`}
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-75"
draggable={false}
src={homeDialogBoxImage}
/>
<span
className={`z-10 block text-[14px] font-normal leading-[1.75] tracking-[0.04em] text-white [font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif] [text-shadow:1px_1.5px_0_rgba(0,0,0,0.72),0_0_1px_rgba(0,0,0,0.38)] ${
activeDialog.kind === 'idle'
? 'relative mt-4 max-w-[82%]'
: 'absolute left-7 top-1/2 w-[80%] -translate-y-1/2'
}`}
>
{activeDialog.text}
</span>
</div>
{activeDialog.kind === 'idle' ? (
<div className="mx-auto mt-1.5 flex w-[78%] animate-[home-idle-dialog-enter_360ms_cubic-bezier(0.2,0.82,0.24,1)] flex-col gap-1.5">
{activeDialog.choices.map((choice) => (
<button
className="group relative min-h-[31px] overflow-hidden rounded-[8px] border-0 bg-transparent px-0 py-0 text-left font-normal text-white shadow-[0_8px_18px_rgba(0,0,0,0.2)] transition active:scale-[0.99] [font-family:'Microsoft_YaHei_UI','Microsoft_YaHei',sans-serif]"
key={choice.label}
onClick={(event) => {
event.stopPropagation()
handleDialogChoice(choice)
}}
type="button"
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-85 transition group-hover:opacity-85"
draggable={false}
src={homeChoiceBoxImage}
/>
<span
className="absolute z-10 flex items-center justify-center overflow-hidden text-center text-[12px] leading-none tracking-[0.04em] drop-shadow-[0_1px_4px_rgba(0,0,0,0.72)] [font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]"
style={homeChoiceTextBoxStyle}
>
<span className="block w-full truncate">{choice.label}</span>
</span>
</button>
))}
</div>
) : null}
</div>
) : null}
<HomeLayoutBox
className="z-30"
elementId="profile"
@@ -711,6 +635,82 @@ export function HomePage({
})}
</div>
</div>
{activeDialog ? (
<div
className={`absolute inset-x-[4%] bottom-[15.8%] z-40 ${
activeDialog.kind === 'idle'
? 'pointer-events-auto'
: 'pointer-events-none'
}`}
key={`${activeDialog.kind}-${activeDialog.text}`}
>
{activeDialog.kind === 'idle' ? (
<button
className="absolute right-[13%] top-0 z-30 border-0 bg-transparent p-0 text-[10px] font-normal leading-none text-white drop-shadow-[0_1px_4px_rgba(8,22,64,0.82)] transition hover:text-white active:scale-[0.98]"
onClick={(event) => {
event.stopPropagation()
setActiveDialog(null)
}}
type="button"
>
</button>
) : null}
<div
className={`relative min-h-[128px] overflow-hidden rounded-[10px] px-7 pb-5 pt-7 text-left [font-family:'Microsoft_YaHei_UI','Microsoft_YaHei',sans-serif] ${
activeDialog.kind === 'idle'
? 'animate-[home-idle-dialog-enter_360ms_cubic-bezier(0.2,0.82,0.24,1)]'
: 'animate-[home-dialog-float_2500ms_ease-out_both]'
}`}
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-75"
draggable={false}
src={homeDialogBoxImage}
/>
<span
className={`z-10 block text-[14px] font-normal leading-[1.75] tracking-[0.04em] text-white [font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif] [text-shadow:1px_1.5px_0_rgba(0,0,0,0.72),0_0_1px_rgba(0,0,0,0.38)] ${
activeDialog.kind === 'idle'
? 'relative mt-4 max-w-[82%]'
: 'absolute left-7 top-1/2 w-[80%] -translate-y-1/2'
}`}
>
{activeDialog.text}
</span>
</div>
{activeDialog.kind === 'idle' ? (
<div className="mx-auto mt-1.5 flex w-[78%] animate-[home-idle-dialog-enter_360ms_cubic-bezier(0.2,0.82,0.24,1)] flex-col gap-1.5">
{activeDialog.choices.map((choice) => (
<button
className="group relative min-h-[31px] overflow-hidden rounded-[8px] border-0 bg-transparent px-0 py-0 text-left font-normal text-white shadow-[0_8px_18px_rgba(0,0,0,0.2)] transition active:scale-[0.99] [font-family:'Microsoft_YaHei_UI','Microsoft_YaHei',sans-serif]"
key={choice.label}
onClick={(event) => {
event.stopPropagation()
handleDialogChoice(choice)
}}
type="button"
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-85 transition group-hover:opacity-85"
draggable={false}
src={homeChoiceBoxImage}
/>
<span
className="absolute z-10 flex items-center justify-center overflow-hidden text-center text-[12px] leading-none tracking-[0.04em] drop-shadow-[0_1px_4px_rgba(0,0,0,0.72)] [font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]"
style={homeChoiceTextBoxStyle}
>
<span className="block w-full truncate">{choice.label}</span>
</span>
</button>
))}
</div>
) : null}
</div>
) : null}
<div className="absolute inset-x-0 bottom-0 z-30 overflow-hidden" style={{ aspectRatio: "108 / 25" }}><img src={bottomIconBar} alt="" aria-hidden="true" draggable={false} className="pointer-events-none absolute inset-0 h-full w-full object-fill scale-x-[1.12]" />{[{ route: "shop", icon: shopIcon, left: "8.1%" }, { route: "moments", icon: momentsIcon, left: "33.7%" }, { route: "pet", icon: petIcon, left: "56.6%" }, { route: "album", icon: albumIcon, left: "80%" }].map((t) => (<button key={t.route} type="button" aria-label={t.route} onClick={() => onNavigate(t.route as AppRoute)} style={{ left: t.left, width: "13.3%" }} className="absolute top-1/2 flex -translate-y-1/2 items-center justify-center active:scale-95">{t.route === "moments" ? (<span className="pointer-events-none absolute -top-1 left-1/2 z-10 -translate-x-1/2 whitespace-nowrap rounded-full border border-white/40 bg-[#f4d79b] px-1.5 py-px text-[8px] font-bold leading-tight text-[#5e3717] shadow-[0_2px_6px_rgba(0,0,0,0.3)]"></span>) : null}<img src={t.icon} alt="" draggable={false} className="w-full select-none object-contain" /></button>))}</div>
</div>
)