107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
|
|
import type { EditorService } from './editor.service';
|
|||
|
|
import { useViewState } from './useViewState';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 工具栏逻辑封装(不侵入 EditorService)
|
|||
|
|
* - 网格开关/设置
|
|||
|
|
* - 标尺开关/设置
|
|||
|
|
* - 适配视图:基于当前点集中心,用 jumpToPosition 实现跳转
|
|||
|
|
*/
|
|||
|
|
export function useToolbar() {
|
|||
|
|
const { getCurrentViewState, jumpToPosition } = useViewState();
|
|||
|
|
|
|||
|
|
// 标尺设置/开关(操作 editor.store.options / editor.store.data 并重绘)
|
|||
|
|
const setRule = (editor: EditorService, options: { rule: boolean; ruleColor?: string }) => {
|
|||
|
|
const { rule, ruleColor } = options;
|
|||
|
|
const o = editor.store.options as unknown as { rule?: boolean; ruleColor?: string };
|
|||
|
|
const d = editor.store.data as unknown as { rule?: boolean; ruleColor?: string };
|
|||
|
|
o.rule = rule;
|
|||
|
|
d.rule = rule;
|
|||
|
|
if (ruleColor) {
|
|||
|
|
o.ruleColor = ruleColor;
|
|||
|
|
d.ruleColor = ruleColor;
|
|||
|
|
}
|
|||
|
|
(editor.store as unknown as { patchFlagsTop?: boolean }).patchFlagsTop = true;
|
|||
|
|
editor.render();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const toggleRule = (editor: EditorService, color?: string) => {
|
|||
|
|
const cur = (editor.store.data as unknown as { rule?: boolean }).rule ?? false;
|
|||
|
|
setRule(editor, { rule: !cur, ruleColor: color });
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 网格设置/开关
|
|||
|
|
const setGrid = (
|
|||
|
|
editor: EditorService,
|
|||
|
|
options: { grid: boolean; gridColor?: string; gridSize?: number; gridRotate?: number },
|
|||
|
|
) => {
|
|||
|
|
const { grid, gridColor, gridSize, gridRotate } = options;
|
|||
|
|
const o = editor.store.options as unknown as {
|
|||
|
|
grid?: boolean;
|
|||
|
|
gridColor?: string;
|
|||
|
|
gridSize?: number;
|
|||
|
|
gridRotate?: number;
|
|||
|
|
};
|
|||
|
|
const d = editor.store.data as unknown as {
|
|||
|
|
grid?: boolean;
|
|||
|
|
gridColor?: string;
|
|||
|
|
gridSize?: number;
|
|||
|
|
gridRotate?: number;
|
|||
|
|
};
|
|||
|
|
o.grid = grid;
|
|||
|
|
d.grid = grid;
|
|||
|
|
if (gridColor != null) {
|
|||
|
|
o.gridColor = gridColor;
|
|||
|
|
d.gridColor = gridColor;
|
|||
|
|
}
|
|||
|
|
if (gridSize != null) {
|
|||
|
|
o.gridSize = gridSize;
|
|||
|
|
d.gridSize = gridSize;
|
|||
|
|
}
|
|||
|
|
if (gridRotate != null) {
|
|||
|
|
o.gridRotate = gridRotate;
|
|||
|
|
d.gridRotate = gridRotate;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type CanvasWithTemplate = { canvasTemplate?: { bgPatchFlags?: boolean } };
|
|||
|
|
const canvas = editor.canvas as unknown as CanvasWithTemplate | undefined;
|
|||
|
|
if (canvas?.canvasTemplate) {
|
|||
|
|
canvas.canvasTemplate.bgPatchFlags = true;
|
|||
|
|
}
|
|||
|
|
editor.render();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const toggleGrid = (editor: EditorService) => {
|
|||
|
|
const cur = (editor.store.data as unknown as { grid?: boolean }).grid ?? false;
|
|||
|
|
setGrid(editor, { grid: !cur });
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 适配视图:计算当前中心点,然后用 jumpToPosition 跳转(并保持现有策略:若首次/非恢复则缩放到 8%)
|
|||
|
|
const fitView = async (editor: EditorService) => {
|
|||
|
|
const state = getCurrentViewState(editor);
|
|||
|
|
await jumpToPosition(editor, state.centerX, state.centerY, false);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 基础缩放
|
|||
|
|
const zoomIn = (editor: EditorService, step = 0.01) => {
|
|||
|
|
const s = editor.data().scale || 1;
|
|||
|
|
editor.scale(s + step);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const zoomOut = (editor: EditorService, step = 0.01) => {
|
|||
|
|
const s = editor.data().scale || 1;
|
|||
|
|
const next = Math.max(0.05, s - step);
|
|||
|
|
editor.scale(next);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
setRule,
|
|||
|
|
toggleRule,
|
|||
|
|
setGrid,
|
|||
|
|
toggleGrid,
|
|||
|
|
fitView,
|
|||
|
|
zoomIn,
|
|||
|
|
zoomOut,
|
|||
|
|
};
|
|||
|
|
}
|