summaryrefslogtreecommitdiffstats
path: root/src/transform.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/transform.js')
-rw-r--r--src/transform.js246
1 files changed, 216 insertions, 30 deletions
diff --git a/src/transform.js b/src/transform.js
index 0e7a5a0..e6ad9ae 100644
--- a/src/transform.js
+++ b/src/transform.js
@@ -1,8 +1,8 @@
-SVG.extend(SVG.Element, SVG.FX, {
+SVG.extend(SVG.Element, {
// Add transformations
transform: function(o, relative) {
// get target in case of the fx module, otherwise reference this
- var target = this.target || this
+ var target = this
, matrix
// act as a getter
@@ -10,20 +10,11 @@ SVG.extend(SVG.Element, SVG.FX, {
// get current matrix
matrix = new SVG.Matrix(target).extract()
- // add parametric rotation
- if (typeof this.param === 'object') {
- matrix.rotation = this.param.rotation
- matrix.cx = this.param.cx
- matrix.cy = this.param.cy
- }
-
return typeof o === 'string' ? matrix[o] : matrix
}
// get current matrix
- matrix = this instanceof SVG.FX && this.attrs.transform ?
- this.attrs.transform :
- new SVG.Matrix(target)
+ matrix = new SVG.Matrix(target)
// ensure relative flag
relative = !!relative || !!o.relative
@@ -41,24 +32,12 @@ SVG.extend(SVG.Element, SVG.FX, {
// ensure centre point
ensureCentre(o, target)
- // relativize rotation value
- if (relative) {
- o.rotation += this.param && this.param.rotation != null ?
- this.param.rotation :
- matrix.extract().rotation
- }
-
- // store parametric values
- this.param = o
-
// apply transformation
- if (this instanceof SVG.Element) {
- matrix = relative ?
- // relative
- matrix.rotate(o.rotation, o.cx, o.cy) :
- // absolute
- matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
- }
+ matrix = relative ?
+ // relative
+ matrix.rotate(o.rotation, o.cx, o.cy) :
+ // 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) {
@@ -114,7 +93,84 @@ SVG.extend(SVG.Element, SVG.FX, {
}
}
- return this.attr(this instanceof SVG.Pattern ? 'patternTransform' : this instanceof SVG.Gradient ? 'gradientTransform' : 'transform', matrix)
+ return this.attr('transform', matrix)
+ }
+})
+
+SVG.extend(SVG.FX, {
+ transform: function(o, relative) {
+ // get target in case of the fx module, otherwise reference this
+ var target = this.target()
+ , matrix
+
+ // act as a getter
+ if (typeof o !== 'object') {
+ // get current matrix
+ matrix = new SVG.Matrix(target).extract()
+
+ return typeof o === 'string' ? matrix[o] : matrix
+ }
+
+ // ensure relative flag
+ relative = !!relative || !!o.relative
+
+ // act on matrix
+ if (o.a != null) {
+ matrix = new SVG.Matrix(o)
+
+ // act on rotation
+ } else if (o.rotation != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // apply transformation
+ matrix = new SVG.Rotate(o.rotation, o.cx, o.cy)
+
+ // act on scale
+ } else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure scale values on both axes
+ 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
+
+ matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
+
+ // act on skew
+ } else if (o.skewX != null || o.skewY != null) {
+ // ensure centre point
+ ensureCentre(o, target)
+
+ // ensure skew values on both axes
+ o.skewX = o.skewX != null ? o.skewX : 0
+ o.skewY = o.skewY != null ? o.skewY : 0
+
+ matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
+
+ // act on flip
+ } else if (o.flip) {
+ matrix = new SVG.Matrix().morph(new SVG.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) {
+ matrix = new SVG.Translate(o.x, o.y)
+ }
+
+ if(!matrix) return this
+
+ matrix.relative = relative
+
+ var situation = this.situations.length ? this.situations[this.situations.length-1] : this.current
+
+ situation.transforms.push(matrix)
+
+ setTimeout(function(){this.start()}.bind(this), 0)
+
+ return this
}
})
@@ -161,3 +217,133 @@ SVG.extend(SVG.Element, {
}
})
+
+SVG.Transformation = SVG.invent({
+
+ create: function(source, inversed){
+
+ if(arguments.length > 1 && typeof inversed != 'boolean'){
+ return this.create([].slice.call(arguments))
+ }
+
+ if(typeof source == 'object'){
+ for(var i = 0, len = this.arguments.length; i < len; ++i){
+ this[this.arguments[i]] = source[this.arguments[i]]
+ }
+ }
+
+ if(Array.isArray(source)){
+ for(var i = 0, len = this.arguments.length; i < len; ++i){
+ this[this.arguments[i]] = source[i]
+ }
+ }
+
+ this.inversed = false
+
+ if(inversed === true){
+ this.inversed = true
+ }
+
+ }
+
+, extend: {
+
+ at: function(pos){
+
+ var params = []
+
+ for(var i = 0, len = this.arguments.length; i < len; ++i){
+ params.push(this[this.arguments[i]])
+ }
+
+ var m = this._undo || new SVG.Matrix()
+
+ m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos)
+
+ return this.inversed ? m.inverse() : m
+
+ }
+
+ , undo: function(o){
+ this._undo = new SVG[capitalize(this.method)](o, true).at(1)
+ return this
+ }
+
+ }
+
+})
+
+SVG.Translate = SVG.invent({
+
+ parent: SVG.Matrix
+, inherit: SVG.Transformation
+
+, create: function(source, inversed){
+ if(typeof source == 'object') this.constructor.call(this, source, inversed)
+ else this.constructor.call(this, [].slice.call(arguments))
+ }
+
+, extend: {
+ arguments: ['transformedX', 'transformedY']
+ , method: 'translate'
+ }
+
+})
+
+SVG.Rotate = SVG.invent({
+
+ parent: SVG.Matrix
+, inherit: SVG.Transformation
+
+, create: function(source, inversed){
+ if(typeof source == 'object') this.constructor.call(this, source, inversed)
+ else this.constructor.call(this, [].slice.call(arguments))
+ }
+
+, extend: {
+ arguments: ['rotation', 'cx', 'cy']
+ , method: 'rotate'
+ , at: function(pos){
+ var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy)
+ return this.inversed ? m.inverse() : m
+ }
+ , undo: function(o){
+ this._undo = o
+ }
+ }
+
+})
+
+SVG.Scale = SVG.invent({
+
+ parent: SVG.Matrix
+, inherit: SVG.Transformation
+
+, create: function(source, inversed){
+ if(typeof source == 'object') this.constructor.call(this, source, inversed)
+ else this.constructor.call(this, [].slice.call(arguments))
+ }
+
+, extend: {
+ arguments: ['scaleX', 'scaleY', 'cx', 'cy']
+ , method: 'scale'
+ }
+
+})
+
+SVG.Skew = SVG.invent({
+
+ parent: SVG.Matrix
+, inherit: SVG.Transformation
+
+, create: function(source, inversed){
+ if(typeof source == 'object') this.constructor.call(this, source, inversed)
+ else this.constructor.call(this, [].slice.call(arguments))
+ }
+
+, extend: {
+ arguments: ['skewX', 'skewY', 'cx', 'cy']
+ , method: 'skew'
+ }
+
+})