From ff79ab1aca088a32c434c1b596c2473d37b1325e Mon Sep 17 00:00:00 2001 From: asturur Date: Wed, 14 Oct 2015 08:48:03 +0200 Subject: [PATCH] first changes to group transform handling --- src/mixins/object_geometry.mixin.js | 38 +++++++++--- src/shapes/group.class.js | 89 ++++------------------------- src/util/misc.js | 8 ++- 3 files changed, 48 insertions(+), 87 deletions(-) diff --git a/src/mixins/object_geometry.mixin.js b/src/mixins/object_geometry.mixin.js index a2609690..86b9020a 100644 --- a/src/mixins/object_geometry.mixin.js +++ b/src/mixins/object_geometry.mixin.js @@ -9,7 +9,8 @@ ]; } - var degreesToRadians = fabric.util.degreesToRadians; + var degreesToRadians = fabric.util.degreesToRadians, + multiplyMatrices = fabric.util.multiplyTransformMatrices fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { @@ -346,12 +347,35 @@ return this; }, - _calcDimensionsTransformMatrix: function(skewX, skewY) { - var skewMatrixX = [1, 0, Math.tan(degreesToRadians(skewX)), 1, 0, 0], - skewMatrixY = [1, Math.tan(degreesToRadians(skewY)), 0, 1, 0, 0], - scaleMatrix = [this.scaleX, 0, 0, this.scaleY, 0, 0], - m = fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true); - return fabric.util.multiplyTransformMatrices(m, skewMatrixY, true); + _calcRotateMatrix: function() { + if (this.angle) { + var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta); + return [cos, sin, -sin, cos, 0, 0]; + } + return [1, 0, 0, 1, 0, 0]; + }, + + calcTransformMatrix: function() { + var center = this.getCenterPoint(), + translateMatrix = [1, 0, 0, 1, center.x, center.y], + rotateMatrix = this._calcRotateMatrix(), + dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), + matrix = this.group ? this.group.calcTransformMatrix() : [1, 0, 0, 1, 0, 0]; + matrix = multiplyMatrices(matrix, translateMatrix); + matrix = multiplyMatrices(matrix, rotateMatrix); + matrix = multiplyMatrices(matrix, dimensionMatrix); + console.log(matrix); + return matrix; + }, + + _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { + var skewMatrixX = [1, 0, Math.tan(degreesToRadians(skewX)), 1], + skewMatrixY = [1, Math.tan(degreesToRadians(skewY)), 0, 1], + scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1), + scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1), + scaleMatrix = [scaleX, 0, 0, scaleY], + m = multiplyMatrices(scaleMatrix, skewMatrixX, true); + return multiplyMatrices(m, skewMatrixY, true); } }); })(); diff --git a/src/shapes/group.class.js b/src/shapes/group.class.js index 512782b9..3e35fb22 100644 --- a/src/shapes/group.class.js +++ b/src/shapes/group.class.js @@ -174,7 +174,7 @@ * @chainable */ removeWithUpdate: function(object) { - this._moveFlippedObject(object); + //this._moveFlippedObject(object); this._restoreObjectsState(); // since _restoreObjectsState set objects inactive @@ -325,59 +325,11 @@ * @return {fabric.Object} transformedObject */ realizeTransform: function(object) { - this._moveFlippedObject(object); + //this._moveFlippedObject(object); this._setObjectPosition(object); return object; }, - /** - * Moves a flipped object to the position where it's displayed - * @private - * @param {fabric.Object} object - * @return {fabric.Group} thisArg - */ - _moveFlippedObject: function(object) { - var oldOriginX = object.get('originX'), - oldOriginY = object.get('originY'), - center = object.getCenterPoint(); - - object.set({ - originX: 'center', - originY: 'center', - left: center.x, - top: center.y - }); - - this._toggleFlipping(object); - - var newOrigin = object.getPointByOrigin(oldOriginX, oldOriginY); - - object.set({ - originX: oldOriginX, - originY: oldOriginY, - left: newOrigin.x, - top: newOrigin.y - }); - - return this; - }, - - /** - * @private - */ - _toggleFlipping: function(object) { - if (this.flipX) { - object.toggle('flipX'); - object.set('left', -object.get('left')); - object.setAngle(-object.getAngle()); - } - if (this.flipY) { - object.toggle('flipY'); - object.set('top', -object.get('top')); - object.setAngle(-object.getAngle()); - } - }, - /** * Restores original state of a specified object in group * @private @@ -385,13 +337,12 @@ * @return {fabric.Group} thisArg */ _restoreObjectState: function(object) { - this._setObjectPosition(object); + this._setObjectPosition(object); object.setCoords(); object.hasControls = object.__origHasControls; delete object.__origHasControls; object.set('active', false); - object.setCoords(); delete object.group; return this; @@ -401,30 +352,14 @@ * @private */ _setObjectPosition: function(object) { - var center = this.getCenterPoint(), - rotated = this._getRotatedLeftTop(object); - - object.set({ - angle: object.getAngle() + this.getAngle(), - left: center.x + rotated.left, - top: center.y + rotated.top, - scaleX: object.get('scaleX') * this.get('scaleX'), - scaleY: object.get('scaleY') * this.get('scaleY') - }); - }, - - /** - * @private - */ - _getRotatedLeftTop: function(object) { - var groupAngle = this.getAngle() * (Math.PI / 180); - return { - left: (-Math.sin(groupAngle) * object.getTop() * this.get('scaleY') + - Math.cos(groupAngle) * object.getLeft() * this.get('scaleX')), - - top: (Math.cos(groupAngle) * object.getTop() * this.get('scaleY') + - Math.sin(groupAngle) * object.getLeft() * this.get('scaleX')) - }; + var matrix = object.calcTransformMatrix(), + options = fabric.util.qrDecompose(matrix), + center = new fabric.Point(options.translateX, options.translateY); + console.log(matrix, options); + delete options.translateX; + delete options.translateY; + object.set(options); + object.setPositionByOrigin(center, 'center', 'center'); }, /** @@ -433,7 +368,7 @@ * @chainable */ destroy: function() { - this._objects.forEach(this._moveFlippedObject, this); + //this._objects.forEach(this._moveFlippedObject, this); return this._restoreObjectsState(); }, diff --git a/src/util/misc.js b/src/util/misc.js index 50017f18..bf6ba0fc 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -505,8 +505,8 @@ * @return {Object} Components of transform */ qrDecompose: function(a) { - var angle = atan(a[0] / a[1]), - denom = pow(a[0]) + pow(a[1]), + var angle = atan(a[1] / a[0]), + denom = pow(a[0], 2) + pow(a[1], 2), scaleX = sqrt(denom), scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX, skewX = atan((a[0] * a[2] + a[1] * a [3]) / denom); @@ -515,7 +515,9 @@ scaleX: scaleX, scaleY: scaleY, skewX: skewX / PiBy180, - skewY: 0 + skewY: 0, + translateX: a[4], + translateY: a[5] }; },