svgdotjs / svg.js

The lightweight library for manipulating and animating SVG
https://svgjs.dev
Other
11.14k stars 1.08k forks source link

runner.queue() seems only to trigger once #1108

Closed pragdave closed 4 years ago

pragdave commented 4 years ago

I'm probably not understanding what should happen, but here's a Pen: https://codepen.io/pragdave/pen/zYvLVrJ

let started = Date.now()
const timeline = new SVG.Timeline().persist(true)

// here's a callback that appends to the msg div when triggered
const msg = document.getElementById("msg")
const msgRunner = new SVG.Runner({duration: 1})
let count = 1

msgRunner.queue(() => msg.innerText+=` @${Date.now()-started}ms, event: ${count++}`)
msgRunner.schedule(timeline, 2000, 'absolute')

// and heres the exciting animation
const canvas = SVG().size(1000,500)
canvas.addTo("#canvas")

let r = canvas.rect(40,40).transform({position: [50, 50]}).fill("orange").timeline(timeline)
r.animate({duration: 10*1000, delay: 0, when: "absolute"}).ease("-").transform({position: [450,50]})

window.addEventListener("keyup", () => {
  msg.innerText += " key "
  timeline.reverse().play()
})

Two seconds into the animation, it triggers a function that outputs "Event 1". You can then hit any key to reverse the timeline. As it backs over the 2s point, the queued call isn't made. If you hit a key again, it goes back to playing forward. As it crosses the 2s mark, nothing happens.

I was expecting the callback still to be on the timeline at the 2s mark

Fuzzyma commented 4 years ago

Interesting cache. So here is the explanation:

queue() expects up to 4 parameters to be passed. It is used to queue the actual methods which run the animation. The 4 parameters are queue(initFn, runFn, retargetFn, isTransform). As you already can guess from the variable names, the first method is only run once to initialize the current state (so the animation knows were to start). The runFn on the other hand is run at every animation step (which would be only once in your case because your runner goes only one ms). Since an animation is only initialized once, the function will never rerun.

So what you can try is to just pass a runFn and see if that works out

Fuzzyma commented 4 years ago

So here is a working example. I wondered why it wasnt working as I imagined but then I realized that you passed an object to Runner. That doesnt work. Runner only takes a duration or a controller. Dont ask why we called the parameter options -.-

https://codepen.io/fuzzyma/pen/wvKEBam

Btw: I changed the "any" key to "a"

pragdave commented 4 years ago

Ah! I avoided the run function because I wasn't sure I could guarantee it would run exactly once. Rereading the code, though, it looks like it should be fine.

Thanks for the speedy reply. You saved me a morning, as I was just going to start working out what the timeline needed from a runner, so I could implement by own :) I'm not a big fan of TypeScript, but I can see the benefit of having an interface Runnable

On Thu, May 14, 2020 at 2:58 AM Ulrich-Matthias Schäfer < notifications@github.com> wrote:

So here is a working example. I wondered why it wasnt working as I imagined but then I realized that you passed an object to Runner. That doesnt work. Runner only takes a duration or a controller. Dont ask why we called the parameter options -.-

https://codepen.io/fuzzyma/pen/wvKEBam

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/svgdotjs/svg.js/issues/1108#issuecomment-628462909, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAACTGHCLA2XLGWV565J2ATRROQBJANCNFSM4NAJJVMQ .

Fuzzyma commented 4 years ago

Interesting thought. However, it was never intended to have something else running on the timeline except runners. They are complicated enough as is already :D.

Just had a look into the d.ts file and saw the overload which mentiones creating a runner with an object. Have to remove that one

Fuzzyma commented 4 years ago

What IS possible beside passing a number or a controller is passing a function. But that is converted to a Controller, too.

pragdave commented 4 years ago

As I already had it checked out, I just pushed than one-line deletion... :)

On Thu, May 14, 2020 at 4:34 PM Ulrich-Matthias Schäfer < notifications@github.com> wrote:

What IS possible beside passing a number or a controller is passing a function. But that is converted to a Controller, too.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/svgdotjs/svg.js/issues/1108#issuecomment-628898634, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAACTGBT5RRGPP2VPK7A5VTRRRPWTANCNFSM4NAJJVMQ .