Skip to content

Commit 6499464

Browse files
committed
refactor: optimize Vue canvas interaction logic, extract element positioning and interaction methods
重构: 优化 Vue 画布交互逻辑,提取元素定位和交互方法
1 parent fc16170 commit 6499464

22 files changed

Lines changed: 1474 additions & 573 deletions

designer-demo/engine.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ export default {
33
theme: 'light',
44
material: ['/mock/bundle.json'],
55
scripts: [],
6-
styles: []
6+
styles: [],
7+
dslMode: 'vue'
78
}

packages/canvas/container/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import CanvasContainer from './src/CanvasContainer.vue'
2-
import { useMultiSelect } from './src/composables/useMultiSelect'
2+
import { useSelectNode } from './src/interactions'
33
import { registerHotkeyEvent, removeHotkeyEvent } from './src/keyboard'
44
import metaData from './meta'
55

66
export default {
77
...metaData,
88
entry: CanvasContainer,
9-
api: { useMultiSelect, registerHotkeyEvent, removeHotkeyEvent }
9+
api: { useSelectNode, registerHotkeyEvent, removeHotkeyEvent }
1010
}

packages/canvas/container/src/CanvasContainer.vue

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
<template>
2-
<div v-for="state in multiSelectedStates" :key="state.id">
2+
<div v-for="state in selectState" :key="state.id">
33
<canvas-action
4-
:hoverState="hoverState"
5-
:inactiveHoverState="inactiveHoverState"
64
:selectState="state"
7-
:lineState="lineState"
85
:windowGetClickEventTarget="target"
96
:resize="canvasState.type === 'absolute'"
107
:multiStateLength="multiStateLength"
118
@select-slot="selectSlot"
129
@setting="settingModel"
1310
></canvas-action>
1411
</div>
15-
<canvas-router-jumper :hoverState="hoverState" :inactiveHoverState="inactiveHoverState"></canvas-router-jumper>
16-
<canvas-viewer-switcher :hoverState="hoverState" :inactiveHoverState="inactiveHoverState"></canvas-viewer-switcher>
12+
<canvas-hover :hoverState="curHoverState"></canvas-hover>
13+
<canvas-insert-line :lineState="lineState" :hoverState="curHoverState"></canvas-insert-line>
14+
<canvas-router-jumper :hoverState="curHoverState"></canvas-router-jumper>
15+
<canvas-viewer-switcher :hoverState="curHoverState"></canvas-viewer-switcher>
1716
<canvas-divider :selectState="computedSelectState"></canvas-divider>
1817
<canvas-resize-border :selectState="computedSelectState" :iframe="iframe"></canvas-resize-border>
1918
<canvas-resize>
@@ -53,7 +52,7 @@
5352
import { onMounted, ref, computed, onUnmounted, watch, watchEffect } from 'vue'
5453
import { iframeMonitoring } from '@opentiny/tiny-engine-common/js/monitor'
5554
import { useTranslate, useCanvas, useMessage, useResource } from '@opentiny/tiny-engine-meta-register'
56-
import { NODE_UID, NODE_LOOP, DESIGN_MODE } from '../../common'
55+
import { DESIGN_MODE } from '../../common'
5756
import { registerHotkeyEvent, removeHotkeyEvent } from './keyboard'
5857
import CanvasMenu, { closeMenu, openMenu } from './components/CanvasMenu.vue'
5958
import CanvasAction from './components/CanvasAction.vue'
@@ -62,27 +61,22 @@ import CanvasViewerSwitcher from './components/CanvasViewerSwitcher.vue'
6261
import CanvasResize from './components/CanvasResize.vue'
6362
import CanvasDivider from './components/CanvasDivider.vue'
6463
import CanvasResizeBorder from './components/CanvasResizeBorder.vue'
65-
import { useMultiSelect } from './composables/useMultiSelect'
64+
import CanvasHover from './components/CanvasHover.vue'
65+
import CanvasInsertLine from './components/CanvasInsertLine.vue'
6666
import {
6767
canvasState,
6868
onMouseUp,
6969
dragMove,
7070
dragState,
71-
initialRectState,
72-
hoverState,
73-
inactiveHoverState,
7471
lineState,
7572
removeNodeById,
7673
syncNodeScroll,
77-
getElement,
7874
dragStart,
79-
selectNode,
8075
initCanvas,
8176
clearLineState,
82-
querySelectById,
83-
getCurrent,
8477
canvasApi
8578
} from './container'
79+
import { useHoverNode, useSelectNode } from './interactions'
8680
8781
export default {
8882
components: {
@@ -92,7 +86,9 @@ export default {
9286
CanvasDivider,
9387
CanvasResizeBorder,
9488
CanvasRouterJumper,
95-
CanvasViewerSwitcher
89+
CanvasViewerSwitcher,
90+
CanvasHover,
91+
CanvasInsertLine
9692
},
9793
props: {
9894
controller: Object,
@@ -109,44 +105,29 @@ export default {
109105
const showSettingModel = ref(false)
110106
const target = ref(null)
111107
const srcAttrName = computed(() => (props.canvasSrc ? 'src' : 'srcdoc'))
112-
113108
const containerPanel = ref(null)
114109
const insertContainer = ref(false)
115-
116-
const { multiSelectedStates } = useMultiSelect()
117-
118-
const multiStateLength = computed(() => multiSelectedStates.value.length)
119-
110+
const { selectState, updateSelectedNode, defaultSelectState } = useSelectNode()
111+
const { curHoverState, updateHoverNode } = useHoverNode()
112+
const multiStateLength = computed(() => selectState.value.length)
120113
const computedSelectState = computed(() => {
121-
if (multiSelectedStates.value.length === 1) {
122-
return multiSelectedStates.value[0]
114+
if (selectState.value.length === 1) {
115+
return selectState.value[0]
123116
}
124117
125-
return initialRectState
118+
return defaultSelectState
126119
})
127120
128-
const setCurrentNode = async (event) => {
121+
const handleNodeInteractions = async (event) => {
129122
const { clientX, clientY } = event
130-
const element = getElement(event.target)
131123
closeMenu()
132-
let node = getCurrent().schema
133-
134-
if (element) {
135-
const currentElement = querySelectById(getCurrent().schema?.id)
136-
137-
if (!currentElement?.contains(element) || event.button === 0) {
138-
const isCtrlKey = event.ctrlKey || event.metaKey
139-
const loopId = element.getAttribute(NODE_LOOP)
140-
if (loopId) {
141-
node = await selectNode(element.getAttribute(NODE_UID), `loop-id=${loopId}`, isCtrlKey)
142-
} else {
143-
node = await selectNode(element.getAttribute(NODE_UID), undefined, isCtrlKey)
144-
}
145-
}
146-
147-
if (event.button === 0 && element !== element.ownerDocument.body) {
148-
const { x, y } = element.getBoundingClientRect()
124+
await updateSelectedNode(event)
125+
const node = selectState.value.node
149126
127+
if (node) {
128+
const element = selectState.value.element
129+
if (event.button === 0 && element !== element?.ownerDocument?.body) {
130+
const { left: x, top: y } = selectState.value.rect
150131
dragStart(node, element, { offsetX: clientX - x, offsetY: clientY - y })
151132
}
152133
@@ -211,38 +192,47 @@ export default {
211192
// 以下是内部iframe监听的事件
212193
win.addEventListener('mousedown', (event) => {
213194
handleCanvasEvent(() => {
214-
// html元素使用scroll和mouseup事件处理
215-
if (event.target === doc.documentElement) {
216-
isScrolling = false
217-
return
218-
}
195+
insertPosition.value = false
196+
insertContainer.value = false
197+
handleNodeInteractions(event)
198+
target.value = event.target
199+
})
219200
220-
const element = getElement(event.target)
221-
if (!element) {
201+
useMessage().publish({ topic: 'canvas-mousedown', data: { event } })
202+
})
203+
win.addEventListener('contextmenu', (event) => {
204+
handleCanvasEvent(() => {
205+
if (event.target === doc.documentElement) {
222206
return
223207
}
224208
225209
insertPosition.value = false
226210
insertContainer.value = false
227-
setCurrentNode(event)
211+
handleNodeInteractions(event)
228212
target.value = event.target
229213
})
230-
231-
useMessage().publish({ topic: 'canvas-mousedown', data: { event } })
232214
})
233215
216+
let scrollTimeout = null
234217
win.addEventListener('scroll', () => {
235218
isScrolling = true
219+
220+
clearTimeout(scrollTimeout)
221+
222+
scrollTimeout = setTimeout(() => {
223+
isScrolling = false
224+
}, 100)
236225
})
237226
227+
// TODO: 需要确认下该事件还是否需要
238228
win.addEventListener('mouseup', (event) => {
239229
if (event.target !== doc.documentElement || isScrolling) {
240230
return
241231
}
242232
243233
insertPosition.value = false
244234
insertContainer.value = false
245-
setCurrentNode(event)
235+
// handleNodeInteractions(event)
246236
target.value = event.target
247237
})
248238
@@ -257,9 +247,10 @@ export default {
257247
onMouseUp(ev)
258248
})
259249
260-
win.addEventListener('mousemove', (ev) => {
250+
win.addEventListener('mouseover', (ev) => {
261251
handleCanvasEvent(() => {
262-
dragMove(ev, true)
252+
// 更新当前鼠标 hover 的节点
253+
updateHoverNode(ev)
263254
})
264255
})
265256
@@ -311,8 +302,9 @@ export default {
311302
insertPosition.value = position
312303
}
313304
314-
const selectSlot = (slotName) => {
315-
hoverState.slot = slotName
305+
// TODO: 需要确认下该事件还是否需要
306+
const selectSlot = (_slotName) => {
307+
// hoverState.slot = slotName
316308
}
317309
318310
onMounted(() => run(iframe))
@@ -329,11 +321,9 @@ export default {
329321
return {
330322
iframe,
331323
dragState,
332-
hoverState,
333-
inactiveHoverState,
324+
// hoverState,
334325
computedSelectState,
335326
lineState,
336-
multiSelectedStates,
337327
multiStateLength,
338328
removeNodeById,
339329
selectSlot,
@@ -347,7 +337,9 @@ export default {
347337
insertPosition,
348338
insertContainer,
349339
loading,
350-
srcAttrName
340+
srcAttrName,
341+
selectState,
342+
curHoverState
351343
}
352344
}
353345
}

0 commit comments

Comments
 (0)