From: Ulrich-Matthias Schäfer Date: Sun, 3 Jun 2018 06:02:08 +0000 (+0200) Subject: transformation works now for ONE element. More work required X-Git-Tag: 3.0.0~60^2~38 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=977554fea55eaf42ed09757529bc2566c003e755;p=svg.js.git transformation works now for ONE element. More work required --- diff --git a/dirty.html b/dirty.html index a31ab64..d329d86 100644 --- a/dirty.html +++ b/dirty.html @@ -199,18 +199,26 @@ function getColor(t) { var timer = 0 -let recy = SVG('').addTo('svg').size(100, 100).transform({translateX: -50, translateY: -50}) +let recy = SVG('').addTo('svg').size(100, 100)//.transform({translateX: -50, translateY: -50}) recy.timeline().source(() => { - timer += 16 + timer += 5 return timer }) var runner = recy - .animate(5000) - .transform({rotate: 360, origin: [200, 200]}, true) - .transform({translate: [200, 200]}, true) - .animate(2000, 1000, 'absolute') - .transform({scale: 2}, true) + // .animate(100).attr('fill', '#fff') + //.animate().transform({rotate: -45, origin: [50, 50]}) + .animate(500) + .transform({ + a: -1, b: -0.1, c: 0.1, d: -1, e: 200, f: 200, affine: true + }, true) + .animate(500, 0, 'after') + .transform({scale:2}, true) + // .transform({rotate: 360}, true) + // .transform({translateX: 50, translateY: 50}, true) + //.transform({translateX: 50, translateY: 50}, true) + // .animate(500, 0, 'absolute') + // .transform({scale: 2}, true) // .animate(2000, 0, 'absolute') // .transform({rotate: -300}) diff --git a/src/runner.js b/src/runner.js index 3fe5e70..e6f7358 100644 --- a/src/runner.js +++ b/src/runner.js @@ -48,7 +48,7 @@ SVG.Runner = SVG.invent({ this.tags = {} // save transforms applied to this runner - // this.transforms = [] + this.transforms = new SVG.Matrix() this.count = 0 // Looping variables @@ -285,19 +285,25 @@ SVG.Runner = SVG.invent({ // this.fire('start', this) } + // Work out if the runner is finished + // set the done flag here so animations know, + // that they are running in the last step + // (this is good for transformations which can be merged) + this.done = !declarative && !justFinished && this._time >= duration + // Call initialise and the run function this._initialise() var declarative = this._isDeclarative if ( runNow || declarative ) { + this.transforms = new SVG.Matrix() var converged = this._run(declarative ? dt : position) // this.fire('step', this) } - this.count = 0 + // correct the done flag here + // declaritive animations itself know when they converged + this.done = this.done || (converged && declarative) - // Work out if we are done and return this - this.done = (converged && declarative) - || (this._time >= duration && !justFinished && !declarative) if (this.done) { // this.fire('finish', this) } @@ -420,14 +426,14 @@ SVG.Runner = SVG.invent({ }, _pushLeft: function (transform) { - // this.transforms.push(transform) - // this.element().addRunner(this) - this.element()._queueTransform(transform, false, this.id, this.count++) + this.transforms = this.transforms.lmultiply(transform) + this.element().addRunner(this) + //this.element()._queueTransform(transform, false, this.id, this.count++) return this }, _currentTransform: function () { - return this.element()._currentTransform(this.id, this.count) + return this.element()._currentTransform(this) } }, @@ -465,20 +471,58 @@ SVG.Runner.sanitise = function (duration, delay, when) { } } -recudeTransform = function (arr, base) { - return arr.reduceRight(function (last, curr) { - if(Array.isArray(curr)) return recudeTransform(curr, last) +reduceTransform = function (arr, base) { + return arr.reduce(function (last, curr) { return last.lmultiply(curr) }, base) } +function mergeTransforms () { + var net = reduceTransform(this.runners.map(el => el.transforms), this._baseTransform) + this.transform(net) + this._mergeTransforms = null + //_this._transformationChain = [] +} + SVG.extend(SVG.Element, { + addRunner: function (r) { + var runners = this.runners + var index = ((runners.indexOf(r) + 1) || this.runners.push(r)) - 1 + + if(r.done) this.checkForSimplification(index) + + this._mergeTransforms = SVG.Animator.transform_frame(mergeTransforms.bind(this)) + }, + + checkForSimplification: function (index) { + var r + if(index == 0) { + r = this.runners.shift() + this._baseTransform = this._baseTransform.lmultiply(r.transforms) + r.transforms = new SVG.Matrix() + return + } + + var r = this.runners[index-1] + + if(!r.done) return +console.log(r, this.runners[index]) + var obj = { + done: true, + transforms: r.transforms.multiply(this.runners[index].transforms) + } + + this.runners.splice(index-1, 2, obj) + + }, + _prepareRunner: function () { if (!this._baseTransform) { this._baseTransform = new SVG.Matrix(this) this._mergeTransforms = null this._transformationChain = [] + this.runners = [] } }, @@ -502,7 +546,7 @@ SVG.extend(SVG.Element, { // This function will merge all of the transforms on the chain, but it // should only be called at most, once per animation frame function mergeTransforms () { - var net = recudeTransform(_this._transformationChain.map(el => el.transforms), _this._baseTransform) + var net = reduceTransform(_this.runners.map(el => el.transforms), _this._baseTransform) _this.transform(net) _this._mergeTransforms = null //_this._transformationChain = [] @@ -518,21 +562,11 @@ SVG.extend(SVG.Element, { this._mergeTransforms = SVG.Animator.transform_frame(mergeTransforms) }, - _currentTransform: function (id, count) { - var runners = [] - var chain = this._transformationChain - - for(var i = 0, len = chain.length; i < len; ++i) { - if(chain[i].id == id) { - var a = {id: id, transforms: chain[i].transforms.slice(0, count+1)} - runners.push(a) - break - } + _currentTransform: function (r) { - runners.push(chain[i]) - } + var transforms = this.runners.slice(0, this.runners.indexOf(this)+1).map(el => el.transforms) - return recudeTransform(runners.map(el => el.transforms), this._baseTransform) + return reduceTransform(transforms, this._baseTransform) } }) @@ -596,8 +630,9 @@ SVG.extend(SVG.Runner, { // 4. Now you get the delta matrix as a result: D = F * inv(M) transform: function (transforms, relative, affine) { - affine = transforms.affine || affine || !!transforms.a - relative = transforms.relative || relative || false + var isMatrix = transforms.a != null + affine = transforms.affine || affine || !isMatrix + relative = transforms.relative || relative var morpher @@ -619,7 +654,7 @@ SVG.extend(SVG.Runner, { // the following cases are covered here: // - true, false with ObjectBag // - true, true with ObjectBag - if(relative && transforms.a == null) { + if(relative && !isMatrix) { morpher = new SVG.Morphable.ObjectBag(formatTransforms({})) .to(formatTransforms(transforms)) .stepper(this._stepper) @@ -641,7 +676,7 @@ SVG.extend(SVG.Runner, { // - false, false with SVG.Matrix // 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx] - morpher = (transforms.a && !affine) + morpher = (isMatrix && !affine) ? new SVG.Matrix().to(transforms) : new SVG.Morphable.TransformBag().to(transforms) diff --git a/src/timeline.js b/src/timeline.js index eb2e56b..f697c01 100644 --- a/src/timeline.js +++ b/src/timeline.js @@ -43,7 +43,6 @@ SVG.Timeline = SVG.invent({ this._persist = 0 // Keep track of the running animations and their starting parameters - this._baseTransform = null this._nextFrame = null this._paused = false this._runners = new Set() diff --git a/todo.md b/todo.md index b1b5a87..9b0621a 100644 --- a/todo.md +++ b/todo.md @@ -12,6 +12,9 @@ Ulima timeline.persist('monkey-in', Infinity) +- animation result is different from setting directly +- format transforms didnt take all parameters into account (theta / rotate) + Both ==== - We discussed that matrices should always be applied from the left for animation, so we have: