diff options
author | wout <wout@impinc.co.uk> | 2014-08-24 16:15:56 +0200 |
---|---|---|
committer | wout <wout@impinc.co.uk> | 2014-08-24 16:15:56 +0200 |
commit | a5837d5bf9d980605358f3bfc63a65acd87c3444 (patch) | |
tree | 81f1af10505f36ad8618ddfb247ab820f4c18bd8 /src | |
parent | 35c46452577fc550793d13075c3010619ac1c96d (diff) | |
download | svg.js-a5837d5bf9d980605358f3bfc63a65acd87c3444.tar.gz svg.js-a5837d5bf9d980605358f3bfc63a65acd87c3444.zip |
Implemented absolute and relative matrix transformations
Diffstat (limited to 'src')
-rwxr-xr-x | src/boxes.js | 2 | ||||
-rwxr-xr-x | src/group.js | 4 | ||||
-rw-r--r-- | src/matrix.js | 6 | ||||
-rw-r--r-- | src/transform.js | 143 |
4 files changed, 94 insertions, 61 deletions
diff --git a/src/boxes.js b/src/boxes.js index a2da745..96c4246 100755 --- a/src/boxes.js +++ b/src/boxes.js @@ -95,8 +95,6 @@ SVG.RBox = SVG.invent({ } // Recalculate viewbox distortion - // this.x /= zoom - // this.y /= zoom this.width = box.width /= zoom this.height = box.height /= zoom diff --git a/src/group.js b/src/group.js index 326f50b..66a8437 100755 --- a/src/group.js +++ b/src/group.js @@ -9,11 +9,11 @@ SVG.G = SVG.invent({ , extend: { // Move over x-axis x: function(x) { - return x == null ? this.transform('x') : this.transform({ x: -this.x() + x }) + return x == null ? this.transform('x') : this.transform({ x: -this.x() + x }, true) } // Move over y-axis , y: function(y) { - return y == null ? this.transform('y') : this.transform({ y: -this.y() + y }) + return y == null ? this.transform('y') : this.transform({ y: -this.y() + y }, true) } // Move by center over x-axis , cx: function(x) { diff --git a/src/matrix.js b/src/matrix.js index e9c8900..7ee2874 100644 --- a/src/matrix.js +++ b/src/matrix.js @@ -141,7 +141,11 @@ SVG.Matrix = SVG.invent({ } // Convert matrix to string , toString: function() { - return 'matrix(' + [this.a, this.b, this.c, this.d, this.e, this.f].join() + ')' + return 'matrix(' + this.toArray().join() + ')' + } + // Convert matrix to array + , toArray: function() { + return [this.a, this.b, this.c, this.d, this.e, this.f] } } diff --git a/src/transform.js b/src/transform.js index ded67fb..da2bf37 100644 --- a/src/transform.js +++ b/src/transform.js @@ -1,68 +1,99 @@ SVG.extend(SVG.Element, SVG.FX, { - // Add transformations - transform: function(o) { - // get target in case of the fx module, otherwise reference this - var target = this.target || this + // Add transformations + transform: function(o, relative) { + // get target in case of the fx module, otherwise reference this + var target = this.target || this - // full getter - if (o == null) - return target.ctm().extract() + // full getter + if (o == null) + return target.ctm().extract() - // singular getter - else if (typeof o === 'string') - return target.ctm().extract()[o] - - // get current matrix - var matrix = new SVG.Matrix(o.add === true ? target : {}) - - // act on matrix - if (o.a != null) - matrix = matrix.multiply(new SVG.Matrix(o)) - - // act on rotate - else if (o.rotation) - matrix = matrix.rotate( - o.rotation - , o.cx == null ? target.bbox().cx : o.cx - , o.cy == null ? target.bbox().cy : o.cy - ) - - // act on scale - else if (o.scale != null || o.scaleX != null || o.scaleY != null) - matrix = matrix.scale( - o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 - , o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 - , o.cx == null ? target.bbox().x : o.cx - , o.cy == null ? target.bbox().y : o.cy - ) + // singular getter + else if (typeof o === 'string') + return target.ctm().extract()[o] - // act on skew - else if (o.skewX || o.skewY) - matrix = matrix.skew( - o.skewX - , o.skewY - , o.cx == null ? target.bbox().cx : o.cx - , o.cy == null ? target.bbox().cy : o.cy - ) + // get current matrix + var matrix = new SVG.Matrix(target) - // act on flip - else if (o.flip) - matrix = matrix.flip( - o.flip - , o.offset == null ? target.bbox()['c' + o.flip] : o.offset - ) + // ensure relative flag + relative = !!relative || !!o.relative + + // act on matrix + if (o.a != null) { + matrix = relative ? + // relative + matrix.multiply(new SVG.Matrix(o)) : + // absolute + new SVG.Matrix(o) + + // act on rotate + } else if (o.rotation != null) { + o.cx = o.cx == null ? target.bbox().cx : o.cx + o.cy = o.cy == null ? target.bbox().cy : o.cy - // act on translate - else if (o.x || o.y) - matrix = matrix.translate(o.x, o.y) + matrix = relative ? + // relative + target.attr('transform', matrix + ' rotate(' + [o.rotation, o.cx, o.cy].join() + ')').ctm() : + // absolute + matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy) + + // act on scale + } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { + o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 + o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 + o.cx = o.cx == null ? target.bbox().cx : o.cx + o.cy = o.cy == null ? target.bbox().cy : o.cy - return this.attr('transform', matrix) - } + if (!relative) { + // absolute; multiply inversed values + var e = matrix.extract() + o.scaleX = o.scaleX * 1 / e.scaleX + o.scaleY = o.scaleY * 1 / e.scaleY + } + + matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy) + + // act on skew + } else if (o.skewX != null || o.skewY != null) { + o.skewX = o.skewX != null ? o.skewX : 0 + o.skewY = o.skewY != null ? o.skewY : 0 + o.cx = o.cx == null ? target.bbox().cx : o.cx + o.cy = o.cy == null ? target.bbox().cy : o.cy + + if (!relative) { + // absolute; reset skew values + var e = matrix.extract() + matrix = matrix.multiply(new SVG.Matrix().skew(e.skewX, e.skewY, o.cx, o.cy).inverse()) + } + + matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy) + + // act on flip + } else if (o.flip) { + matrix = matrix.flip( + o.flip + , o.offset == null ? target.bbox()['c' + o.flip] : o.offset + ) + + // act on translate + } else if (o.x != null || o.y != null) { + if (relative) { + // relative + matrix = matrix.translate(o.x, o.y) + } else { + // absolute + if (o.x != null) matrix.e = o.x + if (o.y != null) matrix.f = o.y + } + } + + return this.attr('transform', matrix) + } }) SVG.extend(SVG.Element, { - // Reset all transformations + // Reset all transformations untransform: function() { - return this.attr('transform', null) - } + return this.attr('transform', null) + } })
\ No newline at end of file |