From a1c41e7b37a6ce1ccb35f32ec8689a39895a019f Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 00:09:29 +0100 Subject: [PATCH 1/6] changed toDataUrl --- src/mixins/canvas_dataurl_exporter.mixin.js | 71 ++++++++++----------- src/util/misc.js | 2 +- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/mixins/canvas_dataurl_exporter.mixin.js b/src/mixins/canvas_dataurl_exporter.mixin.js index 294b011e323..3e351f0b62c 100644 --- a/src/mixins/canvas_dataurl_exporter.mixin.js +++ b/src/mixins/canvas_dataurl_exporter.mixin.js @@ -47,64 +47,59 @@ top: options.top || 0, width: options.width || 0, height: options.height || 0, - }; - return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); + }, + canvasEl = this.toCanvasElement(cropping, multiplier); + return this.__toDataURL(canvasEl, format, quality); }, /** - * @private + * Create a new HTMLCanvas element painted with the current canvas content. + * No need to resize the actual one or repaint it. + * Will transfer object ownership to a new canvas, paint it, and set everything back. + * This is an intermediary step used to get to a dataUrl but also it is usefull to + * create quick image copies of a canvas without passing for the dataUrl string + * @param {Object} [cropping] Cropping informations + * @param {Number} [cropping.left] Cropping left offset. + * @param {Number} [cropping.top] Cropping top offset. + * @param {Number} [cropping.width] Cropping width. + * @param {Number} [cropping.height] Cropping height. + * @param {Number} [multiplier] a zoom factor. */ - __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - - var origWidth = this.width, - origHeight = this.height, - scaledWidth = (cropping.width || this.width) * multiplier, + toCanvasElement: function(cropping, multiplier) { + var scaledWidth = (cropping.width || this.width) * multiplier, scaledHeight = (cropping.height || this.height) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, + originalVp = this.viewportTransform, + originalOffscreen = this.skipOffscreen, + originalCanvas = this.lowerCanvasEl, newVp = [newZoom, 0, 0, newZoom, translateX, translateY], - originalInteractive = this.interactive, - originalSkipOffScreen = this.skipOffscreen, - needsResize = origWidth !== scaledWidth || origHeight !== scaledHeight; - + canvasEl = fabric.util.createCanvasElement(); + canvasEl.width = scaledWidth; + canvasEl.height = scaledHeight; this.viewportTransform = newVp; - this.skipOffscreen = false; - // setting interactive to false avoid exporting controls - this.interactive = false; - if (needsResize) { - this.setDimensions({ width: scaledWidth, height: scaledHeight }, { backstoreOnly: true }); - } - // call a renderAll to force sync update. This will cancel the scheduled requestRenderAll - // from setDimensions - this.renderAll(); - var data = this.__toDataURL(format, quality, cropping); - this.interactive = originalInteractive; - this.skipOffscreen = originalSkipOffScreen; - this.viewportTransform = vp; - //setDimensions with no option object is taking care of: - //this.width, this.height, this.requestRenderAll() - if (needsResize) { - this.setDimensions({ width: origWidth, height: origHeight }, { backstoreOnly: true }); - } + this.lowerCanvasEl = canvasEl; + // will be renderAllExport(); this.renderAll(); - return data; + this.viewportTransform = originalVp; + this.skipOffscreen = originalOffscreen; + this.lowerCanvasEl = originalCanvas; + return canvasEl; }, /** + * since 2.5.0 does not need to be on canvas instance anymore. + * leave it here for context; * @private */ - __toDataURL: function(format, quality) { - - var canvasEl = this.contextContainer.canvas; - var data = supportQuality + __toDataURL: function(canvasEl, format, quality) { + return supportQuality ? canvasEl.toDataURL('image/' + format, quality) : canvasEl.toDataURL('image/' + format); - - return data; - }, + } }); })(); diff --git a/src/util/misc.js b/src/util/misc.js index 03902d586d5..6016b9df0eb 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -837,6 +837,6 @@ findScaleToCover: function(source, destination) { return Math.max(destination.width / source.width, destination.height / source.height); - } + }, }; })(typeof exports !== 'undefined' ? exports : this); From 7810c060da76ac63a307354e94e7f9e8e6f7ddad Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 00:15:16 +0100 Subject: [PATCH 2/6] ok not broken --- src/mixins/canvas_dataurl_exporter.mixin.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mixins/canvas_dataurl_exporter.mixin.js b/src/mixins/canvas_dataurl_exporter.mixin.js index 3e351f0b62c..c8155511d3b 100644 --- a/src/mixins/canvas_dataurl_exporter.mixin.js +++ b/src/mixins/canvas_dataurl_exporter.mixin.js @@ -73,20 +73,22 @@ vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, - originalVp = this.viewportTransform, + originalInteractive = this.interactive, originalOffscreen = this.skipOffscreen, - originalCanvas = this.lowerCanvasEl, + originalContext = this.contextContainer, newVp = [newZoom, 0, 0, newZoom, translateX, translateY], canvasEl = fabric.util.createCanvasElement(); canvasEl.width = scaledWidth; canvasEl.height = scaledHeight; + this.interactive = false; this.viewportTransform = newVp; - this.lowerCanvasEl = canvasEl; + this.contextContainer = canvasEl.getContext('2d'); // will be renderAllExport(); this.renderAll(); - this.viewportTransform = originalVp; + this.viewportTransform = vp; this.skipOffscreen = originalOffscreen; - this.lowerCanvasEl = originalCanvas; + this.contextContainer = originalContext; + this.interactive = originalInteractive; return canvasEl; }, From f50a7c23bee77cc3abe4eb23e63863484259d5e9 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 00:26:55 +0100 Subject: [PATCH 3/6] ok not broken --- src/util/misc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/misc.js b/src/util/misc.js index 6016b9df0eb..03902d586d5 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -837,6 +837,6 @@ findScaleToCover: function(source, destination) { return Math.max(destination.width / source.width, destination.height / source.height); - }, + } }; })(typeof exports !== 'undefined' ? exports : this); From 123dce7fbc7fced76bfcd4dfe37e957a02b73d51 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 00:36:13 +0100 Subject: [PATCH 4/6] fix --- src/mixins/canvas_dataurl_exporter.mixin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mixins/canvas_dataurl_exporter.mixin.js b/src/mixins/canvas_dataurl_exporter.mixin.js index c8155511d3b..c17dcd363d1 100644 --- a/src/mixins/canvas_dataurl_exporter.mixin.js +++ b/src/mixins/canvas_dataurl_exporter.mixin.js @@ -41,7 +41,7 @@ var format = options.format || 'png', quality = options.quality || 1, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? 1 : 1 / this.getRetinaScaling()), + multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1), cropping = { left: options.left || 0, top: options.top || 0, From 2587b4514f57cf11ceb5e2524d1e07a1e951706d Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 14:17:16 +0100 Subject: [PATCH 5/6] missed the offscreen --- src/mixins/canvas_dataurl_exporter.mixin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mixins/canvas_dataurl_exporter.mixin.js b/src/mixins/canvas_dataurl_exporter.mixin.js index c17dcd363d1..7609ff5b6ba 100644 --- a/src/mixins/canvas_dataurl_exporter.mixin.js +++ b/src/mixins/canvas_dataurl_exporter.mixin.js @@ -80,6 +80,7 @@ canvasEl = fabric.util.createCanvasElement(); canvasEl.width = scaledWidth; canvasEl.height = scaledHeight; + this.skipOffscreen = false; this.interactive = false; this.viewportTransform = newVp; this.contextContainer = canvasEl.getContext('2d'); From d616f375dc2649ea4d0383868191b42a53c56067 Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 30 Dec 2018 15:33:27 +0100 Subject: [PATCH 6/6] added nonsense testing --- src/mixins/canvas_dataurl_exporter.mixin.js | 18 +++--- test/unit/canvas_static.js | 62 ++++++++++++++++++--- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/mixins/canvas_dataurl_exporter.mixin.js b/src/mixins/canvas_dataurl_exporter.mixin.js index 7609ff5b6ba..477cf028a6a 100644 --- a/src/mixins/canvas_dataurl_exporter.mixin.js +++ b/src/mixins/canvas_dataurl_exporter.mixin.js @@ -42,13 +42,7 @@ var format = options.format || 'png', quality = options.quality || 1, multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1), - cropping = { - left: options.left || 0, - top: options.top || 0, - width: options.width || 0, - height: options.height || 0, - }, - canvasEl = this.toCanvasElement(cropping, multiplier); + canvasEl = this.toCanvasElement(multiplier, options); return this.__toDataURL(canvasEl, format, quality); }, @@ -58,21 +52,23 @@ * Will transfer object ownership to a new canvas, paint it, and set everything back. * This is an intermediary step used to get to a dataUrl but also it is usefull to * create quick image copies of a canvas without passing for the dataUrl string + * @param {Number} [multiplier] a zoom factor. * @param {Object} [cropping] Cropping informations * @param {Number} [cropping.left] Cropping left offset. * @param {Number} [cropping.top] Cropping top offset. * @param {Number} [cropping.width] Cropping width. * @param {Number} [cropping.height] Cropping height. - * @param {Number} [multiplier] a zoom factor. */ - toCanvasElement: function(cropping, multiplier) { + toCanvasElement: function(multiplier, cropping) { + multiplier = multiplier || 1; + cropping = cropping || { }; var scaledWidth = (cropping.width || this.width) * multiplier, scaledHeight = (cropping.height || this.height) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, - translateX = (vp[4] - cropping.left) * multiplier, - translateY = (vp[5] - cropping.top) * multiplier, + translateX = (vp[4] - (cropping.left || 0)) * multiplier, + translateY = (vp[5] - (cropping.top || 0)) * multiplier, originalInteractive = this.interactive, originalOffscreen = this.skipOffscreen, originalContext = this.contextContainer, diff --git a/test/unit/canvas_static.js b/test/unit/canvas_static.js index e0f271ea02a..0e589204354 100644 --- a/test/unit/canvas_static.js +++ b/test/unit/canvas_static.js @@ -3,10 +3,10 @@ // var emptyImageCanvasData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t+KAAAH7ElEQVR4nO3VMQ0AMAzAsPInvYHoMS2yEeTLHADge/M6AADYM3QACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIMHQACDB0AAgwdAAIuMjH4b7osLFBAAAAAElFTkSuQmCC"; var CANVAS_SVG = '\n\n' + - '\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; + '\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; var CANVAS_SVG_VIEWBOX = '\n\n' + - '\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; + '\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; var PATH_JSON = '{"version":"' + fabric.version + '","objects": [{"type": "path", "version":"' + fabric.version + '", "originX": "left", "originY": "top", "left": 268, "top": 266, "width": 51, "height": 49,' + ' "fill": "rgb(0,0,0)", "stroke": null, "strokeWidth": 1, "scaleX": 1, "scaleY": 1, ' + @@ -143,8 +143,8 @@ // force creation of static canvas // TODO: fix this - var canvas = this.canvas = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 600, height: 600}); - var canvas2 = this.canvas2 = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 600, height: 600}); + var canvas = this.canvas = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 200, height: 200}); + var canvas2 = this.canvas2 = new fabric.StaticCanvas(null, {enableRetinaScaling: false, width: 200, height: 200}); var lowerCanvasEl = canvas.lowerCanvasEl; @@ -158,6 +158,8 @@ beforeEach: function() { fabric.Object.__uid = 0; canvas.clear(); + canvas.setDimensions({ width: 200, heigth: 200 }); + canvas2.setDimensions({ width: 200, heigth: 200 }); canvas.backgroundColor = fabric.StaticCanvas.prototype.backgroundColor; canvas.backgroundImage = fabric.StaticCanvas.prototype.backgroundImage; canvas.overlayColor = fabric.StaticCanvas.prototype.overlayColor; @@ -454,6 +456,30 @@ assert.equal(canvas, canvas.renderAll()); }); + // QUnit.test('setDimensions', function(assert) { + // assert.ok(typeof canvas.setDimensions === 'function');; + // canvas.setDimensions({ width: 4, height: 5 }); + // assert.equal(canvas.getWidth(), 4); + // assert.equal(canvas.getHeight(), 5); + // assert.equal(canvas.lowerCanvasEl.style.width, '5px'); + // assert.equal(canvas.lowerCanvasEl.style.height, '4px'); + // }); + + QUnit.test('toCanvasElement', function(assert) { + assert.ok(typeof canvas.toCanvasElement === 'function');; + var canvasEl = canvas.toCanvasElement(); + assert.equal(canvasEl.width, canvas.getWidth(), 'get a canvas of same width'); + assert.equal(canvasEl.height, canvas.getHeight(), 'get a canvas of same height'); + }); + + QUnit.test('toCanvasElement with multiplier', function(assert) { + assert.ok(typeof canvas.toCanvasElement === 'function'); + var multiplier = 2; + var canvasEl = canvas.toCanvasElement(multiplier); + assert.equal(canvasEl.width, canvas.getWidth() * multiplier, 'get a canvas of multiplied width'); + assert.equal(canvasEl.height, canvas.getHeight() * multiplier, 'get a canvas of multiplied height'); + }); + QUnit.test('toDataURL', function(assert) { assert.ok(typeof canvas.toDataURL === 'function'); if (!fabric.Canvas.supports('toDataURL')) { @@ -885,12 +911,12 @@ canvas.renderOnAddRemove = false; canvas.backgroundImage = imageBG; canvas.overlayImage = imageOL; - var expectedSVG = '\n\n\nCreated with Fabric.js ' + fabric.version + '\n\n\n\n\t\n\n\n\t\n\n'; + var expectedSVG = '\n\n\nCreated with Fabric.js ' + fabric.version + '\n\n\n\n\t\n\n\n\t\n\n'; var svg1 = canvas.toSVG(); assert.equal(svg1, expectedSVG, 'svg with bg and overlay do not match'); imageBG.excludeFromExport = true; imageOL.excludeFromExport = true; - var expectedSVG2 = '\n\n\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; + var expectedSVG2 = '\n\n\nCreated with Fabric.js ' + fabric.version + '\n\n\n'; var svg2 = canvas.toSVG(); assert.equal(svg2, expectedSVG2, 'svg without bg and overlay do not match'); canvas.backgroundImage = null; @@ -1470,7 +1496,7 @@ QUnit.test('getSetWidth', function(assert) { assert.ok(typeof canvas.getWidth === 'function'); - assert.equal(canvas.getWidth(), 600); + assert.equal(canvas.getWidth(), 200); assert.equal(canvas.setWidth(444), canvas, 'should be chainable'); assert.equal(canvas.getWidth(), 444); assert.equal(canvas.lowerCanvasEl.style.width, 444 + 'px'); @@ -1478,7 +1504,7 @@ QUnit.test('getSetHeight', function(assert) { assert.ok(typeof canvas.getHeight === 'function'); - assert.equal(canvas.getHeight(), 600); + assert.equal(canvas.getHeight(), 200); assert.equal(canvas.setHeight(765), canvas, 'should be chainable'); assert.equal(canvas.getHeight(), 765); assert.equal(canvas.lowerCanvasEl.style.height, 765 + 'px'); @@ -1497,7 +1523,16 @@ canvas.setHeight('100%', { cssOnly: true }); assert.equal(canvas.lowerCanvasEl.style.height, '100%', 'Should be as the css only value'); - assert.equal(canvas.getWidth(), 123, 'Should be as the none css only value'); + assert.equal(canvas.getHeight(), 123, 'Should be as the none css only value'); + }); + + QUnit.test('setDimensions css only', function(assert) { + canvas.setDimensions({ width: 200, height: 200 }); + canvas.setDimensions({ width: '250px', height: '350px' }, { cssOnly: true }); + assert.equal(canvas.lowerCanvasEl.style.width, '250px', 'Should be as none backstore only value + "px"'); + assert.equal(canvas.lowerCanvasEl.style.height, '350px', 'Should be as none backstore only value + "px"'); + assert.equal(canvas.getWidth(), 200, 'Should be as the backstore only value'); + assert.equal(canvas.getHeight(), 200, 'Should be as the backstore only value'); }); QUnit.test('setWidth backstore only', function(assert) { @@ -1516,6 +1551,15 @@ assert.equal(canvas.getHeight(), 500, 'Should be as the backstore only value'); }); + QUnit.test('setDimensions backstore only', function(assert) { + canvas.setDimensions({ width: 200, height: 200 }); + canvas.setDimensions({ width: 250, height: 350 }, { backstoreOnly: true }); + assert.equal(canvas.lowerCanvasEl.style.width, 200 + 'px', 'Should be as none backstore only value + "px"'); + assert.equal(canvas.lowerCanvasEl.style.height, 200 + 'px', 'Should be as none backstore only value + "px"'); + assert.equal(canvas.getWidth(), 250, 'Should be as the backstore only value'); + assert.equal(canvas.getHeight(), 350, 'Should be as the backstore only value'); + }); + QUnit.test('fxRemove', function(assert) { var done = assert.async(); assert.ok(typeof canvas.fxRemove === 'function');