From ac854317c3ef89ca2c25b6293530babf1cd9b28c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ulrich-Matthias=20Sch=C3=A4fer?= Date: Wed, 4 Jul 2018 11:57:00 +0200 Subject: [PATCH] fix origin transformation --- dirty.html | 21 +++++++++++---------- src/helpers.js | 1 - src/runner.js | 49 ++++++++++++++++++++++++------------------------ src/transform.js | 2 +- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dirty.html b/dirty.html index 1670e9c..896449b 100644 --- a/dirty.html +++ b/dirty.html @@ -271,21 +271,22 @@ a.timeline().source(() => { return timer }) - -let el = canvas.ellipse(20, 20) -window.moveit = function (x, y) { - el.move(x, y) -} - - let obj = { rotate: 180, origin: 'center', translate: [300, 0] } -let obj2 = { rotate: -180, origin: 'center' } +let obj2 = { rotate: 360, origin: 'center' } a.clone() // startPosition a.clone().transform(obj, true).transform(obj2, true) // endPosition -//a.animate(new SVG.Spring(50, 30)).transform(obj) // animation -a.animate(300).transform(obj, true).transform(obj2, true) // animation +// that works +a.animate(new SVG.Spring(50, 30)).transform(obj) // animation +// that breaks (why??) +// a.clone().animate(new SVG.Spring(50, 30)).transform(obj) // animation +//a.animate(300).transform(obj, true).transform(obj2, true) // animation + + + + +//setTimeout(()=>console.log(a.transform()), 6000) // // // Put an ellipse where we expect the object to be // canvas.ellipse(30, 30).center(100, 500) diff --git a/src/helpers.js b/src/helpers.js index 108fbfc..b25d3b6 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -281,7 +281,6 @@ function getOrigin (o, element) { : y + height / 2 // Find the new center in the transformed coordinates - console.log(element.attr('transform')) const matrix = new SVG.Matrix(element) const {x: tx , y: ty} = new SVG.Point(bx, by).transform(matrix) diff --git a/src/runner.js b/src/runner.js index 20cc03e..1454ad9 100644 --- a/src/runner.js +++ b/src/runner.js @@ -631,10 +631,6 @@ SVG.extend(SVG.Runner, { true, true: relative whatever was passed transformation with ObjectBag **/ - - // Set the origin here - - // If we have a relative transformation and its not a matrix // we morph all parameters directly with the ObjectBag // the following cases are covered here: @@ -642,7 +638,6 @@ SVG.extend(SVG.Runner, { // - true, true with ObjectBag var morpher var origin - var startTransform var current var element if(relative && !isMatrix) { @@ -656,7 +651,7 @@ SVG.extend(SVG.Runner, { origin = new SVG.Point(transformedOrigin) .transform(new SVG.Matrix(element).inverse()) - transforms.origin = [origin.x, origin.y] + transforms = {...transforms, origin: [origin.x, origin.y]} morpher.to(formatTransforms(transforms)) } @@ -665,19 +660,10 @@ SVG.extend(SVG.Runner, { this.element().addRunner(this) }, function (pos) { - let currentMatrix = element._currentTransform(this) - //origin = getOrigin (transforms, element) let {x, y} = origin.transform(currentMatrix) -moveit(x, y) - -// console.log(currentMatrix.decompose(origin[0], origin[1])); - - /* - - 1. Transform the origin by figuring out the delta - At the start, we had: @@ -689,9 +675,9 @@ moveit(x, y) let C = Matrix(element) let newOrigin = origin.transform(S.inv).transform(C) - */ + // this is an ugly hack to update the origins in the morpher let index = morpher._from.indexOf('ox') morpher._from.splice(index, 4, 'ox', x, 'oy', y) morpher._to.splice(index, 4, 'ox', x, 'oy', y) @@ -714,7 +700,6 @@ moveit(x, y) // - true, false with SVG.Matrix // - false, false with SVG.Matrix - // 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx] var morphType = (isMatrix && !affine) ? SVG.Matrix : SVG.Morphable.TransformBag @@ -728,8 +713,14 @@ moveit(x, y) element.addRunner(this) if (!origin && affine) { - origin = getOrigin(transforms, element) - transforms.origin = origin + // origin = getOrigin(transforms, element) + // transforms = {...transforms, origin} + + let transformedOrigin = getOrigin (transforms, element) + origin = new SVG.Point(transformedOrigin) + .transform(new SVG.Matrix(element).inverse()) + + transforms = {...transforms, origin: [origin.x, origin.y]} morpher.to(transforms) } @@ -746,8 +737,8 @@ moveit(x, y) if (affine) { startMatrix.origin = origin - // FIXME: correct the rotation so that it takes the shortest path - // GIVE ME (rCurrent) (rTarget) - to store the current/target angle + // that a hack to update the rotation in the morpher + // so it always takes the shortest path const rTarget = transforms.rotate || 0 const rCurrent = startMatrix.decompose(origin[0], origin[1]).rotate @@ -760,12 +751,22 @@ moveit(x, y) morpher._to.splice(3, 1, target) } - morpher.from(startMatrix) + // make sure morpher starts at the current matrix for declarative + // this happens only when the init function is called multiple times + // which is only true for declarative + morpher.from(current || startMatrix) }, function (pos) { if (!relative) this.clearTransform() - var matrix = morpher.at(pos) - this.addTransform(matrix) + + let currentMatrix = element._currentTransform(this) + let {x, y} = origin.transform(currentMatrix) + + morpher._from.splice(-2, 2, x, y) + morpher._to.splice(-2, 2, x, y) + + current = morpher.at(pos) + this.addTransform(current) return morpher.done() }, true) diff --git a/src/transform.js b/src/transform.js index c769f53..8b1d56b 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.origin = getOrigin(o, this) + 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) -- 2.39.5