perf(vue): patch layer tree node updates
This commit is contained in:
parent
cde9cd4610
commit
7f99638e65
|
|
@ -7,6 +7,7 @@ import { provideLayerTree } from '#vue/primitives/LayerTree/context'
|
|||
import { useLayerDrag } from '#vue/primitives/LayerTree/useLayerDrag'
|
||||
|
||||
import type { LayerNode } from '#vue/primitives/LayerTree/context'
|
||||
import type { SceneNode } from '@open-pencil/scene-graph'
|
||||
|
||||
const { indentPerLevel = 16 } = defineProps<{
|
||||
indentPerLevel?: number
|
||||
|
|
@ -32,6 +33,17 @@ const { draggingId, instruction, instructionTargetId, setupItem } = useLayerDrag
|
|||
expandNode
|
||||
)
|
||||
|
||||
function nodeToLayerNode(node: SceneNode): LayerNode {
|
||||
return {
|
||||
id: node.id,
|
||||
name: node.name,
|
||||
type: node.type,
|
||||
layoutMode: node.layoutMode,
|
||||
visible: node.visible,
|
||||
locked: node.locked
|
||||
}
|
||||
}
|
||||
|
||||
function buildTree(parentId: string): LayerNode[] {
|
||||
const parent = editor.graph.getNode(parentId)
|
||||
if (!parent) return []
|
||||
|
|
@ -39,12 +51,7 @@ function buildTree(parentId: string): LayerNode[] {
|
|||
.map((cid) => editor.graph.getNode(cid))
|
||||
.filter((n): n is NonNullable<typeof n> => !!n)
|
||||
.map((node) => ({
|
||||
id: node.id,
|
||||
name: node.name,
|
||||
type: node.type,
|
||||
layoutMode: node.layoutMode,
|
||||
visible: node.visible,
|
||||
locked: node.locked,
|
||||
...nodeToLayerNode(node),
|
||||
children: node.childIds.length > 0 ? buildTree(node.id) : undefined
|
||||
}))
|
||||
}
|
||||
|
|
@ -59,6 +66,46 @@ function rebuildTree() {
|
|||
treeVersion.value++
|
||||
}
|
||||
|
||||
function replaceLayerNode(nodes: LayerNode[], replacement: LayerNode): LayerNode[] | null {
|
||||
let changed = false
|
||||
const next = nodes.map((node) => {
|
||||
if (node.id === replacement.id) {
|
||||
changed = true
|
||||
return { ...replacement, children: node.children }
|
||||
}
|
||||
if (!node.children) return node
|
||||
const children = replaceLayerNode(node.children, replacement)
|
||||
if (!children) return node
|
||||
changed = true
|
||||
return { ...node, children }
|
||||
})
|
||||
return changed ? next : null
|
||||
}
|
||||
|
||||
function patchLayerNode(id: string, changes: Partial<SceneNode>) {
|
||||
if ('childIds' in changes || 'parentId' in changes) {
|
||||
rebuildTree()
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
'name' in changes ||
|
||||
'type' in changes ||
|
||||
'layoutMode' in changes ||
|
||||
'visible' in changes ||
|
||||
'locked' in changes
|
||||
)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const node = editor.graph.getNode(id)
|
||||
if (!node) return
|
||||
const next = replaceLayerNode(items.value, nodeToLayerNode(node))
|
||||
if (next) items.value = next
|
||||
}
|
||||
|
||||
const unsubscribe = [
|
||||
editor.onEditorEvent('graph:replaced', rebuildTree),
|
||||
editor.onEditorEvent('page:changed', rebuildTree),
|
||||
|
|
@ -66,7 +113,7 @@ const unsubscribe = [
|
|||
editor.onEditorEvent('node:deleted', rebuildTree),
|
||||
editor.onEditorEvent('node:reparented', rebuildTree),
|
||||
editor.onEditorEvent('node:reordered', rebuildTree),
|
||||
editor.onEditorEvent('node:updated', rebuildTree)
|
||||
editor.onEditorEvent('node:updated', patchLayerNode)
|
||||
]
|
||||
|
||||
onScopeDispose(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue