refactor(canvas): 浮层 inset token 体系重建 + 全量应用(审计 D2/P0-2)
#116 曾引入 --canvas-inset-* token,上游合并后丢失。本轮重新建立画布 安全区 token 并全量替换硬编码定位,所有替换值等价(零视觉变化)。 新增 token(globals.css 6b 段,紧随 Elevation): - --canvas-inset-x/y: 16px 浮层水平/垂直安全区 - --canvas-topbar-h: 64px 顶部栏高度 - --canvas-topbar-offset: 72px 顶栏下方浮层顶部偏移 - --canvas-dock-popover-offset: 50px dock 弹出面板底部偏移 替换: - dock 根 inset-x-4/bottom-4 → --canvas-inset-x/y - dock 弹出面板 bottom-[50px] ×4(appearance/add-node/zoom/asset-tray)→ --canvas-dock-popover-offset - 顶栏 h-16/px-4 → --canvas-topbar-h/--canvas-inset-x - 活动任务面板 top-[72px] → --canvas-topbar-offset 活动任务面板 right-3(12px) 刻意保留:与 16px 安全区不同且改它会级联到 --canvas-panel-width 公式(PR #130 领地),不宜混入。
This commit is contained in:
@@ -41,7 +41,7 @@ export function CanvasActiveTaskPanel({ tasks }: { tasks: GenerationTask[] }) {
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: -8, scale: 0.98 }}
|
||||
transition={motionTransition}
|
||||
className="pointer-events-none absolute right-3 top-[72px] z-[var(--z-panel-floating)] w-[min(332px,calc(100vw-24px))]"
|
||||
className="pointer-events-none absolute right-3 top-[var(--canvas-topbar-offset)] z-[var(--z-panel-floating)] w-[min(332px,calc(100vw-24px))]"
|
||||
>
|
||||
<LayoutGroup id="canvas-active-tasks">
|
||||
<motion.section
|
||||
|
||||
@@ -133,7 +133,7 @@ export function CanvasAssetTray({ assetImages, canvasImages, showLibrary = true,
|
||||
animate={{ opacity: 1, y: 0, scale: 1, rotateX: 0 }}
|
||||
exit={{ opacity: 0, y: 14, scale: 0.95, rotateX: 3 }}
|
||||
transition={aceternityMotion.spring.panel}
|
||||
className="aceternity-floating-panel absolute bottom-[50px] left-0 flex w-[min(88vw,312px)] origin-bottom-left flex-col overflow-hidden rounded-[18px] border p-2.5 backdrop-blur-2xl"
|
||||
className="aceternity-floating-panel absolute bottom-[var(--canvas-dock-popover-offset)] left-0 flex w-[min(88vw,312px)] origin-bottom-left flex-col overflow-hidden rounded-[18px] border p-2.5 backdrop-blur-2xl"
|
||||
style={{ background: theme.spatial.elevated, borderColor: theme.toolbar.border, color: theme.node.text, height: safeTrayHeight, minHeight: Math.min(TRAY_MIN_HEIGHT, getMaxTrayHeight()), maxHeight: "calc(100vh - 6rem)", boxShadow: `0 32px 100px ${theme.spatial.shadow}` }}
|
||||
>
|
||||
<div className="absolute inset-x-10 top-0 h-px" style={{ background: `linear-gradient(90deg, transparent, ${theme.spatial.glowStrong}, transparent)` }} />
|
||||
|
||||
@@ -175,7 +175,7 @@ export function CanvasToolbar({
|
||||
const resourceCommands = addNodeCommands.filter((cmd) => cmd.section === "resource").map(toCommand);
|
||||
|
||||
return (
|
||||
<div ref={rootRef} data-canvas-no-zoom className="pointer-events-none absolute inset-x-4 bottom-4 z-[var(--z-toolbar)] flex justify-center">
|
||||
<div ref={rootRef} data-canvas-no-zoom className="pointer-events-none absolute inset-x-[var(--canvas-inset-x)] bottom-[var(--canvas-inset-y)] z-[var(--z-toolbar)] flex justify-center">
|
||||
<AnimatePresence>
|
||||
{addOpen ? (
|
||||
<AddNodeMenu
|
||||
@@ -191,7 +191,7 @@ export function CanvasToolbar({
|
||||
|
||||
<AnimatePresence>
|
||||
{appearanceOpen ? (
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: aceternityMotion.duration.instant }} className="pointer-events-auto absolute bottom-[50px] z-[var(--dock-z-popover)] w-[224px] max-w-[calc(100vw-24px)] -translate-x-1/2" style={{ left: panelX || "50%" }}>
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: aceternityMotion.duration.instant }} className="pointer-events-auto absolute bottom-[var(--canvas-dock-popover-offset)] z-[var(--dock-z-popover)] w-[224px] max-w-[calc(100vw-24px)] -translate-x-1/2" style={{ left: panelX || "50%" }}>
|
||||
<SpotlightSurface spotlightColor={theme.toolbar.itemHover} initial={{ y: 6, scale: 0.97 }} animate={{ y: 0, scale: 1 }} exit={{ y: 4, scale: 0.98 }} transition={{ duration: aceternityMotion.duration.instant, ease: aceternityMotion.easing.enter }} className="aceternity-floating-panel overflow-hidden rounded-[var(--panel-radius)] border p-2.5 backdrop-blur-2xl" style={{ background: theme.spatial.elevated, borderColor: theme.toolbar.border, color: theme.toolbar.item, boxShadow: `0 24px 64px ${theme.spatial.shadow}` }} onWheel={(event) => event.stopPropagation()}>
|
||||
<PanelHeading icon={<Palette className="size-4" />} title="画布外观" subtitle="调整整个创作空间" theme={theme} />
|
||||
<div className="mt-3 text-[var(--fs-micro)] font-semibold uppercase opacity-45">主题模式</div>
|
||||
@@ -231,7 +231,7 @@ function AddNodeMenu({ x, theme, nodeCommands, resourceCommands }: {
|
||||
resourceCommands: CanvasCreateCommand[];
|
||||
}) {
|
||||
return (
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: aceternityMotion.duration.instant }} className="pointer-events-auto absolute bottom-[50px] z-[var(--dock-z-popover)] w-[260px] max-w-[calc(100vw-24px)] -translate-x-1/2" style={{ left: x || "50%" }}>
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: aceternityMotion.duration.instant }} className="pointer-events-auto absolute bottom-[var(--canvas-dock-popover-offset)] z-[var(--dock-z-popover)] w-[260px] max-w-[calc(100vw-24px)] -translate-x-1/2" style={{ left: x || "50%" }}>
|
||||
<SpotlightSurface spotlightColor={theme.toolbar.itemHover} initial={{ y: 6, scale: 0.97 }} animate={{ y: 0, scale: 1 }} exit={{ y: 4, scale: 0.98 }} transition={{ duration: aceternityMotion.duration.instant, ease: aceternityMotion.easing.enter }} className="aceternity-floating-panel overflow-hidden rounded-[var(--panel-radius)] border p-2 backdrop-blur-2xl" style={{ background: theme.spatial.elevated, borderColor: theme.toolbar.border, color: theme.node.text, boxShadow: `0 24px 64px ${theme.spatial.shadow}` }} onWheel={(event) => event.stopPropagation()}>
|
||||
<PanelHeading icon={<Plus className="size-4" />} title="创建内容" subtitle="选择节点类型" theme={theme} />
|
||||
<MenuSection title="创作节点" />
|
||||
|
||||
@@ -94,7 +94,7 @@ export function CanvasZoomControls({ scale, onScaleChange, onReset, isMiniMapOpe
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 9, scale: 0.96 }}
|
||||
transition={aceternityMotion.spring.panel}
|
||||
className="aceternity-floating-panel absolute bottom-[50px] left-0 w-[220px] overflow-hidden rounded-[var(--panel-radius)] border p-2.5 backdrop-blur-2xl"
|
||||
className="aceternity-floating-panel absolute bottom-[var(--canvas-dock-popover-offset)] left-0 w-[220px] overflow-hidden rounded-[var(--panel-radius)] border p-2.5 backdrop-blur-2xl"
|
||||
style={{ background: theme.spatial.elevated, borderColor: theme.toolbar.border, color: theme.node.text, boxShadow: `0 28px 80px ${theme.spatial.shadow}` }}
|
||||
>
|
||||
<div className="absolute inset-x-10 top-0 h-px" style={{ background: `linear-gradient(90deg, transparent, ${theme.spatial.glowStrong}, transparent)` }} />
|
||||
|
||||
@@ -95,7 +95,7 @@ export function CanvasTopBar({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="pointer-events-none absolute left-0 right-0 top-0 z-[var(--z-toolbar)] flex h-16 items-center justify-between px-4">
|
||||
<div className="pointer-events-none absolute left-0 right-0 top-0 z-[var(--z-toolbar)] flex h-[var(--canvas-topbar-h)] items-center justify-between px-[var(--canvas-inset-x)]">
|
||||
<div className="pointer-events-auto flex min-w-0 items-center gap-3">
|
||||
<Dropdown
|
||||
trigger={["click"]}
|
||||
|
||||
@@ -117,6 +117,13 @@
|
||||
--z-tooltip: 1000; /* L12 提示 */
|
||||
--z-max: 2000; /* L13 最高(紧急通知)*/
|
||||
|
||||
/* --- 6b. Canvas 浮层定位 inset(画布安全区,对应审计 D2/P0-2)--- */
|
||||
--canvas-inset-x: 16px; /* 浮层水平安全区(dock inset、顶栏 px)*/
|
||||
--canvas-inset-y: 16px; /* 浮层垂直安全区(dock 底部)*/
|
||||
--canvas-topbar-h: 64px; /* 顶部栏高度 */
|
||||
--canvas-topbar-offset: 72px; /* 顶栏下方浮层顶部偏移(topbar-h + 8px 间距)*/
|
||||
--canvas-dock-popover-offset: 50px; /* dock 弹出面板底部偏移 */
|
||||
|
||||
/* --- 7. 动效(对应 #99 动效 token)--- */
|
||||
/* duration */
|
||||
--motion-dur-instant: 80ms;
|
||||
|
||||
Reference in New Issue
Block a user