From ddaf8ba7962c0fa17a2dfe7bb93900fde7f60041 Mon Sep 17 00:00:00 2001 From: Kienz Date: Fri, 1 Feb 2013 18:27:20 +0100 Subject: [PATCH] Fix touch events if canvas is inside a scrolled container (see issue #123). Fix bug if mouse moves over absolute scrolled element while object scaling (see issue #385). Also if mouse is moved over documentElement (fabric.document) while scaling object is fixed (same issue like #385). Tested with Safari 5.1.7, 6.1, Firefox 18, 3.6.28, Chrome 24/25beta, Opera 12.12 and iPhone iOS 6.1, iPad iOS 6.1 in non-scrolled and scrolled containers. --- src/canvas.class.js | 4 ++-- src/canvas_events.mixin.js | 4 ++-- src/object_interactivity.mixin.js | 2 +- src/util/dom_event.js | 28 +++++++++++++++++++++------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/canvas.class.js b/src/canvas.class.js index 6e7e10cb..b8b3553d 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -339,7 +339,7 @@ _setupCurrentTransform: function (e, target) { var action = 'drag', corner, - pointer = getPointer(e); + pointer = getPointer(e, target.canvas.upperCanvasEl); corner = target._findTargetCorner(e, this._offset); if (corner) { @@ -774,7 +774,7 @@ * @return {Object} object with "x" and "y" number values */ getPointer: function (e) { - var pointer = getPointer(e); + var pointer = getPointer(e, this.upperCanvasEl); return { x: pointer.x - this._offset.left, y: pointer.y - this._offset.top diff --git a/src/canvas_events.mixin.js b/src/canvas_events.mixin.js index 653ab8c1..6a153bdd 100644 --- a/src/canvas_events.mixin.js +++ b/src/canvas_events.mixin.js @@ -290,7 +290,7 @@ // We initially clicked in an empty area, so we draw a box for multiple selection. if (groupSelector !== null) { - pointer = getPointer(e); + pointer = getPointer(e, this.upperCanvasEl); groupSelector.left = pointer.x - this._offset.left - groupSelector.ex; groupSelector.top = pointer.y - this._offset.top - groupSelector.ey; @@ -323,7 +323,7 @@ } else { // object is being transformed (scaled/rotated/moved/etc.) - pointer = getPointer(e); + pointer = getPointer(e, this.upperCanvasEl); var x = pointer.x, y = pointer.y; diff --git a/src/object_interactivity.mixin.js b/src/object_interactivity.mixin.js index e133dca0..f76467b7 100644 --- a/src/object_interactivity.mixin.js +++ b/src/object_interactivity.mixin.js @@ -16,7 +16,7 @@ _findTargetCorner: function(e, offset) { if (!this.hasControls || !this.active) return false; - var pointer = getPointer(e), + var pointer = getPointer(e, this.canvas.upperCanvasEl), ex = pointer.x - offset.left, ey = pointer.y - offset.top, xpoints, diff --git a/src/util/dom_event.js b/src/util/dom_event.js index b34068dc..cda8ff07 100644 --- a/src/util/dom_event.js +++ b/src/util/dom_event.js @@ -172,27 +172,41 @@ * @method getPointer * @memberOf fabric.util * @param {Event} event + * @param {HTMLCanvasElement} upperCanvasEl <canvas> element on which object selection is drawn */ - function getPointer(event) { + function getPointer(event, upperCanvasEl) { event || (event = fabric.window.event); var element = event.target || (typeof event.srcElement !== 'unknown' ? event.srcElement : null), + body = fabric.document.body || {scrollLeft: 0, scrollTop: 0}, + docElement = fabric.document.documentElement, + orgElement = element, scrollLeft = 0, scrollTop = 0, firstFixedAncestor; while (element && element.parentNode && !firstFixedAncestor) { - element = element.parentNode; + element = element.parentNode; - if (element !== fabric.document && fabric.util.getElementPosition(element) === 'fixed') firstFixedAncestor = element; + if (element !== fabric.document && fabric.util.getElementPosition(element) === 'fixed') firstFixedAncestor = element; + if (element !== fabric.document && orgElement !== upperCanvasEl && fabric.util.getElementPosition(element) === 'absolute') { + scrollLeft = 0; + scrollTop = 0; + } + else if (element === fabric.document && orgElement !== upperCanvasEl) { + scrollLeft = body.scrollLeft || docElement.scrollLeft || 0; + scrollTop = body.scrollTop || docElement.scrollTop || 0; + } + else { scrollLeft += element.scrollLeft || 0; scrollTop += element.scrollTop || 0; + } } return { - x: pointerX(event) + scrollLeft, - y: pointerY(event) + scrollTop + x: pointerX(event) + scrollLeft, + y: pointerY(event) + scrollTop }; } @@ -209,10 +223,10 @@ if (fabric.isTouchSupported) { pointerX = function(event) { - return event.touches && event.touches[0] && event.touches[0].pageX || event.clientX; + return (event.touches && event.touches[0] ? (event.touches[0].pageX - (event.touches[0].pageX - event.touches[0].clientX)) || event.clientX : event.clientX); }; pointerY = function(event) { - return event.touches && event.touches[0] && event.touches[0].pageY || event.clientY; + return (event.touches && event.touches[0] ? (event.touches[0].pageY - (event.touches[0].pageY - event.touches[0].clientY)) || event.clientY : event.clientY); }; }