diff --git a/packages/core/src/auto-imports.d.ts b/packages/core/src/auto-imports.d.ts index af5fbc75..9313ac40 100644 --- a/packages/core/src/auto-imports.d.ts +++ b/packages/core/src/auto-imports.d.ts @@ -176,7 +176,6 @@ declare global { const until: typeof import('@vueuse/core')['until'] const updateEdge: typeof import('./utils/graph')['updateEdge'] const updateEdgeAction: typeof import('./utils/store')['updateEdgeAction'] - const updatePosition: typeof import('./utils/drag')['updatePosition'] const useActions: typeof import('./store/actions')['useActions'] const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] diff --git a/packages/core/src/composables/useDrag.ts b/packages/core/src/composables/useDrag.ts index 12657530..38151f47 100644 --- a/packages/core/src/composables/useDrag.ts +++ b/packages/core/src/composables/useDrag.ts @@ -3,7 +3,7 @@ import { drag } from 'd3-drag' import { select } from 'd3-selection' import type { Ref } from 'vue' import type { MaybeRef } from '@vueuse/core' -import type { NodeDragEvent, NodeDragItem, SnapGrid, XYPosition } from '~/types' +import type { CoordinateExtent, NodeDragEvent, NodeDragItem, SnapGrid, XYPosition } from '~/types' export type UseDragEvent = D3DragEvent @@ -90,8 +90,6 @@ function useDrag(params: UseDragParams) { getNode: $$(getNode), }) onStart(event.sourceEvent, currentNode, nodes) - - dragging.value = true } }) .on('drag', (event: UseDragEvent) => { @@ -99,19 +97,32 @@ function useDrag(params: UseDragParams) { const mousePos = getMousePosition(event, snapGrid) + let hasChange = false + // skip events without movement if ((lastPos.x !== mousePos.x || lastPos.y !== mousePos.y) && dragItems) { lastPos = mousePos - dragItems = dragItems.map((n) => - updatePosition( - n, - mousePos, - !!snapGrid ?? snapToGrid, - snapGrid ?? globalSnapGrid, - n.parentNode ? getNode(n.parentNode) : undefined, - nodeExtent, - ), - ) + + dragItems = dragItems.map((n) => { + const nextPosition = { x: mousePos.x - n.distance.x, y: mousePos.y - n.distance.y } + + if (snapToGrid && snapGrid) { + const [snapX, snapY] = snapGrid + nextPosition.x = snapX * Math.round(nextPosition.x / snapX) + nextPosition.y = snapY * Math.round(nextPosition.y / snapY) + } + + const currentExtent = applyExtent(n, nodeExtent, n.parentNode ? getNode(n.parentNode) : undefined) + + // we want to make sure that we only fire a change event when there is a changes + hasChange = hasChange || n.position.x !== nextPosition.x || n.position.y !== nextPosition.y + + n.position = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition + + return n + }) + + if (!hasChange) return updateNodePositions(dragItems, true, true) diff --git a/packages/core/src/utils/drag.ts b/packages/core/src/utils/drag.ts index 8d815afe..7f9b6309 100644 --- a/packages/core/src/utils/drag.ts +++ b/packages/core/src/utils/drag.ts @@ -1,5 +1,5 @@ import type { Ref } from 'vue' -import type { ComputedGetters, CoordinateExtent, Getters, GraphNode, NodeDragItem, SnapGrid, XYPosition } from '~/types' +import type { ComputedGetters, CoordinateExtent, Getters, GraphNode, NodeDragItem, XYPosition } from '~/types' export function hasSelector(target: Element, selector: string, node: Ref): boolean { let current = target @@ -58,28 +58,6 @@ export function getEventHandlerParams({ return [id ? extendedDragItems.find((n) => n.id === id)! : extendedDragItems[0], extendedDragItems] } -export function updatePosition( - dragItem: NodeDragItem, - mousePos: XYPosition, - snapToGrid?: boolean, - snapGrid?: SnapGrid, - parent?: GraphNode, - nodeExtent?: CoordinateExtent, -): NodeDragItem { - const nextPosition = { x: mousePos.x - dragItem.distance.x, y: mousePos.y - dragItem.distance.y } - if (snapToGrid && snapGrid) { - const [snapX, snapY] = snapGrid - nextPosition.x = snapX * Math.round(nextPosition.x / snapX) - nextPosition.y = snapY * Math.round(nextPosition.y / snapY) - } - - const currentExtent = applyExtent(dragItem, nodeExtent, parent) - - dragItem.position = currentExtent ? clampPosition(nextPosition, currentExtent as CoordinateExtent) : nextPosition - - return dragItem -} - export function applyExtent(item: T, extent?: CoordinateExtent, parent?: GraphNode) { const currentExtent = item.extent ?? extent let nextExtent = currentExtent