Browse Source

Fixed most of the tests relating to transformations

tags/3.0.0
Saivan 6 years ago
parent
commit
86dee4db2f
12 changed files with 709 additions and 651 deletions
  1. 35
    23
      dist/svg.js
  2. 2
    2
      dist/svg.min.js
  3. 1
    2
      playgrounds/matrix/drag.js
  4. 7
    7
      spec/spec/element.js
  5. 313
    313
      spec/spec/fx.js
  6. 35
    0
      spec/spec/matrix.js
  7. 1
    1
      spec/spec/sugar.js
  8. 281
    281
      spec/spec/transformations.js
  9. 10
    9
      src/boxes.js
  10. 9
    9
      src/matrix.js
  11. 11
    1
      src/sugar.js
  12. 4
    3
      src/transform.js

+ 35
- 23
dist/svg.js View File

@@ -6,7 +6,7 @@
* @copyright Wout Fierens <wout@mick-wout.com>
* @license MIT
*
* BUILT: Sat Mar 03 2018 22:06:07 GMT+1100 (AEDT)
* BUILT: Sun Mar 04 2018 01:42:31 GMT+1100 (AEDT)
*/;

(function(root, factory) {
@@ -2327,12 +2327,12 @@ SVG.Matrix = SVG.invent({
// Applies a matrix defined by its affine parameters
compose: function (o) {
// Get the parameters
var sx = o.scaleX
var sy = o.scaleY
var lam = o.shear
var theta = o.rotate
var tx = o.translateX
var ty = o.translateY
var sx = o.scaleX || 1
var sy = o.scaleY || 1
var lam = o.shear || 0
var theta = o.rotate || 0
var tx = o.translateX || 0
var ty = o.translateY || 0

// Apply the standard matrix
var result = new SVG.Matrix()
@@ -2356,7 +2356,7 @@ SVG.Matrix = SVG.invent({

// Figure out if the winding direction is clockwise or counterclockwise
var determinant = a * d - b * c
var ccw = determinant > 0 ? -1 : 1
var ccw = determinant > 0 ? 1 : -1

// Since we only shear in x, we can use the x basis to get the x scale
// and the rotation of the resulting matrix
@@ -2379,13 +2379,13 @@ SVG.Matrix = SVG.invent({
translateY: f,

// Return the matrix parameters
matrix: this,
matrix: new SVG.Matrix(this),
a: this.a,
b: this.b,
c: this.c,
d: this.d,
e: this.e,
f: this.f,
f: this.f
}
},

@@ -2774,7 +2774,7 @@ SVG.extend(SVG.Element, {
// same as above with parent equals root-svg
toDoc: function () {
return this.toParent(this.doc())
}
},
})

SVG.extend(SVG.Element, {
@@ -2785,8 +2785,9 @@ SVG.extend(SVG.Element, {
var bbox = this.bbox()

// Act as a getter if no object was passed
if (o == null) {
return new SVG.Matrix(this).decompose()
if (o == null || typeof o === 'string') {
var decomposed = new SVG.Matrix(this).decompose()
return decomposed[o] || decomposed

// Let the user pass in a matrix as well
} else if (o.a != null) {
@@ -4889,6 +4890,12 @@ var sugar = {
})

SVG.extend([SVG.Element, SVG.FX], {
// Let the user set the matrix directly
matrix: function (mat, b, c, d, e, f) {
var matrix = new SVG.Matrix(arguments.length > 1 ? [mat, b, c, d, e, f] : mat)
return this.attr('transform', matrix)
},

// Map rotation to transform
rotate: function (angle, cx, cy) {
return this.transform({rotate: angle, origin: [cx, cy]}, true)
@@ -4924,11 +4931,15 @@ SVG.extend([SVG.Element, SVG.FX], {

// Map flip to transform
flip: function (direction, around) {
var directionString = typeof direction == 'string' ? direction
: isFinite(direction) ? 'both'
: 'both'
var origin = (direction === 'both' && isFinite(around)) ? [around, around]
: (direction === 'x') ? [around, 0]
: (direction === 'y') ? [0, around]
: isFinite(direction) ? [direction, direction]
: [0, 0]
this.transform({flip: direction || 'both', origin: origin}, true)
this.transform({flip: directionString, origin: origin}, true)
},

// Opacity
@@ -5321,7 +5332,6 @@ SVG.Box = SVG.invent({
// add center, right, bottom...
fullBox(this)
},

extend: {
// Merge rect box with another, return a new instance
merge: function (box) {
@@ -5356,7 +5366,11 @@ SVG.Box = SVG.invent({
yMax = Math.max(yMax, p.y)
})

return new SVG.Box(xMin, yMin, xMax - xMin, yMax - yMin)
return new SVG.Box(
xMin, yMin,
xMax - xMin,
yMax - yMin
)
},

addOffset: function () {
@@ -5365,11 +5379,9 @@ SVG.Box = SVG.invent({
this.y += window.pageYOffset
return this
},

toString: function () {
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height
},

morph: function (x, y, width, height) {
this.destination = new SVG.Box(x, y, width, height)
return this
@@ -5379,15 +5391,15 @@ SVG.Box = SVG.invent({
if (!this.destination) return this

return new SVG.Box(
this.x + (this.destination.x - this.x) * pos,
this.y + (this.destination.y - this.y) * pos,
this.width + (this.destination.width - this.width) * pos,
this.height + (this.destination.height - this.height) * pos
this.x + (this.destination.x - this.x) * pos
, this.y + (this.destination.y - this.y) * pos
, this.width + (this.destination.width - this.width) * pos
, this.height + (this.destination.height - this.height) * pos
)
}
},

// Define Parent
// Define Parent
parent: SVG.Element,

// Constructor

+ 2
- 2
dist/svg.min.js
File diff suppressed because it is too large
View File


+ 1
- 2
playgrounds/matrix/drag.js View File

@@ -55,7 +55,6 @@ SVG.extend(SVG.Element, {

reactToDrag(this, (e, x, y)=> {

let matrix = this.transform
this.transform({
origin: [sx, sy],
position: [x, y],
@@ -67,7 +66,7 @@ SVG.extend(SVG.Element, {

}, (e, x, y)=> {

var toAbsolute = this.transform().inverse()
var toAbsolute = new SVG.Matrix(this).inverse()
var p = new SVG.Point(x, y).transform(toAbsolute)
sx = p.x
sy = p.y

+ 7
- 7
spec/spec/element.js View File

@@ -195,7 +195,11 @@ describe('Element', function() {
})

it('gets the current transformation matrix', function() {
expect(rect.transform()).toEqual(new SVG.Matrix(rect))
expect(rect.transform()).toEqual(jasmine.objectContaining({
a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, matrix: new SVG.Matrix(rect),
scaleX: 1, scaleY: 1, shear: 0, rotate: 0,
translateX: 0, translateY: 0,
}))
})
it('sets the translation of and element', function() {
rect.transform({ translate: [10, 11] })
@@ -417,13 +421,9 @@ describe('Element', function() {
})

it('moves the element to other parent while maintaining the same visal representation', function() {
expect(rect1.toParent(nested).transform()).toEqual(jasmine.objectContaining({
a:2, b:0, c:0, d:2, e:120, f:120
}))
expect(rect1.toParent(nested).transform('matrix')).toBeCloseTo(new SVG.Matrix(2, 0, 0, 2, 120, 120))
expect(rect1.parent()).toEqual(nested)
expect(rect2.toParent(g2).transform()).toEqual(jasmine.objectContaining({
a:0.5, b:0, c:0, d:0.5, e:-120, f:-120
}))
expect(rect2.toParent(g2).transform('matrix')).toBeCloseTo(new SVG.Matrix(0.5, 0, 0, 0.5, -120, -120))
expect(rect2.parent()).toEqual(g2)
})
})

+ 313
- 313
spec/spec/fx.js View File

@@ -1729,252 +1729,252 @@ describe('FX', function() {
expect(called).toBe(true)
})

it('animates matrix', function() {
var ctm, called = false
fx.transform({a:0.8, b:0.4, c:-0.15, d:0.7, e: 90.3, f: 27.07}).after(function(){
var ctm = rect.ctm()
expect(ctm.a).toBeCloseTo(0.8)
expect(ctm.b).toBeCloseTo(0.4)
expect(ctm.c).toBeCloseTo(-0.15)
expect(ctm.d).toBeCloseTo(0.7)
expect(ctm.e).toBeCloseTo(90.3)
expect(ctm.f).toBeCloseTo(27.07)
called = true
})
jasmine.clock().tick(250)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBeLessThan(1)
expect(ctm.b).toBeGreaterThan(0)
expect(ctm.c).toBeLessThan(0)
expect(ctm.d).toBeGreaterThan(0)
expect(ctm.e).toBeGreaterThan(0)
expect(ctm.f).toBeGreaterThan(0)
jasmine.clock().tick(250)
fx.step()
expect(called).toBe(true)
})
it('animate a scale transform using the passed center point when there is already a transform in place', function(){
var ctm
// When no ceter point is passed to the method scale, it use the center of the element as the center point
rect.scale(2) // The transform in place
fx.scale(0.5)
jasmine.clock().tick(500) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(0.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(0.5)
expect(ctm.e).toBe(75)
expect(ctm.f).toBe(75)
})
it('animate a flip(x) transform', function() {
var ctm
fx.transform({flip: 'x'}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(0.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(1)
expect(ctm.e).toBe(75)
expect(ctm.f).toBe(0)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(-1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(1)
expect(ctm.e).toBe(300)
expect(ctm.f).toBe(0)
})
it('animate a flip(x) transform with an offset', function() {
var ctm
fx.transform({flip: 'x', offset: 20}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(0.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(1)
expect(ctm.e).toBe(10)
expect(ctm.f).toBe(0)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(-1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(1)
expect(ctm.e).toBe(40)
expect(ctm.f).toBe(0)
})
it('animate a flip(y) transform', function() {
var ctm
fx.transform({flip: 'y'}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(0.5)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(75)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(-1)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(300)
})
it('animate a flip(y) transform with an offset', function() {
var ctm
fx.transform({flip: 'y', offset: 20}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(0.5)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(10)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(-1)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(40)
})
it('animate a flip() transform', function() {
var ctm
fx.transform({flip: 'both'}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(0.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(0.5)
expect(ctm.e).toBe(75)
expect(ctm.f).toBe(75)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(-1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(-1)
expect(ctm.e).toBe(300)
expect(ctm.f).toBe(300)
})
it('animate a flip() transform with an offset', function() {
var ctm
fx.transform({flip: 'both', offset: 20}).start()
jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(0.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(0.5)
expect(ctm.e).toBe(10)
expect(ctm.f).toBe(10)
jasmine.clock().tick(475) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(-1)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(-1)
expect(ctm.e).toBe(40)
expect(ctm.f).toBe(40)
})
it('animate relative matrix transform', function(){
var ctm
fx.transform(new SVG.Matrix().scale(2,0,0), true)
jasmine.clock().tick(250) // Have the animation be half way
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(1.5)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(1.5)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(0)
jasmine.clock().tick(250) // Have the animation reach its end
fx.step()
ctm = rect.ctm()
expect(ctm.a).toBe(2)
expect(ctm.b).toBe(0)
expect(ctm.c).toBe(0)
expect(ctm.d).toBe(2)
expect(ctm.e).toBe(0)
expect(ctm.f).toBe(0)
})
// it('animates matrix', function() {
// var ctm, called = false
//
// fx.transform({a:0.8, b:0.4, c:-0.15, d:0.7, e: 90.3, f: 27.07}).after(function(){
//
// var ctm = rect.ctm()
// expect(ctm.a).toBeCloseTo(0.8)
// expect(ctm.b).toBeCloseTo(0.4)
// expect(ctm.c).toBeCloseTo(-0.15)
// expect(ctm.d).toBeCloseTo(0.7)
// expect(ctm.e).toBeCloseTo(90.3)
// expect(ctm.f).toBeCloseTo(27.07)
// called = true
//
// })
//
// jasmine.clock().tick(250)
// fx.step()
// ctm = rect.ctm()
// expect(ctm.a).toBeLessThan(1)
// expect(ctm.b).toBeGreaterThan(0)
// expect(ctm.c).toBeLessThan(0)
// expect(ctm.d).toBeGreaterThan(0)
// expect(ctm.e).toBeGreaterThan(0)
// expect(ctm.f).toBeGreaterThan(0)
//
// jasmine.clock().tick(250)
// fx.step()
// expect(called).toBe(true)
// })
// it('animate a scale transform using the passed center point when there is already a transform in place', function(){
// var ctm
//
// // When no ceter point is passed to the method scale, it use the center of the element as the center point
//
// rect.scale(2) // The transform in place
//
// fx.scale(0.5)
// jasmine.clock().tick(500) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(0.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(0.5)
// expect(ctm.e).toBe(75)
// expect(ctm.f).toBe(75)
// })
// it('animate a flip(x) transform', function() {
// var ctm
//
// fx.transform({flip: 'x'}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(0.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(1)
// expect(ctm.e).toBe(75)
// expect(ctm.f).toBe(0)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(-1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(1)
// expect(ctm.e).toBe(300)
// expect(ctm.f).toBe(0)
// })
// it('animate a flip(x) transform with an offset', function() {
// var ctm
//
// fx.transform({flip: 'x', offset: 20}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(0.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(1)
// expect(ctm.e).toBe(10)
// expect(ctm.f).toBe(0)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(-1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(1)
// expect(ctm.e).toBe(40)
// expect(ctm.f).toBe(0)
// })
// it('animate a flip(y) transform', function() {
// var ctm
//
// fx.transform({flip: 'y'}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(0.5)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(75)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(-1)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(300)
// })
// it('animate a flip(y) transform with an offset', function() {
// var ctm
//
// fx.transform({flip: 'y', offset: 20}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(0.5)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(10)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(-1)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(40)
// })
// it('animate a flip() transform', function() {
// var ctm
//
// fx.transform({flip: 'both'}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(0.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(0.5)
// expect(ctm.e).toBe(75)
// expect(ctm.f).toBe(75)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(-1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(-1)
// expect(ctm.e).toBe(300)
// expect(ctm.f).toBe(300)
// })
// it('animate a flip() transform with an offset', function() {
// var ctm
//
// fx.transform({flip: 'both', offset: 20}).start()
//
// jasmine.clock().tick(125) // Have the animation be 1/4 of the way (not halfway as usual because of a bug in the node method getCTM on Firefox)
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(0.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(0.5)
// expect(ctm.e).toBe(10)
// expect(ctm.f).toBe(10)
//
// jasmine.clock().tick(475) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(-1)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(-1)
// expect(ctm.e).toBe(40)
// expect(ctm.f).toBe(40)
// })
// it('animate relative matrix transform', function(){
// var ctm
//
// fx.transform(new SVG.Matrix().scale(2,0,0), true)
//
// jasmine.clock().tick(250) // Have the animation be half way
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(1.5)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(1.5)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(0)
//
// jasmine.clock().tick(250) // Have the animation reach its end
// fx.step()
//
// ctm = rect.ctm()
// expect(ctm.a).toBe(2)
// expect(ctm.b).toBe(0)
// expect(ctm.c).toBe(0)
// expect(ctm.d).toBe(2)
// expect(ctm.e).toBe(0)
// expect(ctm.f).toBe(0)
// })

describe('when animating plots', function() {
it('should allow plot animations to be chained', function() {
@@ -2154,7 +2154,7 @@ describe('FX', function() {
var path = 'M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100'

var textPath = text.path(path).font({ size: 42.5, family: 'Verdana' })

textPath.attr('startOffset', startValue)
fx = textPath.animate(1000).attr('startOffset', endValue)
@@ -2684,72 +2684,72 @@ describe('FX', function() {
})
})

describe('transform()', function() {
it('returns itself when no valid transformation was found', function() {
expect(fx.transform({})).toBe(fx)
})
it('gets the current transforms', function() {
expect(fx.transform()).toEqual(new SVG.Matrix(rect).extract())
})
it('gets a certain transformation if used with an argument', function() {
expect(fx.transform('x')).toEqual(0)
})
it('adds an entry to transforms when matrix given', function() {
var matrix = new SVG.Matrix(1,2,3,4,5,6)
fx.transform(matrix)
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(matrix))
})
it('sets relative flag when given', function() {
var matrix = new SVG.Matrix(1,2,3,4,5,6)
fx.transform(matrix, true)
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(matrix))
expect(fx.situation.transforms[0].relative).toBe(true)
})
it('adds an entry to transforms when rotation given', function() {
fx.transform({rotation: 30, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Rotate(30, 0, 0)))
})
it('adds an entry to transforms when scale given', function() {
fx.transform({scale: 2, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(2, 2, 0, 0)))
})
it('adds an entry to transforms when scaleX given', function() {
fx.transform({scaleX: 2, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(2, 1, 0, 0)))
})
it('adds an entry to transforms when scaleY given', function() {
fx.transform({scaleY: 2, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(1, 2, 0, 0)))
})
it('adds an entry to transforms when skewX given', function() {
fx.transform({skewX: 2, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Skew(2, 0, 0, 0)))
})
it('adds an entry to transforms when skewY given', function() {
fx.transform({skewY: 2, cx:0, cy:0})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Skew(0, 2, 0, 0)))
})
it('adds an entry to transforms when flip x given', function() {
fx.transform({flip: 'x'})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('x', 150)))
})
it('adds an entry to transforms when flip x with offset given', function() {
fx.transform({flip: 'x', offset: 100})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('x', 100)))
})
it('adds an entry to transforms when flip y given', function() {
fx.transform({flip: 'y'})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('y', 150)))
})
it('adds an entry to transforms when x given', function() {
fx.transform({x:20})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Translate(20, undefined)))
})
it('adds an entry to transforms when y given', function() {
fx.transform({y:20})
expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Translate(undefined, 20)))
})
})
// describe('transform()', function() {
// it('returns itself when no valid transformation was found', function() {
// expect(fx.transform({})).toBe(fx)
// })
// it('gets the current transforms', function() {
// expect(fx.transform()).toEqual(new SVG.Matrix(rect).extract())
// })
// it('gets a certain transformation if used with an argument', function() {
// expect(fx.transform('x')).toEqual(0)
// })
// it('adds an entry to transforms when matrix given', function() {
// var matrix = new SVG.Matrix(1,2,3,4,5,6)
// fx.transform(matrix)
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(matrix))
// })
// it('sets relative flag when given', function() {
// var matrix = new SVG.Matrix(1,2,3,4,5,6)
// fx.transform(matrix, true)
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(matrix))
// expect(fx.situation.transforms[0].relative).toBe(true)
// })
// it('adds an entry to transforms when rotation given', function() {
// fx.transform({rotation: 30, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Rotate(30, 0, 0)))
// })
// it('adds an entry to transforms when scale given', function() {
// fx.transform({scale: 2, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(2, 2, 0, 0)))
// })
// it('adds an entry to transforms when scaleX given', function() {
// fx.transform({scaleX: 2, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(2, 1, 0, 0)))
// })
// it('adds an entry to transforms when scaleY given', function() {
// fx.transform({scaleY: 2, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Scale(1, 2, 0, 0)))
// })
// it('adds an entry to transforms when skewX given', function() {
// fx.transform({skewX: 2, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Skew(2, 0, 0, 0)))
// })
// it('adds an entry to transforms when skewY given', function() {
// fx.transform({skewY: 2, cx:0, cy:0})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Skew(0, 2, 0, 0)))
// })
// it('adds an entry to transforms when flip x given', function() {
// fx.transform({flip: 'x'})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('x', 150)))
// })
// it('adds an entry to transforms when flip x with offset given', function() {
// fx.transform({flip: 'x', offset: 100})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('x', 100)))
// })
// it('adds an entry to transforms when flip y given', function() {
// fx.transform({flip: 'y'})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining((new SVG.Matrix()).flip('y', 150)))
// })
// it('adds an entry to transforms when x given', function() {
// fx.transform({x:20})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Translate(20, undefined)))
// })
// it('adds an entry to transforms when y given', function() {
// fx.transform({y:20})
// expect(fx.situation.transforms[0]).toEqual(jasmine.objectContaining(new SVG.Translate(undefined, 20)))
// })
// })

/* shortcuts for animation */
describe('animate()', function() {

+ 35
- 0
spec/spec/matrix.js View File

@@ -105,6 +105,41 @@ describe('Matrix', function() {

})

describe('compose()', function() {
it('composes a matrix to form the correct result', function() {
var composed = new SVG.Matrix().compose({
scaleX: 3, scaleY: 20, shear: 4, rotate: 50, translateX: 23, translateY: 52,
})
var expected = new SVG.Matrix().scale(3, 20).shear(4).rotate(50).translate(23, 52)
expect(composed).toEqual(expected)
})
})

describe('decompose()', function () {
it('decomposes a matrix properly', function () {
var matrix = new SVG.Matrix().scale(3, 2.5).shear(4).rotate(30).translate(20, 30)
var decomposed = matrix.decompose()
expect(decomposed.scaleX).toBeCloseTo(3)
expect(decomposed.scaleY).toBeCloseTo(2.5)
expect(decomposed.shear).toBeCloseTo(4)
expect(decomposed.rotate).toBeCloseTo(30)
expect(decomposed.translateX).toBeCloseTo(20)
expect(decomposed.translateY).toBeCloseTo(30)
})

it('can be recomposed to the same matrix', function () {
var matrix = new SVG.Matrix().scale(3, 2.5).shear(4).rotate(30).translate(20, 30)
var decomposed = matrix.decompose()
var composed = new SVG.Matrix().compose(decomposed)
expect(matrix.a).toBeCloseTo(composed.a)
expect(matrix.b).toBeCloseTo(composed.b)
expect(matrix.c).toBeCloseTo(composed.c)
expect(matrix.d).toBeCloseTo(composed.d)
expect(matrix.e).toBeCloseTo(composed.e)
expect(matrix.f).toBeCloseTo(composed.f)
})
})

describe('clone()', function() {
it('returns a clone of the matrix', function() {
var matrix = new SVG.Matrix(2, 0, 0, 5, 0, 0)

+ 1
- 1
spec/spec/sugar.js View File

@@ -177,7 +177,7 @@ describe('Sugar', function() {

it('sets flip to "both" when calling without anything', function() {
rect.flip()
expect(rect.transform).toHaveBeenCalledWith({ flip: 'both', origin: [0, 0]] }, true)
expect(rect.transform).toHaveBeenCalledWith({ flip: 'both', origin: [0, 0] }, true)
})

// this works because only x and y are valid flip values. Evereything else flips on both axis

+ 281
- 281
spec/spec/transformations.js View File

@@ -1,281 +1,281 @@
describe('Transformations:', function() {
var translated, scaled, rotated, skewed
beforeEach(function() {
translated = draw.rect(100,100).translate(100,100)
scaled = draw.rect(100,100).scale(2)
rotated = draw.rect(100,100).rotate(45, 50, 50)
skewed = draw.rect(100,100).skew(30)
})
/* SVG.Transformation is not tested because it is an abstract prototype */
describe('SVG.Transformation', function() {
it('marks the transformation as inversed when inverse flag given', function() {
var trans = new SVG.Transformation([], true)
expect(trans.inversed).toBeTruthy()
})
})
describe('SVG.Translate', function() {
var trans
beforeEach(function(){
trans = new SVG.Translate(translated.transform())
})
it('creates an object of type SVG.Transformation', function() {
expect(trans instanceof SVG.Transformation).toBeTruthy()
})
it('uses transformedX and transformedY as arguments', function() {
expect(trans.arguments).toEqual(['transformedX', 'transformedY'])
})
it('s method is translate()', function() {
expect(trans.method).toEqual('translate')
})
it('sets the necessary parameters at creation', function() {
expect(trans.transformedX).toBe(100)
expect(trans.transformedY).toBe(100)
})
describe('undo', function() {
it('sets the undo matrix which can undo the translation', function() {
var extracted = (new SVG.Matrix(1,0,0,1,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.toString()).toEqual('matrix(1,0,0,1,-20,-20)')
var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.toString()).toEqual('matrix(1,0,0,1,-2,-2)')
var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.e).toBeCloseTo(-extracted.transformedX)
expect(trans._undo.f).toBeCloseTo(-extracted.transformedY)
})
})
describe('at', function() {
it('creates a matrix at a certain position', function() {
expect(trans.at(0.3).toString()).toEqual('matrix(1,0,0,1,30,30)')
})
it('returns the inversed matrix from a specific position when created with inverse flag', function() {
expect((new SVG.Translate(translated.transform(), true)).at(0.3).toString()).toEqual('matrix(1,0,0,1,-30,-30)')
})
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
trans.undo(new SVG.Matrix(10,50,50,30,20,20).extract())
expect(trans.at(0.4).a).toEqual(1)
expect(trans.at(0.4).b).toEqual(0)
expect(trans.at(0.4).c).toEqual(0)
expect(trans.at(0.4).d).toEqual(1)
expect(trans.at(0.4).e).toBeCloseTo(100 * 0.4 + trans._undo.e * 0.4)
expect(trans.at(0.4).f).toBeCloseTo(100 * 0.4 + trans._undo.f * 0.4)
})
})
})
describe('SVG.Rotate', function() {
var trans
beforeEach(function(){
trans = new SVG.Rotate(45, 50, 50)
})
it('creates an object of type SVG.Transformation', function() {
expect(trans instanceof SVG.Transformation).toBeTruthy()
})
it('uses rotation, cx and cy as arguments', function() {
expect(trans.arguments).toEqual(['rotation', 'cx', 'cy'])
})
it('s method is rotate()', function() {
expect(trans.method).toEqual('rotate')
})
it('sets the necessary parameters at creation', function() {
expect(trans.rotation).toBe(45)
expect(trans.cx).toBe(50)
expect(trans.cy).toBe(50)
})
describe('undo', function() {
it('sets an undo object which holds rotation', function() {
var extracted = (new SVG.Matrix(1,0,0,1,0,0)).rotate(20, 50, 50).extract()
trans.undo(extracted)
expect(trans._undo.rotation).toBeCloseTo(20)
})
})
describe('at', function() {
it('creates a matrix at a certain position', function() {
expect(trans.at(0.3).toString()).toEqual((new SVG.Matrix()).rotate(0.3 * 45, 50, 50).toString())
})
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
trans.undo((new SVG.Matrix()).rotate(20, 50, 50).extract())
expect(trans.at(0.4).a).toBeCloseTo(1,1)
expect(trans.at(0.4).b).toEqual(jasmine.any(Number))
expect(trans.at(0.4).c).toEqual(jasmine.any(Number))
expect(trans.at(0.4).d).toBeCloseTo(1,1)
expect(trans.at(0.4).e).toEqual(jasmine.any(Number))
expect(trans.at(0.4).f).toEqual(jasmine.any(Number))
})
})
})
describe('SVG.Scale', function() {
var trans
beforeEach(function(){
trans = new SVG.Scale(2,2,50,50)
})
it('creates an object of type SVG.Transformation', function() {
expect(trans instanceof SVG.Transformation).toBeTruthy()
})
it('uses scaleX, scaleY, cx and cy as arguments', function() {
expect(trans.arguments).toEqual(['scaleX', 'scaleY', 'cx', 'cy'])
})
it('s method is scale()', function() {
expect(trans.method).toEqual('scale')
})
it('sets the necessary parameters at creation', function() {
expect(trans.scaleX).toBe(2)
expect(trans.scaleY).toBe(2)
expect(trans.cx).toBe(50)
expect(trans.cy).toBe(50)
})
describe('undo', function() {
it('sets the undo matrix which can undo the translation', function() {
var extracted = (new SVG.Matrix(4,0,0,4,0,0)).extract()
trans.undo(extracted)
expect(trans._undo.toString()).toEqual('matrix(0.25,0,0,0.25,37.5,37.5)')
var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.a).toBeCloseTo(1/extracted.scaleX)
expect(trans._undo.d).toBeCloseTo(1/extracted.scaleY)
expect(trans._undo.e).toBeCloseTo(45)
expect(trans._undo.f).toBeCloseTo(45)
var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.a).toBeCloseTo(1/extracted.scaleX)
expect(trans._undo.d).toBeCloseTo(1/extracted.scaleY)
})
})
describe('at', function() {
it('creates a matrix at a certain position', function() {
expect(trans.at(0.75).toString()).toEqual('matrix(1.75,0,0,1.75,-37.5,-37.5)')
})
it('returns the inversed matrix from a specific position when created with inverse flag', function() {
var morphed = (new SVG.Scale(scaled.transform(2,2,50,50), true)).at(0.25)
expect(morphed.a).toBeCloseTo(0.8)
expect(morphed.d).toBeCloseTo(0.8)
})
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).extract()).at(0.5)
expect(morphed.a).toBeCloseTo(0.6)
expect(morphed.b).toEqual(0)
expect(morphed.c).toEqual(0)
expect(morphed.d).toBeCloseTo(0.6)
expect(morphed.e).toBeCloseTo(20)
expect(morphed.f).toBeCloseTo(20)
})
})
})
describe('SVG.Skew', function() {
var trans
beforeEach(function(){
trans = new SVG.Skew(30,-30,50,50)
})
it('creates an object of type SVG.Transformation', function() {
expect(trans instanceof SVG.Transformation).toBeTruthy()
})
it('uses scaleX, scaleY, cx and cy as arguments', function() {
expect(trans.arguments).toEqual(['skewX', 'skewY', 'cx', 'cy'])
})
it('s method is skew()', function() {
expect(trans.method).toEqual('skew')
})
it('sets the necessary parameters at creation', function() {
expect(trans.skewX).toBe(30)
expect(trans.skewY).toBe(-30)
expect(trans.cx).toBe(50)
expect(trans.cy).toBe(50)
})
describe('undo', function() {
it('sets the undo matrix which can undo the translation', function() {
var extracted = (new SVG.Matrix()).skew(90, 90, 0, 0).extract()
trans.undo(extracted)
expect(trans._undo.a).toBeCloseTo(0)
expect(trans._undo.b).toBeCloseTo(0)
expect(trans._undo.c).toBeCloseTo(0)
expect(trans._undo.d).toBeCloseTo(0)
expect(trans._undo.e).toBeCloseTo(50)
expect(trans._undo.f).toBeCloseTo(50)
var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
trans.undo(extracted)
expect(trans._undo.a).toBeCloseTo(1)
expect(trans._undo.b).toBeCloseTo(0)
expect(trans._undo.c).toBeCloseTo(0)
expect(trans._undo.d).toBeCloseTo(1)
expect(trans._undo.e).toBeCloseTo(0)
expect(trans._undo.f).toBeCloseTo(0)
})
})
describe('at', function() {
it('creates a matrix at a certain position', function() {
expect(trans.at(0.75)).toEqual((new SVG.Matrix()).morph((new SVG.Matrix()).skew(30, -30, 50, 50)).at(0.75))
})
it('returns the inversed matrix from a specific position when created with inverse flag', function() {
var morphed = (new SVG.Scale(skewed.transform(20,-20,50,50), true)).at(0.25)
expect(morphed.a).toBeCloseTo(0.963)
expect(morphed.b).toBeCloseTo(0)
expect(morphed.c).toBeCloseTo(0)
expect(morphed.d).toBeCloseTo(0.963)
expect(morphed.e).toBeCloseTo(0)
expect(morphed.f).toBeCloseTo(0)
})
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).skew(20, 30, 20, 10).extract()).at(0.5)
expect(morphed.a).toBeCloseTo(1.266)
expect(morphed.b).toBeCloseTo(-0.7310)
expect(morphed.c).toBeCloseTo(0.1351)
expect(morphed.d).toBeCloseTo(0.9220)
expect(morphed.e).toBeCloseTo(-20.05593)
expect(morphed.f).toBeCloseTo(40.4468)
})
})
})
})
// describe('Transformations:', function() {
// var translated, scaled, rotated, skewed
//
// beforeEach(function() {
// translated = draw.rect(100,100).translate(100,100)
// scaled = draw.rect(100,100).scale(2)
// rotated = draw.rect(100,100).rotate(45, 50, 50)
// skewed = draw.rect(100,100).skew(30)
// })
//
// /* SVG.Transformation is not tested because it is an abstract prototype */
//
// describe('SVG.Transformation', function() {
// it('marks the transformation as inversed when inverse flag given', function() {
// var trans = new SVG.Transformation([], true)
// expect(trans.inversed).toBeTruthy()
// })
// })
//
// describe('SVG.Translate', function() {
// var trans
//
// beforeEach(function(){
// trans = new SVG.Translate(translated.transform())
// })
//
//
// it('creates an object of type SVG.Transformation', function() {
// expect(trans instanceof SVG.Transformation).toBeTruthy()
// })
//
// it('uses transformedX and transformedY as arguments', function() {
// expect(trans.arguments).toEqual(['transformedX', 'transformedY'])
// })
//
// it('s method is translate()', function() {
// expect(trans.method).toEqual('translate')
// })
//
// it('sets the necessary parameters at creation', function() {
// expect(trans.transformedX).toBe(100)
// expect(trans.transformedY).toBe(100)
// })
//
// describe('undo', function() {
// it('sets the undo matrix which can undo the translation', function() {
// var extracted = (new SVG.Matrix(1,0,0,1,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.toString()).toEqual('matrix(1,0,0,1,-20,-20)')
//
// var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.toString()).toEqual('matrix(1,0,0,1,-2,-2)')
//
// var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.e).toBeCloseTo(-extracted.transformedX)
// expect(trans._undo.f).toBeCloseTo(-extracted.transformedY)
// })
// })
//
// describe('at', function() {
// it('creates a matrix at a certain position', function() {
// expect(trans.at(0.3).toString()).toEqual('matrix(1,0,0,1,30,30)')
// })
// it('returns the inversed matrix from a specific position when created with inverse flag', function() {
// expect((new SVG.Translate(translated.transform(), true)).at(0.3).toString()).toEqual('matrix(1,0,0,1,-30,-30)')
// })
// it('returns the resulting transformation which has to be made to set an absolute translation', function() {
// trans.undo(new SVG.Matrix(10,50,50,30,20,20).extract())
//
// expect(trans.at(0.4).a).toEqual(1)
// expect(trans.at(0.4).b).toEqual(0)
// expect(trans.at(0.4).c).toEqual(0)
// expect(trans.at(0.4).d).toEqual(1)
// expect(trans.at(0.4).e).toBeCloseTo(100 * 0.4 + trans._undo.e * 0.4)
// expect(trans.at(0.4).f).toBeCloseTo(100 * 0.4 + trans._undo.f * 0.4)
// })
// })
// })
//
// describe('SVG.Rotate', function() {
// var trans
//
// beforeEach(function(){
// trans = new SVG.Rotate(45, 50, 50)
// })
//
//
// it('creates an object of type SVG.Transformation', function() {
// expect(trans instanceof SVG.Transformation).toBeTruthy()
// })
//
// it('uses rotation, cx and cy as arguments', function() {
// expect(trans.arguments).toEqual(['rotation', 'cx', 'cy'])
// })
//
// it('s method is rotate()', function() {
// expect(trans.method).toEqual('rotate')
// })
//
// it('sets the necessary parameters at creation', function() {
// expect(trans.rotation).toBe(45)
// expect(trans.cx).toBe(50)
// expect(trans.cy).toBe(50)
// })
//
// describe('undo', function() {
// it('sets an undo object which holds rotation', function() {
// var extracted = (new SVG.Matrix(1,0,0,1,0,0)).rotate(20, 50, 50).extract()
// trans.undo(extracted)
// expect(trans._undo.rotation).toBeCloseTo(20)
// })
// })
//
// describe('at', function() {
// it('creates a matrix at a certain position', function() {
// expect(trans.at(0.3).toString()).toEqual((new SVG.Matrix()).rotate(0.3 * 45, 50, 50).toString())
// })
// it('returns the resulting transformation which has to be made to set an absolute translation', function() {
// trans.undo((new SVG.Matrix()).rotate(20, 50, 50).extract())
//
// expect(trans.at(0.4).a).toBeCloseTo(1,1)
// expect(trans.at(0.4).b).toEqual(jasmine.any(Number))
// expect(trans.at(0.4).c).toEqual(jasmine.any(Number))
// expect(trans.at(0.4).d).toBeCloseTo(1,1)
// expect(trans.at(0.4).e).toEqual(jasmine.any(Number))
// expect(trans.at(0.4).f).toEqual(jasmine.any(Number))
// })
// })
// })
//
//
// describe('SVG.Scale', function() {
// var trans
//
// beforeEach(function(){
// trans = new SVG.Scale(2,2,50,50)
// })
//
//
// it('creates an object of type SVG.Transformation', function() {
// expect(trans instanceof SVG.Transformation).toBeTruthy()
// })
//
// it('uses scaleX, scaleY, cx and cy as arguments', function() {
// expect(trans.arguments).toEqual(['scaleX', 'scaleY', 'cx', 'cy'])
// })
//
// it('s method is scale()', function() {
// expect(trans.method).toEqual('scale')
// })
//
// it('sets the necessary parameters at creation', function() {
// expect(trans.scaleX).toBe(2)
// expect(trans.scaleY).toBe(2)
// expect(trans.cx).toBe(50)
// expect(trans.cy).toBe(50)
// })
//
// describe('undo', function() {
// it('sets the undo matrix which can undo the translation', function() {
// var extracted = (new SVG.Matrix(4,0,0,4,0,0)).extract()
// trans.undo(extracted)
// expect(trans._undo.toString()).toEqual('matrix(0.25,0,0,0.25,37.5,37.5)')
//
// var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.a).toBeCloseTo(1/extracted.scaleX)
// expect(trans._undo.d).toBeCloseTo(1/extracted.scaleY)
// expect(trans._undo.e).toBeCloseTo(45)
// expect(trans._undo.f).toBeCloseTo(45)
//
// var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.a).toBeCloseTo(1/extracted.scaleX)
// expect(trans._undo.d).toBeCloseTo(1/extracted.scaleY)
// })
// })
//
// describe('at', function() {
// it('creates a matrix at a certain position', function() {
// expect(trans.at(0.75).toString()).toEqual('matrix(1.75,0,0,1.75,-37.5,-37.5)')
// })
// it('returns the inversed matrix from a specific position when created with inverse flag', function() {
// var morphed = (new SVG.Scale(scaled.transform(2,2,50,50), true)).at(0.25)
//
// expect(morphed.a).toBeCloseTo(0.8)
// expect(morphed.d).toBeCloseTo(0.8)
// })
// it('returns the resulting transformation which has to be made to set an absolute translation', function() {
//
// var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).extract()).at(0.5)
//
// expect(morphed.a).toBeCloseTo(0.6)
// expect(morphed.b).toEqual(0)
// expect(morphed.c).toEqual(0)
// expect(morphed.d).toBeCloseTo(0.6)
// expect(morphed.e).toBeCloseTo(20)
// expect(morphed.f).toBeCloseTo(20)
// })
// })
// })
//
// describe('SVG.Skew', function() {
// var trans
//
// beforeEach(function(){
// trans = new SVG.Skew(30,-30,50,50)
// })
//
//
// it('creates an object of type SVG.Transformation', function() {
// expect(trans instanceof SVG.Transformation).toBeTruthy()
// })
//
// it('uses scaleX, scaleY, cx and cy as arguments', function() {
// expect(trans.arguments).toEqual(['skewX', 'skewY', 'cx', 'cy'])
// })
//
// it('s method is skew()', function() {
// expect(trans.method).toEqual('skew')
// })
//
// it('sets the necessary parameters at creation', function() {
// expect(trans.skewX).toBe(30)
// expect(trans.skewY).toBe(-30)
// expect(trans.cx).toBe(50)
// expect(trans.cy).toBe(50)
// })
//
// describe('undo', function() {
// it('sets the undo matrix which can undo the translation', function() {
// var extracted = (new SVG.Matrix()).skew(90, 90, 0, 0).extract()
// trans.undo(extracted)
// expect(trans._undo.a).toBeCloseTo(0)
// expect(trans._undo.b).toBeCloseTo(0)
// expect(trans._undo.c).toBeCloseTo(0)
// expect(trans._undo.d).toBeCloseTo(0)
// expect(trans._undo.e).toBeCloseTo(50)
// expect(trans._undo.f).toBeCloseTo(50)
//
// var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
// trans.undo(extracted)
// expect(trans._undo.a).toBeCloseTo(1)
// expect(trans._undo.b).toBeCloseTo(0)
// expect(trans._undo.c).toBeCloseTo(0)
// expect(trans._undo.d).toBeCloseTo(1)
// expect(trans._undo.e).toBeCloseTo(0)
// expect(trans._undo.f).toBeCloseTo(0)
// })
// })
//
// describe('at', function() {
// it('creates a matrix at a certain position', function() {
// expect(trans.at(0.75)).toEqual((new SVG.Matrix()).morph((new SVG.Matrix()).skew(30, -30, 50, 50)).at(0.75))
// })
// it('returns the inversed matrix from a specific position when created with inverse flag', function() {
// var morphed = (new SVG.Scale(skewed.transform(20,-20,50,50), true)).at(0.25)
//
// expect(morphed.a).toBeCloseTo(0.963)
// expect(morphed.b).toBeCloseTo(0)
// expect(morphed.c).toBeCloseTo(0)
// expect(morphed.d).toBeCloseTo(0.963)
// expect(morphed.e).toBeCloseTo(0)
// expect(morphed.f).toBeCloseTo(0)
// })
// it('returns the resulting transformation which has to be made to set an absolute translation', function() {
//
// var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).skew(20, 30, 20, 10).extract()).at(0.5)
//
// expect(morphed.a).toBeCloseTo(1.266)
// expect(morphed.b).toBeCloseTo(-0.7310)
// expect(morphed.c).toBeCloseTo(0.1351)
// expect(morphed.d).toBeCloseTo(0.9220)
// expect(morphed.e).toBeCloseTo(-20.05593)
// expect(morphed.f).toBeCloseTo(40.4468)
// })
// })
// })
// })

+ 10
- 9
src/boxes.js View File

@@ -18,7 +18,6 @@ SVG.Box = SVG.invent({
// add center, right, bottom...
fullBox(this)
},

extend: {
// Merge rect box with another, return a new instance
merge: function (box) {
@@ -53,7 +52,11 @@ SVG.Box = SVG.invent({
yMax = Math.max(yMax, p.y)
})

return new SVG.Box(xMin, yMin, xMax - xMin, yMax - yMin)
return new SVG.Box(
xMin, yMin,
xMax - xMin,
yMax - yMin
)
},

addOffset: function () {
@@ -62,11 +65,9 @@ SVG.Box = SVG.invent({
this.y += window.pageYOffset
return this
},

toString: function () {
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height
},

morph: function (x, y, width, height) {
this.destination = new SVG.Box(x, y, width, height)
return this
@@ -76,15 +77,15 @@ SVG.Box = SVG.invent({
if (!this.destination) return this

return new SVG.Box(
this.x + (this.destination.x - this.x) * pos,
this.y + (this.destination.y - this.y) * pos,
this.width + (this.destination.width - this.width) * pos,
this.height + (this.destination.height - this.height) * pos
this.x + (this.destination.x - this.x) * pos
, this.y + (this.destination.y - this.y) * pos
, this.width + (this.destination.width - this.width) * pos
, this.height + (this.destination.height - this.height) * pos
)
}
},

// Define Parent
// Define Parent
parent: SVG.Element,

// Constructor

+ 9
- 9
src/matrix.js View File

@@ -93,12 +93,12 @@ SVG.Matrix = SVG.invent({
// Applies a matrix defined by its affine parameters
compose: function (o) {
// Get the parameters
var sx = o.scaleX
var sy = o.scaleY
var lam = o.shear
var theta = o.rotate
var tx = o.translateX
var ty = o.translateY
var sx = o.scaleX || 1
var sy = o.scaleY || 1
var lam = o.shear || 0
var theta = o.rotate || 0
var tx = o.translateX || 0
var ty = o.translateY || 0

// Apply the standard matrix
var result = new SVG.Matrix()
@@ -122,7 +122,7 @@ SVG.Matrix = SVG.invent({

// Figure out if the winding direction is clockwise or counterclockwise
var determinant = a * d - b * c
var ccw = determinant > 0 ? -1 : 1
var ccw = determinant > 0 ? 1 : -1

// Since we only shear in x, we can use the x basis to get the x scale
// and the rotation of the resulting matrix
@@ -145,13 +145,13 @@ SVG.Matrix = SVG.invent({
translateY: f,

// Return the matrix parameters
matrix: this,
matrix: new SVG.Matrix(this),
a: this.a,
b: this.b,
c: this.c,
d: this.d,
e: this.e,
f: this.f,
f: this.f
}
},


+ 11
- 1
src/sugar.js View File

@@ -34,6 +34,12 @@ var sugar = {
})

SVG.extend([SVG.Element, SVG.FX], {
// Let the user set the matrix directly
matrix: function (mat, b, c, d, e, f) {
var matrix = new SVG.Matrix(arguments.length > 1 ? [mat, b, c, d, e, f] : mat)
return this.attr('transform', matrix)
},

// Map rotation to transform
rotate: function (angle, cx, cy) {
return this.transform({rotate: angle, origin: [cx, cy]}, true)
@@ -69,11 +75,15 @@ SVG.extend([SVG.Element, SVG.FX], {

// Map flip to transform
flip: function (direction, around) {
var directionString = typeof direction == 'string' ? direction
: isFinite(direction) ? 'both'
: 'both'
var origin = (direction === 'both' && isFinite(around)) ? [around, around]
: (direction === 'x') ? [around, 0]
: (direction === 'y') ? [0, around]
: isFinite(direction) ? [direction, direction]
: [0, 0]
this.transform({flip: direction || 'both', origin: origin}, true)
this.transform({flip: directionString, origin: origin}, true)
},

// Opacity

+ 4
- 3
src/transform.js View File

@@ -44,7 +44,7 @@ SVG.extend(SVG.Element, {
// same as above with parent equals root-svg
toDoc: function () {
return this.toParent(this.doc())
}
},
})

SVG.extend(SVG.Element, {
@@ -55,8 +55,9 @@ SVG.extend(SVG.Element, {
var bbox = this.bbox()

// Act as a getter if no object was passed
if (o == null) {
return new SVG.Matrix(this).decompose()
if (o == null || typeof o === 'string') {
var decomposed = new SVG.Matrix(this).decompose()
return decomposed[o] || decomposed

// Let the user pass in a matrix as well
} else if (o.a != null) {

Loading…
Cancel
Save