summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaivan <savian@me.com>2018-09-17 14:10:12 +1000
committerSaivan <savian@me.com>2018-09-17 14:10:12 +1000
commit791bb2bab91a022d1b5265b40faa997ad9938ad7 (patch)
tree6f0a9515b43312efeb51f70463063e21fd078ed5
parenta4c502febf836f02c13a8c1550632eeed09476da (diff)
downloadsvg.js-791bb2bab91a022d1b5265b40faa997ad9938ad7.tar.gz
svg.js-791bb2bab91a022d1b5265b40faa997ad9938ad7.zip
Fixed the relative non-affine transform animations
This commit uncovered an issue with the relative non-affine transformations. It is now correctly fixed and working. Next we should fix the affine transforms as well. Changes ======= - Fixed the relative non-affine transformation animations
-rw-r--r--dirty.html49
-rw-r--r--src/helpers.js22
-rw-r--r--src/runner.js47
-rw-r--r--src/transform.js2
4 files changed, 77 insertions, 43 deletions
diff --git a/dirty.html b/dirty.html
index ab9e3c8..f7542e6 100644
--- a/dirty.html
+++ b/dirty.html
@@ -25,7 +25,7 @@
<div id="position"><label>Position: <input type="range" min="0" max="5" step="0.01"></slider></label><span></span></div>
<!-- Making the svg -->
-<svg width=1000px height=1000px id="canvas" viewbox="-1000 -1000 3000 3000">
+<svg width=1000px height=1000px id="canvas" viewbox="-1000 -2000 5000 5000">
<rect x=50 y=100 width=200 height=100 stroke=none stroke-width=2 />
</svg>
@@ -295,6 +295,7 @@ let canvas = SVG('#canvas')
// })
//
+canvas.ellipse(20, 20).center(100, 100)
let r = canvas.rect(200, 400).move(100, 100)
.attr('opacity', 0.3)
.transform({ tx: 300, ty: 500, origin: 'top-left' })
@@ -304,26 +305,38 @@ let wait = 1000
let rAnim = r.clone().attr('fill', '#f00').animate(wait).attr('fill', '#0f0')
let rDecl = r.clone().attr('fill', 'blue').animate(new SVG.Spring(wait, 15))
-// Move once
-setTimeout(() => {
- let trans = {tx: 500, ty: 300}
- r.transform(trans, true)
- rAnim.animate(wait, 0, 'start').transform(trans, true)
- //rDecl.transform(trans, true)
-}, wait)
-
-// Move again
+// // Move once
// setTimeout(() => {
-// let trans = {rotate: 300}
+// let trans = {tx: 500, ty: 300}
// r.transform(trans, true)
-// rAnim.animate(wait).transform(trans, true)
-// //rDecl.transform(trans, true)
-// }, 1.5 * wait )
-
-
-
-
+// // rAnim.animate(wait, 0, 'start').transform(trans, true)
+// rDecl.transform(trans, true)
+// }, wait)
+// Move again
+setTimeout(() => {
+ let transform = {
+ origin: 'top-left',
+ translate: [530, 250],
+ rotate: 300,
+ scale: 2,
+ shear: 1,
+ }
+ let relative = true
+ let affine = false
+ r.transform(transform, relative)
+ rAnim.animate(wait).transform(transform, relative, affine)
+ rDecl.transform(transform, relative, affine)
+}, 0.1 * wait )
+
+
+// declaritive relative (affine/nonaffine)
+// declaritive absolute non affine
+// normal non affine relative
+
+// D N
+// R
+// A
diff --git a/src/helpers.js b/src/helpers.js
index d4abc08..44bce72 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -249,9 +249,10 @@ function formatTransforms (o) {
}
-function getOrigin (o, element) {
+function getOrigin (o, element, relative) {
// Allow origin or around as the names
let origin = o.around == null ? o.origin : o.around
+ let ox, oy
// Allow the user to pass a string to rotate around a given point
if (typeof origin === 'string' || origin == null) {
@@ -269,13 +270,22 @@ function getOrigin (o, element) {
: y + height / 2
// Set the bounds eg : "bottom-left", "Top right", "middle" etc...
- const ox = o.ox != null ? o.ox : bx
- const oy = o.oy != null ? o.oy : by
+ ox = o.ox != null ? o.ox : bx
+ oy = o.oy != null ? o.oy : by
- // Set the origin based on the current matrix location
- return [ox, oy]
+ } else {
+ ox = origin[0]
+ oy = origin[1]
+ }
+
+ // Transform the origin into the current reference frame
+ if ( relative ) {
+ let matrix = new SVG.Matrix(element)
+ let originRelative = new SVG.Point( ox, oy ).transform(matrix)
+ ox = originRelative.x
+ oy = originRelative.y
}
// Return the origin as it is if it wasn't a string
- return origin
+ return [ ox, oy ]
}
diff --git a/src/runner.js b/src/runner.js
index e82d641..881efd4 100644
--- a/src/runner.js
+++ b/src/runner.js
@@ -615,8 +615,10 @@ SVG.extend(SVG.Runner, {
//
// M v -----|-----(D M v = F v)------|-----> T v
//
- // 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx]
- // 2. on every frame: pull the current state of all previous transforms (M - m can change)
+ // 1. define the final state (T) and decompose it (once)
+ // t = [tx, ty, the, lam, sy, sx]
+ // 2. on every frame: pull the current state of all previous transforms
+ // (M - m can change)
// and then write this as m = [tx0, ty0, the0, lam0, sy0, sx0]
// 3. Find the interpolated matrix F(pos) = m + pos * (t - m)
// - Note F(0) = M
@@ -624,38 +626,43 @@ SVG.extend(SVG.Runner, {
// 4. Now you get the delta matrix as a result: D = F * inv(M)
transform: function (transforms, relative, affine) {
- if (this._isDeclarative && this._tryRetarget('transform', transforms)) {
+ // If we have a declarative function, we should retarget it if possible
+ relative = transforms.relative || relative
+ if (this._isDeclarative && !relative && this._tryRetarget('transform', transforms)) {
return this
}
// Parse the parameters
var isMatrix = transforms.a != null
- relative = transforms.relative || relative
affine = transforms.affine != null
? transforms.affine
: (affine != null ? affine : !isMatrix)
-
- const morpher = new SVG.Morphable().type(
- affine ? SVG.Morphable.TransformBag2 : SVG.Matrix
- ).stepper(this._stepper)
+ // Create a morepher and set its type
+ const morpher = new SVG.Morphable()
+ .type( affine ? SVG.Morphable.TransformBag2 : SVG.Matrix )
+ .stepper(this._stepper)
let origin
let element
let current
let currentAngle
var u = 0
- this.queue(function () {
+
+ function setup () {
// make sure element and origin is defined
element = element || this.element()
- origin = origin || getOrigin(transforms, element)
+ origin = origin || getOrigin(transforms, element, relative)
+
+this.element().parent().ellipse(50, 50).center(...origin)
// add the runner to the element so it can merge transformations
element.addRunner(this)
// Deactivate all transforms that have run so far if we are absolute
- if (!relative) {
+ let absolute = !relative
+ if ( absolute ) {
element._clearTransformRunnersBefore(this)
}
@@ -686,7 +693,9 @@ SVG.extend(SVG.Runner, {
morpher.from(start)
morpher.to(target)
- }, function (pos) {
+ }
+
+ function run (pos) {
// clear all other transforms before this in case something is saved
// on this runner. We are absolute. We dont need these!
@@ -705,23 +714,25 @@ SVG.extend(SVG.Runner, {
current = new SVG.Matrix(affineParameters)
this.addTransform(current)
-
return morpher.done()
+ }
- }, function (newTransforms) {
+ function retarget (newTransforms) {
// only get a new origin if it changed since the last call
- if ((newTransforms.origin || 'center').toString() != (transforms.origin || 'center').toString()) {
+ if (
+ (newTransforms.origin || 'center').toString()
+ != (transforms.origin || 'center').toString()
+ ) {
origin = getOrigin (transforms, element)
}
// overwrite the old transformations with the new ones
transforms = {...newTransforms, origin}
- })
-
+ }
+ this.queue(setup, run, retarget)
this._isDeclarative && this._rememberMorpher('transform', morpher)
-
return this
},
diff --git a/src/transform.js b/src/transform.js
index 0549d7a..35eb53e 100644
--- a/src/transform.js
+++ b/src/transform.js
@@ -58,7 +58,7 @@ SVG.extend(SVG.Element, {
}
// Set the origin according to the defined transform
- o = {...o, origin: getOrigin(o, this, relative)}
+ o = {...o, origin: getOrigin(o, this)}
// The user can pass a boolean, an SVG.Element or an SVG.Matrix or nothing
var cleanRelative = relative === true ? this : (relative || false)