Skip to content

Commit

Permalink
Refactor: make interaction target acquisition faster and more robust (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
monfera authored Mar 20, 2019
1 parent e970140 commit a074f74
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

const ancestorElement = element => {
if (!element) {
return false;
}
// IE11 has no classList on SVG elements, but we're not interested in SVG elements
do {
if (element.classList && element.classList.contains('canvasPage')) {
return element;
}
} while ((element = element.parentElement || element.parentNode)); // no IE11 SVG parentElement
};

const localMousePosition = (box, clientX, clientY) => {
const localMousePosition = (canvasOrigin, clientX, clientY) => {
const { left, top } = canvasOrigin();
return {
x: clientX - box.left,
y: clientY - box.top,
x: clientX - left,
y: clientY - top,
};
};

Expand All @@ -28,28 +17,15 @@ const resetHandler = () => {
window.onmouseup = null;
};

const setupHandler = (commit, target, initialCallback, initialClientX, initialClientY) => {
const setupHandler = (commit, canvasOrigin, initialCallback, initialClientX, initialClientY) => {
// Ancestor has to be identified on setup, rather than 1st interaction, otherwise events may be triggered on
// DOM elements that had been removed: kibana-canvas github issue #1093
const canvasPage = ancestorElement(target);
if (!canvasPage) {
return;
}
const canvasOrigin = canvasPage.getBoundingClientRect();
window.onmousemove = ({
target,
buttons,
clientX,
clientY,
altKey,
metaKey,
shiftKey,
ctrlKey,
}) => {

window.onmousemove = ({ buttons, clientX, clientY, altKey, metaKey, shiftKey, ctrlKey }) => {
const { x, y } = localMousePosition(canvasOrigin, clientX, clientY);
// only commits the cursor position if the target is a nested element of canvasPage
// only commits the cursor position if there's a way to latch onto x/y calculation (canvasOrigin is knowable)
// or if left button is being held down (i.e. an element is being dragged)
if (buttons === 1 || ancestorElement(target)) {
if (buttons === 1 || canvasOrigin) {
commit('cursorPosition', { x, y, altKey, metaKey, shiftKey, ctrlKey });
} else {
// clears cursorPosition
Expand All @@ -71,14 +47,15 @@ const setupHandler = (commit, target, initialCallback, initialClientX, initialCl

const handleMouseMove = (
commit,
{ target, clientX, clientY, altKey, metaKey, shiftKey, ctrlKey },
isEditable
{ clientX, clientY, altKey, metaKey, shiftKey, ctrlKey },
isEditable,
canvasOrigin
) => {
// mouse move must be handled even before an initial click
if (!window.onmousemove && isEditable) {
setupHandler(
commit,
target,
canvasOrigin,
(x, y) => commit('cursorPosition', { x, y, altKey, metaKey, shiftKey, ctrlKey }),
clientX,
clientY
Expand All @@ -88,35 +65,32 @@ const handleMouseMove = (

const handleWheel = (
commit,
{ target, clientX, clientY, altKey, metaKey, shiftKey, ctrlKey },
isEditable
{ clientX, clientY, altKey, metaKey, shiftKey, ctrlKey },
isEditable,
canvasOrigin
) => {
// new mouse position must be registered when page scrolls
if (isEditable) {
setupHandler(
commit,
target,
canvasOrigin,
(x, y) => commit('cursorPosition', { x, y, altKey, metaKey, shiftKey, ctrlKey }),
clientX,
clientY
);
}
};

const handleMouseDown = (commit, e, isEditable) => {
const handleMouseDown = (commit, e, isEditable, canvasOrigin) => {
e.stopPropagation();
const { target, clientX, clientY, buttons, altKey, metaKey, shiftKey, ctrlKey } = e;
const { clientX, clientY, buttons, altKey, metaKey, shiftKey, ctrlKey } = e;
if (buttons !== 1 || !isEditable) {
resetHandler();
return; // left-click and edit mode only
}
const ancestor = ancestorElement(target);
if (!ancestor) {
return;
}
setupHandler(
commit,
ancestor,
canvasOrigin,
(x, y) =>
commit('mouseEvent', { event: 'mouseDown', x, y, altKey, metaKey, shiftKey, ctrlKey }),
clientX,
Expand All @@ -125,8 +99,8 @@ const handleMouseDown = (commit, e, isEditable) => {
};

export const eventHandlers = {
onMouseDown: props => e => handleMouseDown(props.commit, e, props.isEditable),
onMouseMove: props => e => handleMouseMove(props.commit, e, props.isEditable),
onWheel: props => e => handleWheel(props.commit, e, props.isEditable),
onMouseDown: props => e => handleMouseDown(props.commit, e, props.isEditable, props.canvasOrigin),
onMouseMove: props => e => handleMouseMove(props.commit, e, props.isEditable, props.canvasOrigin),
onWheel: props => e => handleWheel(props.commit, e, props.isEditable, props.canvasOrigin),
resetHandler: () => () => resetHandler(),
};
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export const WorkpadPage = compose(
),
withProps(animationProps),
withState('_forceUpdate', 'forceUpdate'), // TODO: phase out this solution
withState('canvasOrigin', 'saveCanvasOrigin'),
withProps(layoutProps), // Updates states; needs to have both local and global
withHandlers(groupHandlerCreators),
withHandlers(eventHandlers) // Captures user intent, needs to have reconciled state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export class WorkpadPage extends PureComponent {
bringToFront: PropTypes.func,
sendBackward: PropTypes.func,
sendToBack: PropTypes.func,
canvasOrigin: PropTypes.func,
saveCanvasOrigin: PropTypes.func.isRequired,
};

componentWillUnmount() {
Expand Down Expand Up @@ -87,6 +89,8 @@ export class WorkpadPage extends PureComponent {
groupElements,
ungroupElements,
forceUpdate,
canvasOrigin,
saveCanvasOrigin,
} = this.props;

let shortcuts = null;
Expand All @@ -112,6 +116,11 @@ export class WorkpadPage extends PureComponent {
<div
key={page.id}
id={page.id}
ref={element => {
if (!canvasOrigin && element && element.getBoundingClientRect) {
saveCanvasOrigin(() => () => element.getBoundingClientRect());
}
}}
data-test-subj="canvasWorkpadPage"
className={`canvasPage ${className} ${isEditable ? 'canvasPage--isEditable' : ''}`}
data-shared-items-container
Expand Down

0 comments on commit a074f74

Please sign in to comment.