mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-05-02 15:56:36 +08:00
feat: 优化拖拽体验
This commit is contained in:
parent
be4df0fc9b
commit
a842c5b0ce
@ -59,6 +59,7 @@ import { throttle } from 'lodash-es';
|
|||||||
|
|
||||||
import type { MNode, MPage } from '@tmagic/schema';
|
import type { MNode, MPage } from '@tmagic/schema';
|
||||||
import { NodeType } from '@tmagic/schema';
|
import { NodeType } from '@tmagic/schema';
|
||||||
|
import StageCore from '@tmagic/stage';
|
||||||
|
|
||||||
import type { EditorService } from '@editor/services/editor';
|
import type { EditorService } from '@editor/services/editor';
|
||||||
import type { Services } from '@editor/type';
|
import type { Services } from '@editor/type';
|
||||||
@ -73,6 +74,7 @@ const select = (data: MNode, editorService?: EditorService) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
editorService?.select(data);
|
editorService?.select(data);
|
||||||
|
editorService?.get<StageCore>('stage')?.select(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const highlight = (data: MNode, editorService?: EditorService) => {
|
const highlight = (data: MNode, editorService?: EditorService) => {
|
||||||
@ -80,6 +82,7 @@ const highlight = (data: MNode, editorService?: EditorService) => {
|
|||||||
throw new Error('没有id');
|
throw new Error('没有id');
|
||||||
}
|
}
|
||||||
editorService?.highlight(data);
|
editorService?.highlight(data);
|
||||||
|
editorService?.get<StageCore>('stage')?.highlight(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const useDrop = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => ({
|
const useDrop = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => ({
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
computed,
|
computed,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
inject,
|
inject,
|
||||||
nextTick,
|
markRaw,
|
||||||
onMounted,
|
onMounted,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
PropType,
|
PropType,
|
||||||
@ -124,7 +124,6 @@ export default defineComponent({
|
|||||||
const page = computed(() => services?.editorService.get<MPage>('page'));
|
const page = computed(() => services?.editorService.get<MPage>('page'));
|
||||||
const zoom = computed(() => services?.uiService.get<number>('zoom'));
|
const zoom = computed(() => services?.uiService.get<number>('zoom'));
|
||||||
const node = computed(() => services?.editorService.get<MNode>('node'));
|
const node = computed(() => services?.editorService.get<MNode>('node'));
|
||||||
const highlightNode = computed(() => services?.editorService.get<MNode>('highlightNode'));
|
|
||||||
|
|
||||||
let stage: StageCore | null = null;
|
let stage: StageCore | null = null;
|
||||||
let runtime: Runtime | null = null;
|
let runtime: Runtime | null = null;
|
||||||
@ -152,7 +151,7 @@ export default defineComponent({
|
|||||||
moveableOptions: props.moveableOptions,
|
moveableOptions: props.moveableOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
services?.editorService.set('stage', stage);
|
services?.editorService.set('stage', markRaw(stage));
|
||||||
|
|
||||||
stage?.mount(stageContainer.value);
|
stage?.mount(stageContainer.value);
|
||||||
|
|
||||||
@ -199,25 +198,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => node.value?.id,
|
|
||||||
(id) => {
|
|
||||||
nextTick(() => {
|
|
||||||
// 等待相关dom变更完成后,再select,适用大多数场景
|
|
||||||
id && stage?.select(id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => highlightNode.value?.id,
|
|
||||||
(id) => {
|
|
||||||
nextTick(() => {
|
|
||||||
id && stage?.highlight(id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
for (const { contentRect } of entries) {
|
for (const { contentRect } of entries) {
|
||||||
services?.uiService.set('stageContainerRect', {
|
services?.uiService.set('stageContainerRect', {
|
||||||
|
@ -63,8 +63,12 @@ export default class StageCore extends EventEmitter {
|
|||||||
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
this.dr = new StageDragResize({ core: this, container: this.mask.content });
|
||||||
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
this.highlightLayer = new StageHighlight({ core: this, container: this.mask.wrapper });
|
||||||
|
|
||||||
this.renderer.on('runtime-ready', (runtime: Runtime) => this.emit('runtime-ready', runtime));
|
this.renderer.on('runtime-ready', (runtime: Runtime) => {
|
||||||
this.renderer.on('page-el-update', (el: HTMLElement) => this.mask?.observe(el));
|
this.emit('runtime-ready', runtime);
|
||||||
|
});
|
||||||
|
this.renderer.on('page-el-update', (el: HTMLElement) => {
|
||||||
|
this.mask?.observe(el);
|
||||||
|
});
|
||||||
|
|
||||||
this.mask
|
this.mask
|
||||||
.on('beforeSelect', (event: MouseEvent) => {
|
.on('beforeSelect', (event: MouseEvent) => {
|
||||||
@ -139,12 +143,14 @@ export default class StageCore extends EventEmitter {
|
|||||||
|
|
||||||
const runtime = await this.renderer.getRuntime();
|
const runtime = await this.renderer.getRuntime();
|
||||||
|
|
||||||
|
await runtime?.select?.(el.id);
|
||||||
|
|
||||||
if (runtime?.beforeSelect) {
|
if (runtime?.beforeSelect) {
|
||||||
await runtime.beforeSelect(el);
|
await runtime.beforeSelect(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mask.setLayout(el);
|
this.mask.setLayout(el);
|
||||||
this.dr?.select(el, event);
|
this.dr.select(el, event);
|
||||||
this.selectedDom = el;
|
this.selectedDom = el;
|
||||||
|
|
||||||
if (this.renderer.contentWindow) {
|
if (this.renderer.contentWindow) {
|
||||||
@ -170,7 +176,7 @@ export default class StageCore extends EventEmitter {
|
|||||||
if (el) {
|
if (el) {
|
||||||
// 更新了组件的布局,需要重新设置mask是否可以滚动
|
// 更新了组件的布局,需要重新设置mask是否可以滚动
|
||||||
this.mask.setLayout(el);
|
this.mask.setLayout(el);
|
||||||
this.dr?.select(el);
|
this.dr.select(el);
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
@ -242,14 +248,11 @@ export default class StageCore extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getTargetElement(idOrEl: Id | HTMLElement): Promise<HTMLElement> {
|
private async getTargetElement(idOrEl: Id | HTMLElement): Promise<HTMLElement> {
|
||||||
let el;
|
|
||||||
if (typeof idOrEl === 'string' || typeof idOrEl === 'number') {
|
if (typeof idOrEl === 'string' || typeof idOrEl === 'number') {
|
||||||
const runtime = await this.renderer?.getRuntime();
|
const el = this.renderer.contentWindow?.document.getElementById(`${idOrEl}`);
|
||||||
el = await runtime?.select?.(`${idOrEl}`);
|
|
||||||
if (!el) throw new Error(`不存在ID为${idOrEl}的元素`);
|
if (!el) throw new Error(`不存在ID为${idOrEl}的元素`);
|
||||||
} else {
|
return el;
|
||||||
el = idOrEl;
|
|
||||||
}
|
}
|
||||||
return el;
|
return idOrEl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ import type { MoveableOptions } from 'moveable';
|
|||||||
import Moveable from 'moveable';
|
import Moveable from 'moveable';
|
||||||
import MoveableHelper from 'moveable-helper';
|
import MoveableHelper from 'moveable-helper';
|
||||||
|
|
||||||
import { GHOST_EL_ID_PREFIX, GuidesType, Mode } from './const';
|
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, GuidesType, Mode } from './const';
|
||||||
import StageCore from './StageCore';
|
import StageCore from './StageCore';
|
||||||
import type { SortEventData, StageDragResizeConfig } from './types';
|
import type { Offset, Runtime, SortEventData, StageDragResizeConfig } from './types';
|
||||||
import { getAbsolutePosition, getMode, getOffset } from './util';
|
import { getAbsolutePosition, getMode, getOffset } from './util';
|
||||||
|
|
||||||
enum ActionStatus {
|
enum ActionStatus {
|
||||||
@ -45,6 +45,7 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
public moveable?: Moveable;
|
public moveable?: Moveable;
|
||||||
public horizontalGuidelines: number[] = [];
|
public horizontalGuidelines: number[] = [];
|
||||||
public verticalGuidelines: number[] = [];
|
public verticalGuidelines: number[] = [];
|
||||||
|
public elementGuidelines: HTMLElement[] = [];
|
||||||
|
|
||||||
private moveableOptions: MoveableOptions = {};
|
private moveableOptions: MoveableOptions = {};
|
||||||
private dragStatus: ActionStatus = ActionStatus.END;
|
private dragStatus: ActionStatus = ActionStatus.END;
|
||||||
@ -65,29 +66,36 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
* @param el 选中组件的Dom节点元素
|
* @param el 选中组件的Dom节点元素
|
||||||
* @param event 鼠标事件
|
* @param event 鼠标事件
|
||||||
*/
|
*/
|
||||||
public async select(el: HTMLElement, event?: MouseEvent): Promise<void> {
|
public select(el: HTMLElement, event?: MouseEvent): void {
|
||||||
this.target = el;
|
this.target = el;
|
||||||
// 如果有滚动条会导致resize时获取到width,height不准确
|
// 如果有滚动条会导致resize时获取到width,height不准确
|
||||||
if (/(auto|scroll)/.test(this.target.style.overflow)) {
|
if (/(auto|scroll)/.test(this.target.style.overflow)) {
|
||||||
this.target.style.overflow = 'hidden';
|
this.target.style.overflow = 'hidden';
|
||||||
}
|
}
|
||||||
this.mode = getMode(el);
|
this.mode = getMode(el);
|
||||||
this.destroyDragEl();
|
|
||||||
this.destroyGhostEl();
|
this.destroyGhostEl();
|
||||||
|
|
||||||
this.dragEl = this.generateDragEl(el);
|
this.generateDragEl(el);
|
||||||
|
|
||||||
this.moveableOptions = await this.getOptions({
|
const originDraggable = this.moveableOptions.draggable;
|
||||||
target: this.dragEl || this.target,
|
|
||||||
|
this.moveableOptions = this.getOptions({
|
||||||
|
target: this.dragEl,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.moveableHelper = MoveableHelper.create({
|
// 从不能拖动到能拖动的节点之间切换,要重新创建moveable,不然dragStart不生效
|
||||||
useBeforeRender: true,
|
if (!this.moveable || originDraggable !== this.moveableOptions.draggable) {
|
||||||
useRender: false,
|
this.moveableHelper = MoveableHelper.create({
|
||||||
createAuto: true,
|
useBeforeRender: true,
|
||||||
});
|
useRender: false,
|
||||||
|
createAuto: true,
|
||||||
|
});
|
||||||
|
|
||||||
this.initMoveable();
|
this.initMoveable();
|
||||||
|
} else {
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
this.moveable?.dragStart(event);
|
this.moveable?.dragStart(event);
|
||||||
@ -97,11 +105,10 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* 初始化选中框并渲染出来
|
* 初始化选中框并渲染出来
|
||||||
*/
|
*/
|
||||||
public async refresh() {
|
public refresh() {
|
||||||
if (!this.moveable) throw new Error('未初始化moveable');
|
if (!this.moveable) throw new Error('未初始化moveable');
|
||||||
|
|
||||||
const options = await this.getOptions();
|
Object.entries(this.moveableOptions).forEach(([key, value]) => {
|
||||||
Object.entries(options).forEach(([key, value]) => {
|
|
||||||
(this.moveable as any)[key] = value;
|
(this.moveable as any)[key] = value;
|
||||||
});
|
});
|
||||||
this.moveable.updateTarget();
|
this.moveable.updateTarget();
|
||||||
@ -110,16 +117,20 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
public setGuidelines(type: GuidesType, guidelines: number[]): void {
|
public setGuidelines(type: GuidesType, guidelines: number[]): void {
|
||||||
if (type === GuidesType.HORIZONTAL) {
|
if (type === GuidesType.HORIZONTAL) {
|
||||||
this.horizontalGuidelines = guidelines;
|
this.horizontalGuidelines = guidelines;
|
||||||
|
this.moveableOptions.horizontalGuidelines = guidelines;
|
||||||
} else if (type === GuidesType.VERTICAL) {
|
} else if (type === GuidesType.VERTICAL) {
|
||||||
this.verticalGuidelines = guidelines;
|
this.verticalGuidelines = guidelines;
|
||||||
|
this.moveableOptions.verticalGuidelines = guidelines;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearGuides() {
|
public clearGuides() {
|
||||||
this.verticalGuidelines = [];
|
|
||||||
this.horizontalGuidelines = [];
|
this.horizontalGuidelines = [];
|
||||||
|
this.verticalGuidelines = [];
|
||||||
|
this.moveableOptions.horizontalGuidelines = [];
|
||||||
|
this.moveableOptions.verticalGuidelines = [];
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +207,7 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
private bindDragEvent(): void {
|
private bindDragEvent(): void {
|
||||||
if (!this.moveable) throw new Error('moveable 为初始化');
|
if (!this.moveable) throw new Error('moveable 为初始化');
|
||||||
|
|
||||||
let offset = {
|
let offset: Offset | null = null;
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.moveable
|
this.moveable
|
||||||
.on('dragStart', (e) => {
|
.on('dragStart', (e) => {
|
||||||
@ -209,14 +217,17 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
|
|
||||||
this.moveableHelper?.onDragStart(e);
|
this.moveableHelper?.onDragStart(e);
|
||||||
|
|
||||||
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
|
||||||
|
|
||||||
if (this.mode === Mode.SORTABLE) {
|
if (this.mode === Mode.SORTABLE) {
|
||||||
this.ghostEl = this.generateGhostEl(this.target);
|
this.ghostEl = this.generateGhostEl(this.target);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('drag', (e) => {
|
.on('drag', (e) => {
|
||||||
if (!this.target || !this.dragEl) return;
|
if (!this.target || !this.dragEl) return;
|
||||||
|
|
||||||
|
if (!offset) {
|
||||||
|
offset = getAbsolutePosition(this.target, { left: 0, top: 0 });
|
||||||
|
}
|
||||||
|
|
||||||
this.dragStatus = ActionStatus.ING;
|
this.dragStatus = ActionStatus.ING;
|
||||||
|
|
||||||
const { left, top } = e;
|
const { left, top } = e;
|
||||||
@ -244,24 +255,23 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
offset = null;
|
||||||
|
|
||||||
this.dragStatus = ActionStatus.END;
|
this.dragStatus = ActionStatus.END;
|
||||||
this.destroyGhostEl();
|
this.destroyGhostEl();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getSnapElements(el: HTMLElement): Promise<HTMLElement[]> {
|
private getSnapElements(runtime: Runtime, el?: HTMLElement): HTMLElement[] {
|
||||||
const { renderer } = this.core;
|
const { renderer, mask } = this.core;
|
||||||
const getSnapElements =
|
const getSnapElements =
|
||||||
(await renderer.getRuntime())?.getSnapElements ||
|
runtime?.getSnapElements ||
|
||||||
(() => {
|
(() => {
|
||||||
const doc = renderer.contentWindow?.document;
|
const doc = renderer.contentWindow?.document;
|
||||||
return doc ? Array.from(doc.querySelectorAll('[id]')) : [];
|
return doc ? Array.from(doc.querySelectorAll('[id]')) : [];
|
||||||
});
|
});
|
||||||
return (
|
return getSnapElements(el).filter(
|
||||||
getSnapElements(el)
|
(element) => element !== this.target && !this.target?.contains(element) && element !== mask.page,
|
||||||
// 排除掉当前组件本身
|
|
||||||
.filter((element) => element !== this.target && !this.target?.contains(element))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +317,7 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
|
|
||||||
const ghostEl = el.cloneNode(true) as HTMLElement;
|
const ghostEl = el.cloneNode(true) as HTMLElement;
|
||||||
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
const { top, left } = getAbsolutePosition(el, getOffset(el));
|
||||||
ghostEl.id = `${GHOST_EL_ID_PREFIX}${ghostEl.id}`;
|
ghostEl.id = `${GHOST_EL_ID_PREFIX}${el.id}`;
|
||||||
ghostEl.style.zIndex = '5';
|
ghostEl.style.zIndex = '5';
|
||||||
ghostEl.style.opacity = '.5';
|
ghostEl.style.opacity = '.5';
|
||||||
ghostEl.style.position = 'absolute';
|
ghostEl.style.position = 'absolute';
|
||||||
@ -322,23 +332,24 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
this.ghostEl = undefined;
|
this.ghostEl = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateDragEl(el: HTMLElement): HTMLElement {
|
private generateDragEl(el: HTMLElement) {
|
||||||
if (this.dragEl) {
|
|
||||||
this.destroyDragEl();
|
|
||||||
}
|
|
||||||
|
|
||||||
const { width, height } = el.getBoundingClientRect();
|
const { width, height } = el.getBoundingClientRect();
|
||||||
const offset = getOffset(el);
|
const offset = getOffset(el);
|
||||||
const dragEl = globalThis.document.createElement('div');
|
|
||||||
dragEl.style.cssText = `
|
if (!this.dragEl) {
|
||||||
|
this.dragEl = globalThis.document.createElement('div');
|
||||||
|
this.container.append(this.dragEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dragEl.style.cssText = `
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: ${offset.left}px;
|
left: ${offset.left}px;
|
||||||
top: ${offset.top}px;
|
top: ${offset.top}px;
|
||||||
width: ${width}px;
|
width: ${width}px;
|
||||||
height: ${height}px;
|
height: ${height}px;
|
||||||
`;
|
`;
|
||||||
this.container.append(dragEl);
|
|
||||||
return dragEl;
|
this.dragEl.id = `${DRAG_EL_ID_PREFIX}${el.id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private destroyDragEl(): void {
|
private destroyDragEl(): void {
|
||||||
@ -346,7 +357,7 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
this.dragEl = undefined;
|
this.dragEl = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getOptions(options: MoveableOptions = {}): Promise<MoveableOptions> {
|
private getOptions(options: MoveableOptions = {}): MoveableOptions {
|
||||||
if (!this.target) return {};
|
if (!this.target) return {};
|
||||||
|
|
||||||
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
const isAbsolute = this.mode === Mode.ABSOLUTE;
|
||||||
@ -378,8 +389,16 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
center: isAbsolute,
|
center: isAbsolute,
|
||||||
middle: isAbsolute,
|
middle: isAbsolute,
|
||||||
},
|
},
|
||||||
|
elementSnapDirections: {
|
||||||
|
top: isAbsolute,
|
||||||
|
right: isAbsolute,
|
||||||
|
bottom: isAbsolute,
|
||||||
|
left: isAbsolute,
|
||||||
|
},
|
||||||
|
isDisplayInnerSnapDigit: true,
|
||||||
horizontalGuidelines: this.horizontalGuidelines,
|
horizontalGuidelines: this.horizontalGuidelines,
|
||||||
verticalGuidelines: this.verticalGuidelines,
|
verticalGuidelines: this.verticalGuidelines,
|
||||||
|
elementGuidelines: this.elementGuidelines,
|
||||||
|
|
||||||
bounds: {
|
bounds: {
|
||||||
top: 0,
|
top: 0,
|
||||||
|
@ -225,12 +225,13 @@ export default class StageMask extends Rule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.content.removeEventListener('mousemove', this.highlightHandler);
|
||||||
|
this.emit('clearHighlight');
|
||||||
|
|
||||||
this.emit('beforeSelect', event);
|
this.emit('beforeSelect', event);
|
||||||
|
|
||||||
// 如果是右键点击,这里的mouseup事件监听没有效果
|
// 如果是右键点击,这里的mouseup事件监听没有效果
|
||||||
globalThis.document.addEventListener('mouseup', this.mouseUpHandler);
|
globalThis.document.addEventListener('mouseup', this.mouseUpHandler);
|
||||||
this.content.removeEventListener('mousemove', this.highlightHandler);
|
|
||||||
this.emit('clearHighlight');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private mouseUpHandler = (): void => {
|
private mouseUpHandler = (): void => {
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
// 流式布局下拖动时需要clone一个镜像节点,镜像节点的id前缀
|
// 流式布局下拖动时需要clone一个镜像节点,镜像节点的id前缀
|
||||||
export const GHOST_EL_ID_PREFIX = 'ghost_el_';
|
export const GHOST_EL_ID_PREFIX = 'ghost_el_';
|
||||||
|
|
||||||
|
export const DRAG_EL_ID_PREFIX = 'drag_el_';
|
||||||
|
|
||||||
// 默认放到缩小倍数
|
// 默认放到缩小倍数
|
||||||
export const DEFAULT_ZOOM = 1;
|
export const DEFAULT_ZOOM = 1;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ export interface RemoveData {
|
|||||||
|
|
||||||
export interface Runtime {
|
export interface Runtime {
|
||||||
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
|
beforeSelect?: (el: HTMLElement) => Promise<boolean> | boolean;
|
||||||
getSnapElements?: (el: HTMLElement) => HTMLElement[];
|
getSnapElements?: (el?: HTMLElement) => HTMLElement[];
|
||||||
updateRootConfig: (config: MApp) => void;
|
updateRootConfig: (config: MApp) => void;
|
||||||
updatePageId?: (id: Id) => void;
|
updatePageId?: (id: Id) => void;
|
||||||
select?: (id: Id) => Promise<HTMLElement> | HTMLElement;
|
select?: (id: Id) => Promise<HTMLElement> | HTMLElement;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user