motion-canvas icon indicating copy to clipboard operation
motion-canvas copied to clipboard

Method to hold an animation state for a specified time in compact form

Open samhattangady opened this issue 1 year ago • 4 comments

Description There are cases where we might want to do some animation, hold it for a certain amount of time, and then move to another.

I have found that it is quite a common usecase in my workflow.

For example, fade some text in, hold it for 2 seconds, and then fade it out again.

Right now, we have to do it like this

yield* headerText().opacity(1, 1, easeInOutCubic);
yield* waitFor(2);
yield* headerText().opacity(0, 1, easeInOutCubic);

// or we can do it like this
// note how the .to method is the same value, and so it keeps the text opacity at 1 for an additional second
yield* headerText().opacity(1, 1, easeInOutCubic).to(1, 2).to(0, 1, easeInOutCubic);

This is very verbose, and it means that if you want to change max opacity from 1 to 0.8, then you would have to make the change in two places.

Proposed solution I think one solutions that would be nice is to have a hold method.

yield* headerText().opacity(1, 1, easeInOutCubic).hold(2).to(0, 1, easeInOutCubic);

Additional context I would like to make the contribution myself, but right now, I don't know where the change should be, My best guess is in signals/types, in the SignalGenerator.

I would appreciate if you could point me in the correct direction.

samhattangady avatar Mar 06 '23 11:03 samhattangady

This is actually a regression because we used to have something like this in v1 during early access.

I think it should be called wait instead of hold to be consistent with functions like waitFor and waitUntil

SignalGenerator only defines the type, the actual implementation of to can be found in SignalContext: https://github.com/motion-canvas/motion-canvas/blob/1c259d0d574bb56dbc8bc448300d9b94ee4d0bc4/packages/core/src/signals/SignalContext.ts#L197-L198

aarthificial avatar Mar 07 '23 00:03 aarthificial

Is there a reason that it was removed? Or any other way that you prefer it to be done?

samhattangady avatar Mar 07 '23 01:03 samhattangady

It wasn't removed, per se. v1 had no signals, it used a slightly different api for chained animations:

yield* node.x(ANIMATE)
  .key(200, 2) // transition to 200
  .diff(-100, 2) // transition to 200 - 100
  .do(() => {}) // call a callback
  .waitFor(2) // wait for 2 seconds
  .run(3) // run the chain 3 times.

After switching to signals, to (key) was the only one I had the time to reimplement.

I think implementing it the same way as to is the best solution here.

aarthificial avatar Mar 07 '23 02:03 aarthificial

Ah got it. I will try to implement it, and see if I can get it working.

Thanks,

samhattangady avatar Mar 07 '23 03:03 samhattangady