- 左侧画布面板支持拖拽调整宽度、展开/收起(带动画),状态与宽度持久化 - 顶栏菜单左侧新增面板开关按钮,并缩小菜单/开关按钮 - 顶栏菜单新增「导出当前画布」为压缩包 - 画布元素列表支持多选并批量导出:图片/视频/音频为文件、文本为 txt、其余各自为 json - 画布/资产切换改为滑动下划线动画,点击元素跳转带缓动动画 - 移除文本/配置/视频等非图片元素图标的灰色底色,并写入 AGENTS.md 规范 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { create } from "zustand";
|
|
|
|
export const CANVAS_SIDE_PANEL_MOTION_MS = 500;
|
|
export const CANVAS_SIDE_PANEL_MIN_WIDTH = 220;
|
|
export const CANVAS_SIDE_PANEL_MAX_WIDTH = 480;
|
|
export const CANVAS_SIDE_PANEL_DEFAULT_WIDTH = 280;
|
|
|
|
const WIDTH_KEY = "canvas-side-panel-width";
|
|
const OPEN_KEY = "canvas-side-panel-open";
|
|
|
|
function initialWidth() {
|
|
if (typeof window === "undefined") return CANVAS_SIDE_PANEL_DEFAULT_WIDTH;
|
|
const stored = Number(localStorage.getItem(WIDTH_KEY));
|
|
if (!stored) return CANVAS_SIDE_PANEL_DEFAULT_WIDTH;
|
|
return Math.min(CANVAS_SIDE_PANEL_MAX_WIDTH, Math.max(CANVAS_SIDE_PANEL_MIN_WIDTH, stored));
|
|
}
|
|
|
|
function initialOpen() {
|
|
if (typeof window === "undefined") return true;
|
|
return localStorage.getItem(OPEN_KEY) !== "0";
|
|
}
|
|
|
|
type CanvasSidePanelStore = {
|
|
width: number;
|
|
panelOpen: boolean;
|
|
panelMounted: boolean;
|
|
panelClosing: boolean;
|
|
setWidth: (width: number) => void;
|
|
openPanel: () => void;
|
|
closePanel: () => void;
|
|
togglePanel: () => void;
|
|
};
|
|
|
|
export const useCanvasSidePanelStore = create<CanvasSidePanelStore>((set, get) => ({
|
|
width: initialWidth(),
|
|
panelOpen: initialOpen(),
|
|
panelMounted: initialOpen(),
|
|
panelClosing: false,
|
|
setWidth: (width) => set({ width }),
|
|
openPanel: () => {
|
|
if (typeof window !== "undefined") localStorage.setItem(OPEN_KEY, "1");
|
|
set({ panelOpen: true, panelMounted: true, panelClosing: false });
|
|
},
|
|
closePanel: () => {
|
|
if (!get().panelMounted || get().panelClosing) return;
|
|
if (typeof window !== "undefined") localStorage.setItem(OPEN_KEY, "0");
|
|
set({ panelOpen: false, panelClosing: true });
|
|
setTimeout(() => {
|
|
if (get().panelClosing) set({ panelMounted: false, panelClosing: false });
|
|
}, CANVAS_SIDE_PANEL_MOTION_MS);
|
|
},
|
|
togglePanel: () => (get().panelOpen ? get().closePanel() : get().openPanel()),
|
|
}));
|