feat(engine): canvas panning, wheel zoom and link editing tools
Drag empty space to pan, mouse-wheel to zoom, and selecting a link now shows vertex/segment/arrowhead/remove tools so connectors can be rerouted and deleted interactively. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8779c88e66
commit
e43ace1853
@ -3,7 +3,7 @@
|
||||
* framework-agnostic API for the React shell: add nodes, edit properties,
|
||||
* select/delete/copy, undo/redo, configure, save/load and run the mock flow.
|
||||
*/
|
||||
import { dia, shapes, highlighters, g } from '@joint/core'
|
||||
import { dia, shapes, highlighters, linkTools, g } from '@joint/core'
|
||||
import {
|
||||
PipelineNode,
|
||||
createNode,
|
||||
@ -113,10 +113,47 @@ export class DiagramController {
|
||||
}
|
||||
})
|
||||
|
||||
// Pan the canvas by dragging empty space.
|
||||
let pan: { tx: number; ty: number; x: number; y: number } | null = null
|
||||
paper.on('blank:pointerdown', (evt: dia.Event) => {
|
||||
const t = paper.translate()
|
||||
pan = { tx: t.tx, ty: t.ty, x: evt.clientX ?? 0, y: evt.clientY ?? 0 }
|
||||
})
|
||||
paper.on('blank:pointermove', (evt: dia.Event) => {
|
||||
if (!pan) return
|
||||
paper.translate(pan.tx + ((evt.clientX ?? 0) - pan.x), pan.ty + ((evt.clientY ?? 0) - pan.y))
|
||||
})
|
||||
paper.on('blank:pointerup', () => (pan = null))
|
||||
|
||||
// Wheel to zoom toward the cursor.
|
||||
paper.on('blank:mousewheel', (evt: dia.Event, _x, _y, delta: number) => {
|
||||
evt.preventDefault?.()
|
||||
this.zoom(delta > 0 ? 1.1 : 1 / 1.1)
|
||||
})
|
||||
paper.on('cell:mousewheel', (_v, evt: dia.Event, _x, _y, delta: number) => {
|
||||
evt.preventDefault?.()
|
||||
this.zoom(delta > 0 ? 1.1 : 1 / 1.1)
|
||||
})
|
||||
|
||||
this.graph.on('remove', () => !this.restoring && this.fire('change'))
|
||||
this.graph.on('add', () => !this.restoring && this.fire('change'))
|
||||
}
|
||||
|
||||
private addLinkTools(link: dia.Link): void {
|
||||
const view = this.paper?.findViewByModel(link)
|
||||
if (!view) return
|
||||
view.addTools(
|
||||
new dia.ToolsView({
|
||||
tools: [
|
||||
new linkTools.Vertices(),
|
||||
new linkTools.Segments(),
|
||||
new linkTools.TargetArrowhead(),
|
||||
new linkTools.Remove({ distance: 20 })
|
||||
]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
private validateConnection = (
|
||||
sourceView: dia.CellView,
|
||||
sourceMagnet: SVGElement | null,
|
||||
@ -197,6 +234,7 @@ export class DiagramController {
|
||||
padding: 4,
|
||||
attrs: { stroke: '#f0c000', 'stroke-width': 2 }
|
||||
})
|
||||
if (cell.isLink()) this.addLinkTools(cell as dia.Link)
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +244,10 @@ export class DiagramController {
|
||||
if (!cell) continue
|
||||
if (!cell.isLink()) this.setPortsVisible(cell as dia.Element, false)
|
||||
const view = this.paper?.findViewByModel(cell)
|
||||
if (view) highlighters.mask.remove(view, 'sel')
|
||||
if (view) {
|
||||
highlighters.mask.remove(view, 'sel')
|
||||
if (cell.isLink()) view.removeTools()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user