Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control when AnimatedContainer resize transition happens #218

Open
emattias opened this issue May 26, 2020 · 2 comments
Open

Control when AnimatedContainer resize transition happens #218

emattias opened this issue May 26, 2020 · 2 comments

Comments

@emattias
Copy link

emattias commented May 26, 2020

For example: I would like to make the resize motion of AnimatedContainer to happen after the fadeOut in this example (this is a transition in a animated-value that is a direct child of an AnimatedContainer):

  transition = function* ({ insertedSprites, removedSprites }) {
    yield fadeOut(removedSprites[0], { duration: 150 });

    yield animatedContainerResize() // <- this is what I would like to do

    yield fadeIn(insertedSprites[0], { duration: 150 });
  }

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! :)

@chrism
Copy link
Contributor

chrism commented May 28, 2020

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

@emattias
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants