ember-animation / liquid-fire

Animations & transitions for ambitious Ember applications.
Other
1.15k stars 199 forks source link

Programatically define transitions #95

Closed Globegitter closed 9 years ago

Globegitter commented 10 years ago

Let's say I have transitions from/to routes, so my transitions.js would look like:

this.transition(
  this.fromRoute('foo'),
  this.toRoute('bar'),
  this.use('toLeft')
);

But now I don't want this route to always be toLeft, but depending on some user interaction I want this to be right, up, down or whatever. So is it possible to change/set, for example in a controller the type of animation/transition for a route? This could probably also be extended to the other types of transitions, but routes are the only ones we need for our use case.

ef4 commented 10 years ago

It's already possible to define arbitrarily complex rules that decide which transition to run. The expectation is that you would decide based on source route, destination route, source model, and destination model.

http://ef4.github.io/liquid-fire/#/transition-map/model-constraints

Does that cover your use case?

codepreneur commented 10 years ago

What I would need is this (i.e. if the button person clicked has certain class transition accordingly):

  this.transition(
    this.fromRoute('foo'),
    this.toRoute('bar'),
    this.hasClass('move-left'), // if true transition to left (this class is inside of {{link-to }} helper
    this.use('toLeft', { duration: 500 }),
    this.reverse('toRight', { duration: 500 })
    );    

  this.transition(
    this.fromRoute('foo'),
    this.toRoute('bar'),
    this.hasClass('move-right'), // if true transition to right (this class is inside of {{link-to }} helper
    this.use('toRight', { duration: 500 }),
    this.reverse('toLeft', { duration: 500 })
    );    

or this (which {{link-to }} helper has been clicked is being recorded):

  this.transition(
    this.fromRoute('foo'),
    this.toRoute('bar'),
    this.toModel(function(){ return this.get('q41') === 'left' })
    this.use('toLeft', { duration: 500 }),
    this.reverse('toRight', { duration: 500 })
    );    

  this.transition(
    this.fromRoute('foo'),
    this.toRoute('bar'),
    this.toModel(function(){ return this.get('q41') === 'right' })
    this.use('toRight', { duration: 500 }),
    this.reverse('toLeft', { duration: 500 })
    );   

or even possibly combining hasClass and Model restrictions.

Is that possible?

http://stackoverflow.com/questions/26512792/how-to-programatically-dynamically-define-route-transitions-in-liquid-fire-embe

Globegitter commented 10 years ago

Just to add to codepreneurs answer, the app has one model that is getting created in the indexController and then all other routes access that same model. I tried to use setupController to manually give some of the routes the model and then in the fromModel check for the value. I can now get the model to print in the fromModel function (and if I check it out in the dev console I can see it does have filled in _data attributes), but console.log(this.get('whateverattribute')) prints undefined.

Edit: Digging a bit further, even if I just return true in the fromModel it doesn't do any animation at all. So as far as I understand and managed to get this to work, this does not seem to cover my use-case.

Globegitter commented 9 years ago

@ef4 Looked more into it over the last few days and I am really not seeing a proper solution for this use-case via liquid-fire. Right now I am trying to use https://github.com/gigafied/ember-animate alongside liquid-fire, which would be able to achieve what I am looking for:

animateOut : function (done) {
  if (this.get('controller.userHasClickedUp')) {
    this.$().slideUp(500, done);
  } else {
    this.$().slideDown(500, done);
  }
}

This is of course a quite simplified implementation, but should demonstrate the basic idea.

But in other words having some more fine-grained/dynamic/user-dependent control over the animations (without the need of the model) would be extremely useful.

ef4 commented 9 years ago

I'm still not understanding the problem here. The examples in @codepreneur 's comment are already supported. You can combine hasClass and model rules.

It is an Ember anti-pattern if your app has state that is not coming from the URL, meaning only the route and the model. It's deliberate that liquid-fire follows Ember's conventions and tries to base its rules on only these things. That's how we can always know what to animate, even when users are deep-linking, using the back button, etc.

If two different actions have different meanings to the user, that meaning should be reflected in either the route or the model.

@Globegitter , I may be misunderstanding but it sounds like your app would break if the user doesn't visit the index route first. If you want the same model in every route, just set them all up the load the same model, and pass it around via your link-to or transitionTos so it only loads on the first route (whichever one that is) and then gets passed around after that.