summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorwout <wout@impinc.co.uk>2014-08-24 16:15:56 +0200
committerwout <wout@impinc.co.uk>2014-08-24 16:15:56 +0200
commita5837d5bf9d980605358f3bfc63a65acd87c3444 (patch)
tree81f1af10505f36ad8618ddfb247ab820f4c18bd8 /src
parent35c46452577fc550793d13075c3010619ac1c96d (diff)
downloadsvg.js-a5837d5bf9d980605358f3bfc63a65acd87c3444.tar.gz
svg.js-a5837d5bf9d980605358f3bfc63a65acd87c3444.zip
Implemented absolute and relative matrix transformations
Diffstat (limited to 'src')
-rwxr-xr-xsrc/boxes.js2
-rwxr-xr-xsrc/group.js4
-rw-r--r--src/matrix.js6
-rw-r--r--src/transform.js143
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