diff options
author | Saivan <savian@me.com> | 2018-09-17 14:10:12 +1000 |
---|---|---|
committer | Saivan <savian@me.com> | 2018-09-17 14:10:12 +1000 |
commit | 791bb2bab91a022d1b5265b40faa997ad9938ad7 (patch) | |
tree | 6f0a9515b43312efeb51f70463063e21fd078ed5 /src | |
parent | a4c502febf836f02c13a8c1550632eeed09476da (diff) | |
download | svg.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
Diffstat (limited to 'src')
-rw-r--r-- | src/helpers.js | 22 | ||||
-rw-r--r-- | src/runner.js | 47 | ||||
-rw-r--r-- | src/transform.js | 2 |
3 files changed, 46 insertions, 25 deletions
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) |