ensuring node can only be dragged within constraints

This commit is contained in:
Alex Windett 2017-03-20 12:40:03 +00:00 committed by Sérgio Ramos
parent 7a2a1f95a6
commit 5459220c77
2 changed files with 64 additions and 42 deletions

View File

@ -5,6 +5,7 @@ import Constants from './constants';
import GraphNode from './graph-node'; import GraphNode from './graph-node';
import GraphLink from './graph-link'; import GraphLink from './graph-link';
import React from 'react'; import React from 'react';
import { triggerMouseEvent } from '../../shared/functions';
const StyledSvg = styled.svg` const StyledSvg = styled.svg`
width: 100%; width: 100%;
@ -102,6 +103,28 @@ class TopologyGraph extends React.Component {
} }
} }
isWithinSVGBounds(target, x, y) {
const svgBounds = document
.getElementsByClassName('topology-svg')[0]
.getBoundingClientRect();
const nodeHeight = target.getBoundingClientRect().height;
const nodeWidth = target.getBoundingClientRect().width;
const constraints = {
top: svgBounds.top + (nodeHeight / 2),
left: svgBounds.left + (nodeWidth / 2),
bottom: svgBounds.bottom - (nodeHeight / 2),
right: svgBounds.right - (nodeWidth / 2)
};
if ( x > constraints.right || x < constraints.left ) return false;
if ( y < constraints.top || y > constraints.bottom ) return false;
return true;
}
render() { render() {
const { const {
@ -123,6 +146,7 @@ class TopologyGraph extends React.Component {
x: svgSize.width - Constants.nodeSize.width, x: svgSize.width - Constants.nodeSize.width,
y: 0 y: 0
} : simNode(service.uuid); } : simNode(service.uuid);
return ({ return ({
...service, ...service,
...sNode ...sNode
@ -143,40 +167,38 @@ class TopologyGraph extends React.Component {
// it's this node's position that we'll need to update // it's this node's position that we'll need to update
dragInfo.dragging = true; dragInfo.dragging = true;
dragInfo.nodeId = nodeId; dragInfo.nodeId = nodeId;
if(evt.changedTouches) {
const x = evt.changedTouches ? evt.changedTouches[0].pageX : evt.clientX;
const y = evt.changedTouches ? evt.changedTouches[0].pageY : evt.clientY;
dragInfo.position = { dragInfo.position = {
x: evt.changedTouches[0].pageX, x,
y: evt.changedTouches[0].pageY y
}; };
}
else {
dragInfo.position = {
x: evt.clientX,
y: evt.clientY
};
}
}; };
const onDragMove = (evt) => { const onDragMove = (evt) => {
if(dragInfo.dragging) { if ( dragInfo.dragging ) {
let offset = {}; const x = evt.changedTouches
if(evt.changedTouches) { ? evt.changedTouches[0].pageX
offset = { : evt.clientX;
x: evt.changedTouches[0].pageX - dragInfo.position.x, const y = evt.changedTouches
y: evt.changedTouches[0].pageY - dragInfo.position.y ? evt.changedTouches[0].pageY
}; : evt.clientY;
if ( !this.isWithinSVGBounds(evt.target, x, y) ) {
triggerMouseEvent(evt.target, 'mouseup');
} }
else {
offset = { const offset = {
x: evt.clientX - dragInfo.position.x, x: x - dragInfo.position.x,
y: evt.clientY - dragInfo.position.y y: y - dragInfo.position.y
}; };
}
const dragNodes = nodes.map((simNode, index) => { const dragNodes = nodes.map((simNode, index) => {
if(simNode.id === dragInfo.nodeId) { if ( simNode.id === dragInfo.nodeId ) {
return ({ return ({
...simNode, ...simNode,
x: simNode.x + offset.x, x: simNode.x + offset.x,
@ -192,26 +214,18 @@ class TopologyGraph extends React.Component {
nodes: dragNodes nodes: dragNodes
}); });
if(evt.changedTouches) {
dragInfo.position = { dragInfo.position = {
x: evt.changedTouches[0].pageX, x,
y: evt.changedTouches[0].pageY y
}; };
} }
else {
dragInfo.position = {
x: evt.clientX,
y: evt.clientY
};
}
}
}; };
const onDragEnd = (evt) => { const onDragEnd = (evt) => {
dragInfo = { dragInfo = {
dragging: false, dragging: false,
nodeId: null, nodeId: null,
position: null position: {}
}; };
}; };
@ -241,6 +255,7 @@ class TopologyGraph extends React.Component {
onMouseUp={onDragEnd} onMouseUp={onDragEnd}
onTouchEnd={onDragEnd} onTouchEnd={onDragEnd}
onTouchCancel={onDragEnd} onTouchCancel={onDragEnd}
className='topology-svg'
> >
<g> <g>
{renderedNodes} {renderedNodes}

View File

@ -51,6 +51,12 @@ const isAnd = (...names) =>
? css(...args) ? css(...args)
: css``; : css``;
const triggerMouseEvent = (trg, ev) => {
const clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent(ev, true, true);
trg.dispatchEvent(clickEvent);
};
export { export {
unitcalc, unitcalc,
remcalc, remcalc,
@ -58,5 +64,6 @@ export {
rndId, rndId,
is, is,
isNot, isNot,
isAnd isAnd,
triggerMouseEvent
}; };