From 8a0a928e17dc9631fda9d63322d3a85c14127f25 Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 11 Sep 2020 17:12:09 +0200 Subject: [PATCH] refactor(nodes): always render nodes that are dragged closes #477 --- src/components/Nodes/wrapNode.tsx | 4 +++ src/components/NodesSelection/index.tsx | 7 ++++++ src/container/NodeRenderer/index.tsx | 1 + src/store/index.ts | 33 +++++++++++-------------- src/types/index.ts | 4 ++- src/utils/graph.ts | 5 ++-- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/components/Nodes/wrapNode.tsx b/src/components/Nodes/wrapNode.tsx index df85651f..6a13af1a 100644 --- a/src/components/Nodes/wrapNode.tsx +++ b/src/components/Nodes/wrapNode.tsx @@ -154,6 +154,10 @@ export default (NodeComponent: ComponentType) => { } setDragging(false); + updateNodePosDiff({ + id, + isDragging: false, + }); onNodeDragStop?.(event as MouseEvent, node); }, diff --git a/src/components/NodesSelection/index.tsx b/src/components/NodesSelection/index.tsx index c46e7b9e..4ac117b6 100644 --- a/src/components/NodesSelection/index.tsx +++ b/src/components/NodesSelection/index.tsx @@ -73,6 +73,13 @@ export default ({ const onStop = useCallback( (event: MouseEvent) => { + selectedNodes?.forEach((node) => { + updateNodePosDiff({ + id: node.id, + isDragging: false, + }); + }); + onSelectionDragStop?.(event, selectedNodes); }, [selectedNodes, onSelectionDragStop] diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx index bf2187a9..18674df8 100644 --- a/src/container/NodeRenderer/index.tsx +++ b/src/container/NodeRenderer/index.tsx @@ -49,6 +49,7 @@ function renderNode( data={node.data} xPos={node.__rf.position.x} yPos={node.__rf.position.y} + isDragging={node.__rf.isDragging} onClick={props.onElementClick} onMouseEnter={props.onNodeMouseEnter} onMouseMove={props.onNodeMouseMove} diff --git a/src/store/index.ts b/src/store/index.ts index ec39cac5..85e08fba 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -227,11 +227,9 @@ export const storeModel: StoreModel = { state.elements.forEach((n) => { if (n.id === id && isNode(n)) { - n.__rf = { - ...n.__rf, - ...dimensions, - handleBounds, - }; + n.__rf.width = dimensions.width; + n.__rf.height = dimensions.height; + n.__rf.handleBounds = handleBounds; } }); }), @@ -249,24 +247,21 @@ export const storeModel: StoreModel = { state.elements.forEach((n) => { if (n.id === id && isNode(n)) { - n.__rf = { - ...n.__rf, - position, - }; + n.__rf.position = position; } }); }), - updateNodePosDiff: action((state, { id, diff }) => { + updateNodePosDiff: action((state, { id, diff = null, isDragging = true }) => { state.elements.forEach((n) => { if (n.id === id && isNode(n)) { - n.__rf = { - ...n.__rf, - position: { + if (diff) { + n.__rf.position = { x: n.__rf.position.x + diff.x, y: n.__rf.position.y + diff.y, - }, - }; + }; + } + n.__rf.isDragging = isDragging; } }); }), @@ -316,7 +311,7 @@ export const storeModel: StoreModel = { if (!selectedNodes) { state.selectionActive = false; - state.userSelectionRect = { ...state.userSelectionRect, draw: false }; + state.userSelectionRect.draw = false; state.nodesSelectionActive = false; state.selectedElements = null; @@ -328,7 +323,7 @@ export const storeModel: StoreModel = { state.nodesSelectionActive = true; state.selectedNodesBbox = selectedNodesBbox; - state.userSelectionRect = { ...state.userSelectionRect, draw: false }; + state.userSelectionRect.draw = false; state.selectionActive = false; }), @@ -454,7 +449,9 @@ export const storeModel: StoreModel = { // we need to sync the d3 zoom transform with the fitted transform d3Selection.property('__zoom', fittedTransform); - state.transform = [fittedTransform.x, fittedTransform.y, fittedTransform.k]; + state.transform[0] = fittedTransform.x; + state.transform[1] = fittedTransform.y; + state.transform[2] = fittedTransform.k; }), zoomTo: action((state, zoomLevel) => { diff --git a/src/types/index.ts b/src/types/index.ts index ae9f53c7..96730e61 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -174,6 +174,7 @@ export interface WrapNodeProps { isInitialized?: boolean; snapToGrid?: boolean; snapGrid?: [number, number]; + isDragging?: boolean; } export type FitViewParams = { @@ -271,7 +272,8 @@ export type NodePosUpdate = { export type NodeDiffUpdate = { id: ElementId; - diff: XYPosition; + diff?: XYPosition; + isDragging?: boolean; }; export type FlowTransform = { diff --git a/src/utils/graph.ts b/src/utils/graph.ts index 6f341ac9..d31c00cb 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -126,6 +126,7 @@ export const parseElement = (element: Node | Edge): Node | Edge => { width: null, height: null, handleBounds: {}, + isDragging: false, }, } as Node; }; @@ -182,13 +183,13 @@ export const getNodesInside = ( height: rect.height / tScale, }); - return nodes.filter(({ __rf: { position, width, height } }) => { + return nodes.filter(({ __rf: { position, width, height, isDragging } }) => { const nBox = rectToBox({ ...position, width, height }); const xOverlap = Math.max(0, Math.min(rBox.x2, nBox.x2) - Math.max(rBox.x, nBox.x)); const yOverlap = Math.max(0, Math.min(rBox.y2, nBox.y2) - Math.max(rBox.y, nBox.y)); const overlappingArea = xOverlap * yOverlap; - if (width === null || height === null) { + if (width === null || height === null || isDragging) { // at the beginnning all nodes have width & height === 0 return true; }