From a6eab8d4e29db55509c4ad56feac942433273b30 Mon Sep 17 00:00:00 2001 From: Kienz Date: Sat, 25 May 2013 17:32:42 +0200 Subject: [PATCH] Fix wrong canvas offset - Copy inline style attributes from lowerCanvasEl to upperCanvasEl - Copy classes from lowerCanvasEl to upperCanvasEl - Add borderTopWidth, borderLeftWidth, paddingTopWidth and paddingLeftWidth (offsetAttributes) to canvas offset (fabric.util.getElementOffset) - these properties are not considered from getBoundingClientRect() - JSfiddle's for tests - new: http://jsfiddle.net/Kienz/KRcsY/, old: http://jsfiddle.net/Kienz/xrMDr/ --- src/canvas.class.js | 15 +++++++++++- src/util/dom_event.js | 4 ++-- src/util/dom_misc.js | 53 ++++++++++++++++++++++++++----------------- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/canvas.class.js b/src/canvas.class.js index 03b9d1c7..16401485 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -746,11 +746,14 @@ * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized */ _createUpperCanvas: function () { + var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''); + this.upperCanvasEl = this._createCanvasElement(); - this.upperCanvasEl.className = 'upper-canvas'; + fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); this.wrapperEl.appendChild(this.upperCanvasEl); + this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl); this._applyCanvasStyle(this.upperCanvasEl); this.contextTop = this.upperCanvasEl.getContext('2d'); }, @@ -802,6 +805,16 @@ fabric.util.makeElementUnselectable(element); }, + /** + * Copys the the entire inline style from one element (fromEl) to another (toEl) + * @private + * @param {Element} fromEl Element style is copied from + * @param {Element} toEl Element copied style is applied to + */ + _copyCanvasStyle: function (fromEl, toEl) { + toEl.style.cssText = fromEl.style.cssText; + }, + /** * Returns context of canvas where object selection is drawn * @return {CanvasRenderingContext2D} diff --git a/src/util/dom_event.js b/src/util/dom_event.js index 0acd1892..3a53a96d 100644 --- a/src/util/dom_event.js +++ b/src/util/dom_event.js @@ -187,9 +187,9 @@ while (element && element.parentNode && !firstFixedAncestor) { element = element.parentNode; - if (element !== fabric.document && fabric.util.getElementPosition(element) === 'fixed') firstFixedAncestor = element; + if (element !== fabric.document && fabric.util.getElementStyle(element, 'position') === 'fixed') firstFixedAncestor = element; - if (element !== fabric.document && orgElement !== upperCanvasEl && fabric.util.getElementPosition(element) === 'absolute') { + if (element !== fabric.document && orgElement !== upperCanvasEl && fabric.util.getElementStyle(element, 'position') === 'absolute') { scrollLeft = 0; scrollTop = 0; } diff --git a/src/util/dom_misc.js b/src/util/dom_misc.js index 724f7be1..22b8f637 100644 --- a/src/util/dom_misc.js +++ b/src/util/dom_misc.js @@ -102,10 +102,23 @@ function getElementOffset(element) { var docElem, win, box = {left: 0, top: 0}, - doc = element && element.ownerDocument; + doc = element && element.ownerDocument, + offset = {left: 0, top: 0}, + offsetAttributes = { + 'borderLeftWidth': 'left', + 'borderTopWidth': 'top', + 'paddingLeft': 'left', + 'paddingTop': 'top' + }; + if (!doc){ return {left: 0, top: 0}; } + + for (var attr in offsetAttributes) { + offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; + } + docElem = doc.documentElement; if ( typeof element.getBoundingClientRect !== "undefined" ) { box = element.getBoundingClientRect(); @@ -116,31 +129,29 @@ win = doc.nodeType === 9 && doc.defaultView; } return { - left: box.left + win.pageXOffset - (docElem.clientLeft || 0), - top: box.top + win.pageYOffset - (docElem.clientTop || 0) + left: box.left + win.pageXOffset - (docElem.clientLeft || 0) + offset.left, + top: box.top + win.pageYOffset - (docElem.clientTop || 0) + offset.top }; } /** - * Returns position of a given element - * @function + * Returns style attribute value of a given element * @memberOf fabric.util - * @param {HTMLElement} element Element to get offset for - * @return {Object} position of the given element. + * @param {HTMLElement} element Element to get style attribute for + * @param {String} attr Style attribute to get for element + * @return {String} Style attribute value of the given element. */ - var getElementPosition; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementPosition = function (element) { - return fabric.document.defaultView.getComputedStyle(element, null).position; - }; - } - else { - /** @ignore */ - getElementPosition = function (element) { - var value = element.style.position; - if (!value && element.currentStyle) value = element.currentStyle.position; - return value; - }; + function getElementStyle(element, attr) { + element.style = element.style || { }; + + if (element.currentStyle) { + return element.currentStyle[attr]; + } + else if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { + return fabric.document.defaultView.getComputedStyle(element, null)[attr]; + } + + return element.style[attr]; } (function () { @@ -237,6 +248,6 @@ fabric.util.addClass = addClass; fabric.util.wrapElement = wrapElement; fabric.util.getElementOffset = getElementOffset; - fabric.util.getElementPosition = getElementPosition; + fabric.util.getElementStyle = getElementStyle; })();