Open emattias opened 4 years ago
Hi @emattias I have some good news! I think I can prove you wrong.
The key thing is that <AnimatedContainer>
uses a motion
, not a transition
— which is slightly different and something I found a bit confusing. By default this motion is Resize
.
But you can use something else.
For your example first create a new motion called dealyedResize, based on Resize, but which instead of resizing over the duration of the animation instead, waits for a third of the duration, then animates over the next third.
import { Resize } from 'ember-animated/motions/resize';
import { wait } from 'ember-animated';
class DelayedResize extends Resize {
* animate() {
yield wait(this.opts.duration / 3);
this.opts.duration = this.opts.duration / 3;
yield * super.animate();
}
}
export default function delayedResize(sprite, opts) {
return new DelayedResize(sprite, opts);
}
And import it into whichever backing class the template uses as a property
import Controller from '@ember/controller';
import delayedResize from '../motions/delayed-resize';
export default class ApplicationController extends Controller {
motion = delayedResize
}
So that you can reference it in the template instead of the default
Then add this motion to the <AnimatedContainer>
<AnimatedContainer @motion={{this.motion}}>
This should change the animation behaviour of the container already.
Then only thing left to do is to change the timing of your transition
to match this, so that the transition is now
1/3: fade out 1/3: animate container (done via the delayedRezise on the container) 1/3: fade in
So the final backing class code would look like this with a motion for the container and a transition for the animated elements.
import Controller from '@ember/controller';
import { fadeIn, fadeOut } from 'ember-animated/motions/opacity';
import { wait } from 'ember-animated';
import delayedResize from '../motions/delayed-resize';
export default class ApplicationController extends Controller {
*transition({ insertedSprites, removedSprites, duration }) {
for (let sprite of removedSprites) {
yield fadeOut(sprite, { duration: duration/3 });
}
yield wait(duration/3)
for (let sprite of insertedSprites) {
fadeIn(sprite, { duration: duration/3 });
}
}
motion = delayedResize
}
This should achieve the effect you want I hope?
Full code example with working demo here https://github.com/chrism/ember-animated-container
Thanks alot for that answer! That looks to achieve what I asked for but in a, I would say, brittle way.
One reason for using js to orchestrate animations is tomorrow have to cobble them together with synchronised delays etc. So I have that we can add a way to have full control of the container resize motion without having to sync delays of animations.
For example: I would like to make the resize motion of
AnimatedContainer
to happen after thefadeOut
in this example (this is a transition in aanimated-value
that is a direct child of anAnimatedContainer
):If I have understood correctly you dont have control over when the resize motion happens for the
AnimatedContainer
.Even by providing your own motion to the
AnimatedContainer
. I would be happy to be proven wrong! :)