diff --git a/src/canvas.class.js b/src/canvas.class.js index 9a83c2fa..653ae932 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -816,6 +816,8 @@ bounds = upperCanvasEl.getBoundingClientRect(), cssScale; + this.calcOffset(); + pointer.x = pointer.x - this._offset.left; pointer.y = pointer.y - this._offset.top; if (!ignoreZoom) { @@ -835,6 +837,7 @@ height: upperCanvasEl.height / bounds.height }; } + return { x: pointer.x * cssScale.width, y: pointer.y * cssScale.height diff --git a/src/node.js b/src/node.js index 9484edbf..d2d5f96d 100644 --- a/src/node.js +++ b/src/node.js @@ -172,8 +172,8 @@ }; var origSetWidth = fabric.StaticCanvas.prototype.setWidth; - fabric.StaticCanvas.prototype.setWidth = function(width) { - origSetWidth.call(this, width); + fabric.StaticCanvas.prototype.setWidth = function(width, options) { + origSetWidth.call(this, width, options); this.nodeCanvas.width = width; return this; }; @@ -182,8 +182,8 @@ } var origSetHeight = fabric.StaticCanvas.prototype.setHeight; - fabric.StaticCanvas.prototype.setHeight = function(height) { - origSetHeight.call(this, height); + fabric.StaticCanvas.prototype.setHeight = function(height, options) { + origSetHeight.call(this, height, options); this.nodeCanvas.height = height; return this; }; diff --git a/src/static_canvas.class.js b/src/static_canvas.class.js index 2a554ae8..2a18ae82 100644 --- a/src/static_canvas.class.js +++ b/src/static_canvas.class.js @@ -468,36 +468,65 @@ /** * Sets width of this canvas instance - * @param {Number} width value to set width to + * @param {Number|String} width value to set width to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions * @return {fabric.Canvas} instance * @chainable true */ - setWidth: function (width) { - return this._setDimension('width', width); + setWidth: function (value, options) { + return this.setDimensions({ width: value }, options); }, /** * Sets height of this canvas instance - * @param {Number} height value to set height to + * @param {Number|String} height value to set height to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions * @return {fabric.Canvas} instance * @chainable true */ - setHeight: function (height) { - return this._setDimension('height', height); + setHeight: function (value, options) { + return this.setDimensions({ height: value }, options); }, /** - * Sets dimensions (width, height) of this canvas instance - * @param {Object} dimensions Object with width/height properties - * @param {Number} [dimensions.width] Width of canvas element - * @param {Number} [dimensions.height] Height of canvas element + * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) + * @param {Object} dimensions Object with width/height properties + * @param {Number|String} [dimensions.width] Width of canvas element + * @param {Number|String} [dimensions.height] Height of canvas element + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions * @return {fabric.Canvas} thisArg * @chainable */ - setDimensions: function(dimensions) { + setDimensions: function (dimensions, options) { + var cssValue; + + options = options || {}; + for (var prop in dimensions) { - this._setDimension(prop, dimensions[prop]); + cssValue = dimensions[prop]; + + if (!options.cssOnly) { + this._setBackstoreDimension(prop, dimensions[prop]); + cssValue += 'px'; + } + + if (!options.backstoreOnly) { + this._setCssDimension(prop, cssValue); + } } + + if (!options.cssOnly) { + this.renderAll(); + } + + this.calcOffset(); + return this; }, @@ -509,27 +538,40 @@ * @return {fabric.Canvas} instance * @chainable true */ - _setDimension: function (prop, value) { + _setBackstoreDimension: function (prop, value) { this.lowerCanvasEl[prop] = value; - this.lowerCanvasEl.style[prop] = value + 'px'; if (this.upperCanvasEl) { this.upperCanvasEl[prop] = value; - this.upperCanvasEl.style[prop] = value + 'px'; } if (this.cacheCanvasEl) { this.cacheCanvasEl[prop] = value; } - if (this.wrapperEl) { - this.wrapperEl.style[prop] = value + 'px'; - } - this[prop] = value; - this.calcOffset(); - this.renderAll(); + return this; + }, + + /** + * Helper for setting css width/height + * @private + * @param {String} prop property (width|height) + * @param {String} value value to set property to + * @return {fabric.Canvas} instance + * @chainable true + */ + _setCssDimension: function (prop, value) { + this.lowerCanvasEl.style[prop] = value; + + if (this.upperCanvasEl) { + this.upperCanvasEl.style[prop] = value; + } + + if (this.wrapperEl) { + this.wrapperEl.style[prop] = value; + } return this; }, diff --git a/test/unit/canvas.js b/test/unit/canvas.js index 0b8c4d74..4f7b4142 100644 --- a/test/unit/canvas.js +++ b/test/unit/canvas.js @@ -932,12 +932,12 @@ }); }); - test('getSetWidth', function() { + test('getSetWidth', function() { ok(typeof canvas.getWidth == 'function'); - equal(canvas.getWidth(), 600); equal(canvas.setWidth(444), canvas, 'should be chainable'); equal(canvas.getWidth(), 444); + equal(canvas.lowerCanvasEl.style.width, 444 + 'px'); }); test('getSetHeight', function() { @@ -945,6 +945,47 @@ equal(canvas.getHeight(), 600); equal(canvas.setHeight(765), canvas, 'should be chainable'); equal(canvas.getHeight(), 765); + equal(canvas.lowerCanvasEl.style.height, 765 + 'px'); + }); + + test('setWidth css only', function() { + canvas.setWidth(123); + canvas.setWidth('100%', { cssOnly: true }); + + equal(canvas.lowerCanvasEl.style.width, '100%', 'Should be as the css only value'); + equal(canvas.upperCanvasEl.style.width, '100%', 'Should be as the css only value'); + equal(canvas.wrapperEl.style.width, '100%', 'Should be as the css only value'); + equal(canvas.getWidth(), 123, 'Should be as the none css only value'); + }); + + test('setHeight css only', function() { + canvas.setHeight(123); + canvas.setHeight('100%', { cssOnly: true }); + + equal(canvas.lowerCanvasEl.style.height, '100%', 'Should be as the css only value'); + equal(canvas.upperCanvasEl.style.height, '100%', 'Should be as the css only value'); + equal(canvas.wrapperEl.style.height, '100%', 'Should be as the css only value'); + equal(canvas.getWidth(), 123, 'Should be as the none css only value'); + }); + + test('setWidth backstore only', function() { + canvas.setWidth(123); + canvas.setWidth(500, { backstoreOnly: true }); + + equal(canvas.lowerCanvasEl.style.width, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.upperCanvasEl.style.width, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.wrapperEl.style.width, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.getWidth(), 500, 'Should be as the backstore only value'); + }); + + test('setHeight backstore only', function() { + canvas.setHeight(123); + canvas.setHeight(500, { backstoreOnly: true }); + + equal(canvas.lowerCanvasEl.style.height, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.upperCanvasEl.style.height, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.wrapperEl.style.height, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.getHeight(), 500, 'Should be as the backstore only value'); }); test('containsPoint', function() { diff --git a/test/unit/canvas_static.js b/test/unit/canvas_static.js index 24bf80e9..bcc6241a 100644 --- a/test/unit/canvas_static.js +++ b/test/unit/canvas_static.js @@ -1024,6 +1024,7 @@ equal(canvas.getWidth(), 600); equal(canvas.setWidth(444), canvas, 'should be chainable'); equal(canvas.getWidth(), 444); + equal(canvas.lowerCanvasEl.style.width, 444 + 'px'); }); test('getSetHeight', function() { @@ -1031,6 +1032,39 @@ equal(canvas.getHeight(), 600); equal(canvas.setHeight(765), canvas, 'should be chainable'); equal(canvas.getHeight(), 765); + equal(canvas.lowerCanvasEl.style.height, 765 + 'px'); + }); + + test('setWidth css only', function() { + canvas.setWidth(123); + canvas.setWidth('100%', { cssOnly: true }); + + equal(canvas.lowerCanvasEl.style.width, '100%', 'Should be as the css only value'); + equal(canvas.getWidth(), 123, 'Should be as the none css only value'); + }); + + test('setHeight css only', function() { + canvas.setHeight(123); + canvas.setHeight('100%', { cssOnly: true }); + + equal(canvas.lowerCanvasEl.style.height, '100%', 'Should be as the css only value'); + equal(canvas.getWidth(), 123, 'Should be as the none css only value'); + }); + + test('setWidth backstore only', function() { + canvas.setWidth(123); + canvas.setWidth(500, { backstoreOnly: true }); + + equal(canvas.lowerCanvasEl.style.width, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.getWidth(), 500, 'Should be as the backstore only value'); + }); + + test('setHeight backstore only', function() { + canvas.setHeight(123); + canvas.setHeight(500, { backstoreOnly: true }); + + equal(canvas.lowerCanvasEl.style.height, 123 + 'px', 'Should be as none backstore only value + "px"'); + equal(canvas.getHeight(), 500, 'Should be as the backstore only value'); }); asyncTest('fxRemove', function() {