diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a6b2b0047c..e1edd98d1cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [4.0.0-beta.5] + +fix(fabric.Object): getObjectScaling takes in account rotation of objects inside groups. [#6118](https://github.com/fabricjs/fabric.js/pull/6118) + ## [4.0.0-beta.4] fix(fabric.Group): will draw shadow will call parent method. [#6116](https://github.com/fabricjs/fabric.js/pull/6116) diff --git a/HEADER.js b/HEADER.js index 1b8d3495f55..09f1728cc69 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: '4.0.0-beta.4' }; +var fabric = fabric || { version: '4.0.0-beta.5' }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/package.json b/package.json index 4d80386ea1a..8bdea23fd97 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fabric", "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", "homepage": "http://fabricjs.com/", - "version": "4.0.0-beta.4", + "version": "4.0.0-beta.5", "author": "Juriy Zaytsev ", "contributors": [ { diff --git a/src/mixins/object_interactivity.mixin.js b/src/mixins/object_interactivity.mixin.js index 7335b2e4329..3ea0152ad1a 100644 --- a/src/mixins/object_interactivity.mixin.js +++ b/src/mixins/object_interactivity.mixin.js @@ -170,7 +170,7 @@ drawBorders: function(ctx, styleOverride) { styleOverride = styleOverride || {}; var wh = this._calculateCurrentDimensions(), - strokeWidth = 1 / this.borderScaleFactor, + strokeWidth = this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth, hasControls = typeof styleOverride.hasControls !== 'undefined' ? @@ -223,17 +223,19 @@ */ drawBordersInGroup: function(ctx, options, styleOverride) { styleOverride = styleOverride || {}; - var p = { x: options.width, y: options.height }, + var p = { x: this.width, y: this.height }, matrix = fabric.util.composeMatrix({ scaleX: options.scaleX, scaleY: options.scaleY, skewX: options.skewX }), wh = fabric.util.transformPoint(p, matrix), - strokeWidth = 1 / this.borderScaleFactor, - width = wh.x + strokeWidth / (this.strokeUniform ? options.scaleX : 1), - height = wh.y + strokeWidth / (this.strokeUniform ? options.scaleY : 1); - + strokeWidth = this.strokeWidth, + borderScaleFactor = this.borderScaleFactor, + width = + wh.x + strokeWidth * (this.strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor, + height = + wh.y + strokeWidth * (this.strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor; ctx.save(); this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); ctx.strokeStyle = styleOverride.borderColor || this.borderColor; diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index 340f5ea856f..b2ebb427cc5 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -372,6 +372,9 @@ /** * Scale factor of object's controlling borders + * bigger number will make a thicker border + * border is 1, so this is basically a border tickness + * since there is no way to change the border itself. * @type Number * @default */ @@ -855,6 +858,8 @@ strokeLineCap: this.strokeLineCap, strokeDashOffset: this.strokeDashOffset, strokeLineJoin: this.strokeLineJoin, + // TODO: add this before release + // strokeUniform: this.strokeUniform, strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), @@ -937,13 +942,8 @@ * @return {Object} object with scaleX and scaleY properties */ getObjectScaling: function() { - var scaleX = this.scaleX, scaleY = this.scaleY; - if (this.group) { - var scaling = this.group.getObjectScaling(); - scaleX *= scaling.scaleX; - scaleY *= scaling.scaleY; - } - return { scaleX: scaleX, scaleY: scaleY }; + var options = fabric.util.qrDecompose(this.calcTransformMatrix()); + return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) }; }, /** @@ -1530,14 +1530,12 @@ } ctx.save(); - if (this.strokeUniform) { - var scaleX = this.scaleX; - var scaleY = this.scaleY; - if (this.group) { - scaleX *= this.group.scaleX; - scaleY *= this.group.scaleY; - } - ctx.scale(1 / scaleX, 1 / scaleY); + if (this.strokeUniform && this.group) { + var scaling = this.getObjectScaling(); + ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY); + } + else if (this.strokeUniform) { + ctx.scale(1 / this.scaleX, 1 / this.scaleY); } this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke); if (this.stroke.toLive && this.stroke.gradientUnits === 'percentage') { diff --git a/test/unit/image.js b/test/unit/image.js index 088112982ae..fa0a89382c8 100644 --- a/test/unit/image.js +++ b/test/unit/image.js @@ -774,8 +774,8 @@ assert.equal(image._element, image._filteredEl, 'after filtering elements are the same'); image.applyResizeFilters(); assert.notEqual(image._element, image._filteredEl, 'after resizing the 2 elements differ'); - assert.equal(image._lastScaleX, image.scaleX, 'after resizing we know how much we scaled'); - assert.equal(image._lastScaleY, image.scaleY, 'after resizing we know how much we scaled'); + assert.equal(image._lastScaleX.toFixed(2), image.scaleX, 'after resizing we know how much we scaled'); + assert.equal(image._lastScaleY.toFixed(2), image.scaleY, 'after resizing we know how much we scaled'); image.applyFilters(); assert.equal(image._element, image._filteredEl, 'after filters again the elements changed'); assert.equal(image._lastScaleX, 1, 'lastScale X is reset'); diff --git a/test/unit/object.js b/test/unit/object.js index e65d902b0db..d515c4612df 100644 --- a/test/unit/object.js +++ b/test/unit/object.js @@ -1023,6 +1023,21 @@ }); }); + QUnit.test('getObjectScaling in group with object rotated', function(assert) { + var object = new fabric.Object({ scaleX: 3, scaleY: 2, angle: 45 }); + var group = new fabric.Group(); + group.scaleX = 2; + group.scaleY = 3; + object.group = group; + var objectScale = object.getObjectScaling(); + objectScale.scaleX = objectScale.scaleX.toFixed(3); + objectScale.scaleY = objectScale.scaleY.toFixed(3); + assert.deepEqual(objectScale, { + scaleX: '7.649', + scaleY: '4.707', + }); + }); + QUnit.test('dirty flag on set property', function(assert) { var object = new fabric.Object({ scaleX: 3, scaleY: 2}); object.cacheProperties = ['propA', 'propB'];