🐛 Fixes #1364 - Incorrect mouse selection when zoomed in or out (#1498)

Prior to this change, the mouse selection box had a fixed position on the page. Nodes have absolute
position within NodeView. This inconsistency in positioning caused issues when calculating
if a node was positioned within the mouse selection. This solution makes both nodes
and mouse selection have consistent positioning, along with correctly calculating the
mouse click position within NodeView when making a selection.
This commit is contained in:
Jon Bake 2021-02-28 11:08:14 -06:00 committed by GitHub
parent 725b3eb408
commit 54f949a972
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 18 deletions

View file

@ -23,14 +23,15 @@ export const mouseSelect = mixins(
this.selectBox.id = 'select-box';
this.selectBox.style.margin = '0px auto';
this.selectBox.style.border = '2px dotted #FF0000';
this.selectBox.style.position = 'fixed';
// Positioned absolutely within #node-view. This is consistent with how nodes are positioned.
this.selectBox.style.position = 'absolute';
this.selectBox.style.zIndex = '100';
this.selectBox.style.visibility = 'hidden';
this.selectBox.addEventListener('mouseup', this.mouseUpMouseSelect);
// document.body.appendChild(this.selectBox);
this.$el.appendChild(this.selectBox);
const nodeViewEl = this.$el.querySelector('#node-view') as HTMLDivElement;
nodeViewEl.appendChild(this.selectBox);
},
isCtrlKeyPressed (e: MouseEvent | KeyboardEvent): boolean {
if (this.isTouchDevice === true) {
@ -41,14 +42,28 @@ export const mouseSelect = mixins(
}
return e.ctrlKey;
},
/**
* Gets mouse position within the node view. Both node view offset and scale (zoom) are considered when
* calculating position.
*
* @param event - mouse event within node view
*/
getMousePositionWithinNodeView (event: MouseEvent) {
// @ts-ignore
const nodeViewScale = this.nodeViewScale;
const offsetPosition = this.$store.getters.getNodeViewOffsetPosition;
return {
x: (event.pageX - offsetPosition[0]) / nodeViewScale,
y: (event.pageY - offsetPosition[1]) / nodeViewScale,
};
},
showSelectBox (event: MouseEvent) {
// @ts-ignore
this.selectBox.x = event.pageX;
// @ts-ignore
this.selectBox.y = event.pageY;
this.selectBox = Object.assign(this.selectBox, this.getMousePositionWithinNodeView(event));
this.selectBox.style.left = event.pageX + 'px';
this.selectBox.style.top = event.pageY + 'px';
// @ts-ignore
this.selectBox.style.left = this.selectBox.x + 'px';
// @ts-ignore
this.selectBox.style.top = this.selectBox.y + 'px';
this.selectBox.style.visibility = 'visible';
this.selectActive = true;
@ -75,25 +90,21 @@ export const mouseSelect = mixins(
this.selectActive = false;
},
getSelectionBox (event: MouseEvent) {
const {x, y} = this.getMousePositionWithinNodeView(event);
return {
// @ts-ignore
x: Math.min(event.pageX, this.selectBox.x),
x: Math.min(x, this.selectBox.x),
// @ts-ignore
y: Math.min(event.pageY, this.selectBox.y),
y: Math.min(y, this.selectBox.y),
// @ts-ignore
width: Math.abs(event.pageX - this.selectBox.x),
width: Math.abs(x - this.selectBox.x),
// @ts-ignore
height: Math.abs(event.pageY - this.selectBox.y),
height: Math.abs(y - this.selectBox.y),
};
},
getNodesInSelection (event: MouseEvent): INodeUi[] {
const returnNodes: INodeUi[] = [];
const selectionBox = this.getSelectionBox(event);
const offsetPosition = this.$store.getters.getNodeViewOffsetPosition;
// Consider the offset of the workflow when it got moved
selectionBox.x -= offsetPosition[0];
selectionBox.y -= offsetPosition[1];
// Go through all nodes and check if they are selected
this.$store.getters.allNodes.forEach((node: INodeUi) => {

View file

@ -2139,6 +2139,7 @@ export default mixins(
position: relative;
width: 100%;
height: 100%;
transform-origin: 0 0;
}
.node-view-background {