fix(drag): use correct coordinates closes #72
This commit is contained in:
@@ -1,19 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* The nodes selection rectangle gets displayed when a user
|
||||||
|
* made a selectio with on or several nodes
|
||||||
|
*/
|
||||||
|
|
||||||
import React, { useState, memo } from 'react';
|
import React, { useState, memo } from 'react';
|
||||||
import ReactDraggable from 'react-draggable';
|
import ReactDraggable from 'react-draggable';
|
||||||
|
|
||||||
import { useStoreState, useStoreActions } from '../../store/hooks';
|
import { useStoreState, useStoreActions } from '../../store/hooks';
|
||||||
import { isNode } from '../../utils/graph';
|
import { isNode } from '../../utils/graph';
|
||||||
import { Node, Elements, XYPosition } from '../../types';
|
import { Node, XYPosition } from '../../types';
|
||||||
|
|
||||||
type StartPositions = { [key: string]: XYPosition };
|
type StartPositions = { [key: string]: XYPosition };
|
||||||
|
|
||||||
function getStartPositions(elements: Elements): StartPositions {
|
function getStartPositions(nodes: Node[]): StartPositions {
|
||||||
const startPositions: StartPositions = {};
|
const startPositions: StartPositions = {};
|
||||||
|
|
||||||
return (elements.filter(isNode) as Node[]).reduce((res, node) => {
|
return nodes.reduce((res, node) => {
|
||||||
const startPosition = {
|
const startPosition = {
|
||||||
x: node.__rg.position.x || node.position.x,
|
x: node.__rg.position.x || node.position.x,
|
||||||
y: node.__rg.position.y || node.position.x,
|
y: node.__rg.position.y || node.position.y,
|
||||||
};
|
};
|
||||||
|
|
||||||
res[node.id] = startPosition;
|
res[node.id] = startPosition;
|
||||||
@@ -30,21 +35,26 @@ export default memo(() => {
|
|||||||
selectedNodesBbox: s.selectedNodesBbox,
|
selectedNodesBbox: s.selectedNodesBbox,
|
||||||
selectedElements: s.selectedElements,
|
selectedElements: s.selectedElements,
|
||||||
snapToGrid: s.snapToGrid,
|
snapToGrid: s.snapToGrid,
|
||||||
snapGrid: s.snapGrid
|
snapGrid: s.snapGrid,
|
||||||
|
nodes: s.nodes,
|
||||||
}));
|
}));
|
||||||
const updateNodePos = useStoreActions(a => a.updateNodePos);
|
const updateNodePos = useStoreActions(a => a.updateNodePos);
|
||||||
const [x, y, k] = state.transform;
|
const [tx, ty, tScale] = state.transform;
|
||||||
const position = state.selectedNodesBbox;
|
const position = state.selectedNodesBbox;
|
||||||
const grid = (state.snapToGrid ? state.snapGrid : [1, 1])! as [number, number];
|
const grid = (state.snapToGrid ? state.snapGrid : [1, 1])! as [number, number];
|
||||||
|
|
||||||
const onStart = (evt: MouseEvent) => {
|
const onStart = (evt: MouseEvent) => {
|
||||||
const scaledClient: XYPosition = {
|
const scaledClient: XYPosition = {
|
||||||
x: evt.clientX * (1 / k),
|
x: evt.clientX / tScale,
|
||||||
y: evt.clientY * (1 / k),
|
y: evt.clientY / tScale,
|
||||||
};
|
};
|
||||||
const offsetX: number = scaledClient.x - position.x - x;
|
const offsetX: number = scaledClient.x - position.x - tx;
|
||||||
const offsetY: number = scaledClient.y - position.y - y;
|
const offsetY: number = scaledClient.y - position.y - ty;
|
||||||
const nextStartPositions = getStartPositions(state.selectedElements);
|
const selectedNodes = (state.selectedElements.filter(isNode) as Node[]).map(
|
||||||
|
selectedNode => state.nodes.find(node => node.id === selectedNode.id)! as Node
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextStartPositions = getStartPositions(selectedNodes);
|
||||||
|
|
||||||
if (nextStartPositions) {
|
if (nextStartPositions) {
|
||||||
setOffset({ x: offsetX, y: offsetY });
|
setOffset({ x: offsetX, y: offsetY });
|
||||||
@@ -54,24 +64,14 @@ export default memo(() => {
|
|||||||
|
|
||||||
const onDrag = (evt: MouseEvent) => {
|
const onDrag = (evt: MouseEvent) => {
|
||||||
const scaledClient: XYPosition = {
|
const scaledClient: XYPosition = {
|
||||||
x: evt.clientX * (1 / k),
|
x: evt.clientX / tScale,
|
||||||
y: evt.clientY * (1 / k),
|
y: evt.clientY / tScale,
|
||||||
};
|
};
|
||||||
|
|
||||||
(state.selectedElements.filter(isNode) as Node[]).forEach(node => {
|
(state.selectedElements.filter(isNode) as Node[]).forEach(node => {
|
||||||
const pos: XYPosition = {
|
const pos: XYPosition = {
|
||||||
x:
|
x: startPositions[node.id].x + scaledClient.x - position.x - offset.x - tx,
|
||||||
startPositions[node.id].x +
|
y: startPositions[node.id].y + scaledClient.y - position.y - offset.y - ty,
|
||||||
scaledClient.x -
|
|
||||||
position.x -
|
|
||||||
offset.x -
|
|
||||||
x,
|
|
||||||
y:
|
|
||||||
startPositions[node.id].y +
|
|
||||||
scaledClient.y -
|
|
||||||
position.y -
|
|
||||||
offset.y -
|
|
||||||
y,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
updateNodePos({ id: node.id, pos });
|
updateNodePos({ id: node.id, pos });
|
||||||
@@ -82,11 +82,11 @@ export default memo(() => {
|
|||||||
<div
|
<div
|
||||||
className="react-flow__nodesselection"
|
className="react-flow__nodesselection"
|
||||||
style={{
|
style={{
|
||||||
transform: `translate(${x}px,${y}px) scale(${k})`,
|
transform: `translate(${tx}px,${ty}px) scale(${tScale})`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ReactDraggable
|
<ReactDraggable
|
||||||
scale={k}
|
scale={tScale}
|
||||||
grid={grid}
|
grid={grid}
|
||||||
onStart={evt => onStart(evt as MouseEvent)}
|
onStart={evt => onStart(evt as MouseEvent)}
|
||||||
onDrag={evt => onDrag(evt as MouseEvent)}
|
onDrag={evt => onDrag(evt as MouseEvent)}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* The user selection rectangle gets displayed when a user drags the mouse while pressing shift
|
||||||
|
*/
|
||||||
|
|
||||||
import React, { useEffect, useRef, useState, memo } from 'react';
|
import React, { useEffect, useRef, useState, memo } from 'react';
|
||||||
|
|
||||||
import { useStoreActions } from '../../store/hooks';
|
import { useStoreActions } from '../../store/hooks';
|
||||||
|
|||||||
@@ -226,7 +226,6 @@ const storeModel: StoreModel = {
|
|||||||
state.selection = selection;
|
state.selection = selection;
|
||||||
state.nodesSelectionActive = true;
|
state.nodesSelectionActive = true;
|
||||||
state.selectedNodesBbox = selectedNodesBbox;
|
state.selectedNodesBbox = selectedNodesBbox;
|
||||||
state.nodesSelectionActive = true;
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setSelectedElements: action((state, elements) => {
|
setSelectedElements: action((state, elements) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user