feat(editor): 参考线缓存与页面绑定

This commit is contained in:
roymondchen 2022-06-22 16:05:12 +08:00 committed by jia000
parent 363330e07a
commit fb612eaddc
8 changed files with 78 additions and 58 deletions

View File

@ -36,11 +36,18 @@ import {
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import type { MApp, MNode, MPage } from '@tmagic/schema'; import type { MApp, MNode, MPage } from '@tmagic/schema';
import type { Runtime, SortEventData, UpdateEventData } from '@tmagic/stage'; import StageCore, { GuidesType, Runtime, SortEventData, UpdateEventData } from '@tmagic/stage';
import StageCore from '@tmagic/stage';
import ScrollViewer from '@editor/components/ScrollViewer.vue'; import ScrollViewer from '@editor/components/ScrollViewer.vue';
import { Layout, Services, StageOptions, StageRect } from '@editor/type'; import {
H_GUIDE_LINE_STORAGE_KEY,
Layout,
Services,
StageOptions,
StageRect,
V_GUIDE_LINE_STORAGE_KEY,
} from '@editor/type';
import { getGuideLineFromCache } from '@editor/utils';
import ViewerMenu from './ViewerMenu.vue'; import ViewerMenu from './ViewerMenu.vue';
@ -70,6 +77,8 @@ export default defineComponent({
let stage: StageCore | null = null; let stage: StageCore | null = null;
let runtime: Runtime | null = null; let runtime: Runtime | null = null;
const getGuideLineKey = (key: string) => `${key}_${root.value?.id}_${page.value?.id}`;
watchEffect(() => { watchEffect(() => {
if (stage) return; if (stage) return;
@ -99,6 +108,11 @@ export default defineComponent({
stage?.mount(stageContainer.value); stage?.mount(stageContainer.value);
stage.mask.setGuides([
getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
]);
stage?.on('select', (el: HTMLElement) => { stage?.on('select', (el: HTMLElement) => {
services?.editorService.select(el.id); services?.editorService.select(el.id);
}); });
@ -115,8 +129,19 @@ export default defineComponent({
services?.editorService.sort(ev.src, ev.dist); services?.editorService.sort(ev.src, ev.dist);
}); });
stage?.on('changeGuides', () => { stage?.on('changeGuides', (e) => {
services?.uiService.set('showGuides', true); services?.uiService.set('showGuides', true);
if (!root.value || !page.value) return;
const storageKey = getGuideLineKey(
e.type === GuidesType.HORIZONTAL ? H_GUIDE_LINE_STORAGE_KEY : V_GUIDE_LINE_STORAGE_KEY,
);
if (e.guides.length) {
globalThis.localStorage.setItem(storageKey, JSON.stringify(e.guides));
} else {
globalThis.localStorage.removeItem(storageKey);
}
}); });
if (!node.value?.id) return; if (!node.value?.id) return;

View File

@ -263,3 +263,6 @@ export enum Layout {
export enum Keys { export enum Keys {
ESCAPE = 'Space', ESCAPE = 'Space',
} }
export const H_GUIDE_LINE_STORAGE_KEY = '$MagicStageHorizontalGuidelinesData';
export const V_GUIDE_LINE_STORAGE_KEY = '$MagicStageVerticalGuidelinesData';

View File

@ -204,3 +204,18 @@ export const Fixed2Other = async (
return toRelative(node); return toRelative(node);
}; };
export const getGuideLineFromCache = (key: string): number[] => {
if (!key) return [];
const guideLineCacheData = globalThis.localStorage.getItem(key);
if (guideLineCacheData) {
try {
return JSON.parse(guideLineCacheData) || [];
} catch (e) {
console.error(e);
}
}
return [];
};

View File

@ -2,14 +2,13 @@ import EventEmitter from 'events';
import Guides, { GuidesEvents } from '@scena/guides'; import Guides, { GuidesEvents } from '@scena/guides';
import { GuidesType, H_GUIDE_LINE_STORAGE_KEY, V_GUIDE_LINE_STORAGE_KEY } from './const'; import { GuidesType } from './const';
import { getGuideLineFromCache } from './util';
export default class Rule extends EventEmitter { export default class Rule extends EventEmitter {
public hGuides: Guides; public hGuides: Guides;
public vGuides: Guides; public vGuides: Guides;
public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL); public horizontalGuidelines: number[] = [];
public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL); public verticalGuidelines: number[] = [];
private container: HTMLDivElement; private container: HTMLDivElement;
private containerResizeObserver: ResizeObserver; private containerResizeObserver: ResizeObserver;
@ -28,6 +27,7 @@ export default class Rule extends EventEmitter {
this.vGuides.resize(); this.vGuides.resize();
this.hGuides.resize(); this.hGuides.resize();
}); });
this.containerResizeObserver.observe(this.container); this.containerResizeObserver.observe(this.container);
} }
@ -45,33 +45,34 @@ export default class Rule extends EventEmitter {
}); });
} }
/** public setGuides([hLines, vLines]: [number[], number[]]) {
* 线 this.horizontalGuidelines = hLines;
*/ this.verticalGuidelines = vLines;
public clearGuides() {
this.horizontalGuidelines = [];
this.verticalGuidelines = [];
this.vGuides.setState({
defaultGuides: [],
});
this.hGuides.setState({ this.hGuides.setState({
defaultGuides: [], defaultGuides: hLines,
}); });
this.emit('changeGuides', { this.vGuides.setState({
type: GuidesType.VERTICAL, defaultGuides: vLines,
guides: [],
}); });
this.emit('changeGuides', { this.emit('changeGuides', {
type: GuidesType.HORIZONTAL, type: GuidesType.HORIZONTAL,
guides: [], guides: hLines,
}); });
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, '[]'); this.emit('changeGuides', {
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, '[]'); type: GuidesType.VERTICAL,
guides: vLines,
});
}
/**
* 线
*/
public clearGuides() {
this.setGuides([[], []]);
} }
/** /**
@ -101,7 +102,7 @@ export default class Rule extends EventEmitter {
} }
} }
scrollRule(scrollTop: number) { public scrollRule(scrollTop: number) {
this.hGuides.scrollGuides(scrollTop); this.hGuides.scrollGuides(scrollTop);
this.hGuides.scroll(0); this.hGuides.scroll(0);
@ -142,8 +143,6 @@ export default class Rule extends EventEmitter {
type: GuidesType.HORIZONTAL, type: GuidesType.HORIZONTAL,
guides: this.horizontalGuidelines, guides: this.horizontalGuidelines,
}); });
globalThis.localStorage.setItem(H_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
}; };
private vGuidesChangeGuidesHandler = (e: GuidesEvents['changeGuides']) => { private vGuidesChangeGuidesHandler = (e: GuidesEvents['changeGuides']) => {
@ -152,7 +151,5 @@ export default class Rule extends EventEmitter {
type: GuidesType.VERTICAL, type: GuidesType.VERTICAL,
guides: this.verticalGuidelines, guides: this.verticalGuidelines,
}); });
globalThis.localStorage.setItem(V_GUIDE_LINE_STORAGE_KEY, JSON.stringify(e.guides));
}; };
} }

View File

@ -26,7 +26,7 @@ import MoveableHelper from 'moveable-helper';
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const'; import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode, ZIndex } from './const';
import StageCore from './StageCore'; import StageCore from './StageCore';
import type { SortEventData, StageDragResizeConfig } from './types'; import type { SortEventData, StageDragResizeConfig } from './types';
import { getAbsolutePosition, getGuideLineFromCache, getMode, getOffset } from './util'; import { getAbsolutePosition, getMode, getOffset } from './util';
/** 拖动状态 */ /** 拖动状态 */
enum ActionStatus { enum ActionStatus {
@ -52,9 +52,9 @@ export default class StageDragResize extends EventEmitter {
/** Moveable拖拽类实例 */ /** Moveable拖拽类实例 */
public moveable?: Moveable; public moveable?: Moveable;
/** 水平参考线 */ /** 水平参考线 */
public horizontalGuidelines: number[] = getGuideLineFromCache(GuidesType.HORIZONTAL); public horizontalGuidelines: number[] = [];
/** 垂直参考线 */ /** 垂直参考线 */
public verticalGuidelines: number[] = getGuideLineFromCache(GuidesType.VERTICAL); public verticalGuidelines: number[] = [];
/** 对齐元素集合 */ /** 对齐元素集合 */
public elementGuidelines: HTMLElement[] = []; public elementGuidelines: HTMLElement[] = [];
/** 布局方式:流式布局、绝对定位、固定定位 */ /** 布局方式:流式布局、绝对定位、固定定位 */
@ -132,7 +132,9 @@ export default class StageDragResize extends EventEmitter {
this.moveableOptions.verticalGuidelines = guidelines; this.moveableOptions.verticalGuidelines = guidelines;
} }
this.updateMoveable(); if (this.moveable) {
this.updateMoveable();
}
} }
public clearGuides() { public clearGuides() {

View File

@ -68,6 +68,3 @@ export enum Mode {
/** 选中节点的class name */ /** 选中节点的class name */
export const SELECTED_CLASS = 'tmagic-stage-selected-area'; export const SELECTED_CLASS = 'tmagic-stage-selected-area';
export const H_GUIDE_LINE_STORAGE_KEY = '$MagicStageHorizontalGuidelinesData';
export const V_GUIDE_LINE_STORAGE_KEY = '$MagicStageVerticalGuidelinesData';

View File

@ -23,4 +23,5 @@ export { default as StageRender } from './StageRender';
export { default as StageMask } from './StageMask'; export { default as StageMask } from './StageMask';
export { default as StageDragResize } from './StageDragResize'; export { default as StageDragResize } from './StageDragResize';
export * from './types'; export * from './types';
export * from './const';
export default StageCore; export default StageCore;

View File

@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { GuidesType, H_GUIDE_LINE_STORAGE_KEY, Mode, SELECTED_CLASS, V_GUIDE_LINE_STORAGE_KEY } from './const'; import { Mode, SELECTED_CLASS } from './const';
import type { Offset } from './types'; import type { Offset } from './types';
const getParents = (el: Element, relative: Element) => { const getParents = (el: Element, relative: Element) => {
@ -149,23 +149,3 @@ export const addSelectedClassName = (el: Element, doc: Document) => {
item.classList.add(`${SELECTED_CLASS}-parents`); item.classList.add(`${SELECTED_CLASS}-parents`);
}); });
}; };
export const getGuideLineFromCache = (type: GuidesType): number[] => {
const key = {
[GuidesType.HORIZONTAL]: H_GUIDE_LINE_STORAGE_KEY,
[GuidesType.VERTICAL]: V_GUIDE_LINE_STORAGE_KEY,
}[type];
if (!key) return [];
const guideLineCacheData = globalThis.localStorage.getItem(key);
if (guideLineCacheData) {
try {
return JSON.parse(guideLineCacheData) || [];
} catch (e) {
console.error(e);
}
}
return [];
};