Skip to content

Commit

Permalink
Remove position pre-calculation, fixes #1559
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmartel committed Nov 28, 2023
1 parent f351592 commit 13f16ce
Show file tree
Hide file tree
Showing 9 changed files with 595 additions and 357 deletions.
61 changes: 15 additions & 46 deletions src/app/toolboxController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {InteractionEventNames, getEventOffset} from '../gui/generic';
import {InteractionEventNames} from '../gui/generic';

// doc imports
/* eslint-disable no-unused-vars */
Expand Down Expand Up @@ -56,7 +56,7 @@ export class ToolboxController {
}
// keydown listener
window.addEventListener('keydown',
this.#getOnMouch('window', 'keydown'), true);
this.#getCallback('window', 'keydown'), true);
}

/**
Expand Down Expand Up @@ -185,7 +185,7 @@ export class ToolboxController {
const names = InteractionEventNames;
for (let i = 0; i < names.length; ++i) {
layer.addEventListener(names[i],
this.#getOnMouch(layer.getId(), names[i]));
this.#getCallback(layer.getId(), names[i]));
}
}

Expand All @@ -200,7 +200,7 @@ export class ToolboxController {
const names = InteractionEventNames;
for (let i = 0; i < names.length; ++i) {
layer.removeEventListener(names[i],
this.#getOnMouch(layer.getId(), names[i]));
this.#getCallback(layer.getId(), names[i]));
}
}

Expand All @@ -213,54 +213,23 @@ export class ToolboxController {
* @param {string} eventType The event type.
* @returns {object} A callback for the provided layer and event.
*/
#getOnMouch(layerId, eventType) {
// augment event with converted offsets
const augmentEventOffsets = function (event) {
// event offset(s)
const offsets = getEventOffset(event);
// should have at least one offset
event._x = offsets[0].x;
event._y = offsets[0].y;
// possible second
if (offsets.length === 2) {
event._x1 = offsets[1].x;
event._y1 = offsets[1].y;
}
};

const applySelectedTool = (event) => {
// make sure we have a tool
if (this.#selectedTool) {
const func = this.#selectedTool[event.type];
if (func) {
func(event);
}
}
};

#getCallback(layerId, eventType) {
if (typeof this.#callbackStore[layerId] === 'undefined') {
this.#callbackStore[layerId] = [];
}

if (typeof this.#callbackStore[layerId][eventType] === 'undefined') {
let callback = null;
if (eventType === 'keydown') {
callback = function (event) {
applySelectedTool(event);
};
} else if (eventType === 'touchend') {
callback = function (event) {
applySelectedTool(event);
};
} else {
// mouse or touch events
callback = function (event) {
augmentEventOffsets(event);
applySelectedTool(event);
};
}
const applySelectedTool = (event) => {
// make sure we have a tool
if (this.#selectedTool) {
const func = this.#selectedTool[event.type];
if (func) {
func(event);
}
}
};
// store callback
this.#callbackStore[layerId][eventType] = callback;
this.#callbackStore[layerId][eventType] = applySelectedTool;
}

return this.#callbackStore[layerId][eventType];
Expand Down
43 changes: 26 additions & 17 deletions src/gui/generic.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {logger} from '../utils/logger';
import {Point2D} from '../math/point';

/**
* List of interaction event names.
Expand Down Expand Up @@ -63,7 +64,7 @@ export const customUI = {
* Get the positions (without the parent offset) of a list of touch events.
*
* @param {Array} touches The list of touch events.
* @returns {Array} The list of positions of the touch events.
* @returns {Point2D[]} The list of positions of the touch events.
*/
function getTouchesPositions(touches) {
// get the touch offset from all its parents
Expand All @@ -87,21 +88,21 @@ function getTouchesPositions(touches) {
// set its position
const positions = [];
for (let i = 0; i < touches.length; ++i) {
positions.push({
x: touches[i].pageX - offsetLeft,
y: touches[i].pageY - offsetTop
});
positions.push(new Point2D(
touches[i].pageX - offsetLeft,
touches[i].pageY - offsetTop
));
}
return positions;
}

/**
* Get the offset of an input event.
* Get the offsets of an input touch event.
*
* @param {object} event The event to get the offset from.
* @returns {Array} The array of offsets.
* @returns {Point2D[]} The array of points.
*/
export function getEventOffset(event) {
export function getTouchPoints(event) {
let positions = [];
if (typeof event.targetTouches !== 'undefined' &&
event.targetTouches.length !== 0) {
Expand All @@ -111,19 +112,27 @@ export function getEventOffset(event) {
event.changedTouches.length !== 0) {
// see https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/changedTouches
positions = getTouchesPositions(event.changedTouches);
} else {
// offsetX/Y: the offset in the X coordinate of the mouse pointer
// between that event and the padding edge of the target node
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX
// https://caniuse.com/mdn-api_mouseevent_offsetx
positions.push({
x: event.offsetX,
y: event.offsetY
});
}
return positions;
}

/**
* Get the offset of an input mouse event.
*
* @param {object} event The event to get the offset from.
* @returns {Point2D} The 2D point.
*/
export function getMousePoint(event) {
// offsetX/Y: the offset in the X coordinate of the mouse pointer
// between that event and the padding edge of the target node
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX
// https://caniuse.com/mdn-api_mouseevent_offsetx
return new Point2D(
event.offsetX,
event.offsetY
);
}

/**
* Test if a canvas with the input size can be created.
*
Expand Down
105 changes: 72 additions & 33 deletions src/tools/draw.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {getLayerDetailsFromEvent} from '../gui/layerGroup';
import {
getEventOffset,
getMousePoint,
getTouchPoints,
customUI
} from '../gui/generic';
import {Point2D} from '../math/point';
Expand Down Expand Up @@ -227,25 +228,25 @@ export class Draw {
#lastIsMouseMovePoint = false;

/**
* Handle mouse down event.
* Start tool interaction.
*
* @param {object} event The mouse down event.
* @param {Point2D} point The start point.
* @param {string} divId The layer group divId.
*/
mousedown = (event) => {
#start(point, divId) {
// exit if a draw was started (handle at mouse move or up)
if (this.#started) {
return;
}

const layerDetails = getLayerDetailsFromEvent(event);
const layerGroup = this.#app.getLayerGroupByDivId(layerDetails.groupDivId);
const layerGroup = this.#app.getLayerGroupByDivId(divId);
const drawLayer = layerGroup.getActiveDrawLayer();

// determine if the click happened in an existing shape
const stage = drawLayer.getKonvaStage();
const kshape = stage.getIntersection({
x: event._x,
y: event._y
x: point.getX(),
y: point.getY()
});

// update scale
Expand Down Expand Up @@ -277,30 +278,26 @@ export class Draw {
this.#points = [];
// store point
const viewLayer = layerGroup.getActiveViewLayer();
this.#lastPoint = viewLayer.displayToPlanePos(
new Point2D(event._x, event._y)
);
this.#lastPoint = viewLayer.displayToPlanePos(point);
this.#points.push(this.#lastPoint);
}
};
}

/**
* Handle mouse move event.
* Update tool interaction.
*
* @param {object} event The mouse move event.
* @param {Point2D} point The update point.
* @param {string} divId The layer group divId.
*/
mousemove = (event) => {
#update(point, divId) {
// exit if not started draw
if (!this.#started) {
return;
}

const layerDetails = getLayerDetailsFromEvent(event);
const layerGroup = this.#app.getLayerGroupByDivId(layerDetails.groupDivId);
const layerGroup = this.#app.getLayerGroupByDivId(divId);
const viewLayer = layerGroup.getActiveViewLayer();
const pos = viewLayer.displayToPlanePos(
new Point2D(event._x, event._y)
);
const pos = viewLayer.displayToPlanePos(point);

// draw line to current pos
if (Math.abs(pos.getX() - this.#lastPoint.getX()) > 0 ||
Expand All @@ -318,14 +315,14 @@ export class Draw {
// update points
this.#onNewPoints(this.#points, layerGroup);
}
};
}

/**
* Handle mouse up event.
* Finish tool interaction.
*
* @param {object} event The mouse up event.
* @param {string} divId The layer group divId.
*/
mouseup = (event) => {
#finish(divId) {
// exit if not started draw
if (!this.#started) {
return;
Expand All @@ -339,16 +336,47 @@ export class Draw {
// do we have all the needed points
if (this.#points.length === this.#currentFactory.getNPoints()) {
// store points
const layerDetails = getLayerDetailsFromEvent(event);
const layerGroup =
this.#app.getLayerGroupByDivId(layerDetails.groupDivId);
this.#app.getLayerGroupByDivId(divId);
this.#onFinalPoints(this.#points, layerGroup);
// reset flag
this.#started = false;
}

// reset mouse move point flag
this.#lastIsMouseMovePoint = false;
}

/**
* Handle mouse down event.
*
* @param {object} event The mouse down event.
*/
mousedown = (event) => {
const mousePoint = getMousePoint(event);
const layerDetails = getLayerDetailsFromEvent(event);
this.#start(mousePoint, layerDetails.groupDivId);
};

/**
* Handle mouse move event.
*
* @param {object} event The mouse move event.
*/
mousemove = (event) => {
const mousePoint = getMousePoint(event);
const layerDetails = getLayerDetailsFromEvent(event);
this.#update(mousePoint, layerDetails.groupDivId);
};

/**
* Handle mouse up event.
*
* @param {object} event The mouse up event.
*/
mouseup = (event) => {
const layerDetails = getLayerDetailsFromEvent(event);
this.#finish(layerDetails.groupDivId);
};

/**
Expand Down Expand Up @@ -385,7 +413,8 @@ export class Draw {
* @param {object} event The mouse out event.
*/
mouseout = (event) => {
this.mouseup(event);
const layerDetails = getLayerDetailsFromEvent(event);
this.#finish(layerDetails.groupDivId);
};

/**
Expand All @@ -394,7 +423,9 @@ export class Draw {
* @param {object} event The touch start event.
*/
touchstart = (event) => {
this.mousedown(event);
const touchPoints = getTouchPoints(event);
const layerDetails = getLayerDetailsFromEvent(event);
this.#start(touchPoints[0], layerDetails.groupDivId);
};

/**
Expand All @@ -409,11 +440,11 @@ export class Draw {
}

const layerDetails = getLayerDetailsFromEvent(event);
const touchPoints = getTouchPoints(event);

const layerGroup = this.#app.getLayerGroupByDivId(layerDetails.groupDivId);
const viewLayer = layerGroup.getActiveViewLayer();
const pos = viewLayer.displayToPlanePos(
new Point2D(event._x, event._y)
);
const pos = viewLayer.displayToPlanePos(touchPoints[0]);

if (Math.abs(pos.getX() - this.#lastPoint.getX()) > 0 ||
Math.abs(pos.getY() - this.#lastPoint.getY()) > 0) {
Expand Down Expand Up @@ -823,7 +854,11 @@ export class Draw {
factory.updateQuantification(group, vc);
}
// highlight trash when on it
const offset = getEventOffset(event.evt)[0];
const mousePoint = getMousePoint(event.evt);
const offset = {
x: mousePoint.getX(),
y: mousePoint.getY()
};
const eventPos = this.#getRealPosition(offset, layerGroup);
const trashHalfWidth =
this.#trash.width() * Math.abs(this.#trash.scaleX()) / 2;
Expand Down Expand Up @@ -876,7 +911,11 @@ export class Draw {
}
const pos = {x: group.x(), y: group.y()};
// delete case
const offset = getEventOffset(event.evt)[0];
const mousePoint = getMousePoint(event.evt);
const offset = {
x: mousePoint.getX(),
y: mousePoint.getY()
};
const eventPos = this.#getRealPosition(offset, layerGroup);
const trashHalfWidth =
this.#trash.width() * Math.abs(this.#trash.scaleX()) / 2;
Expand Down
Loading

0 comments on commit 13f16ce

Please sign in to comment.