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,
|
||
};
|
||
}
|