Giter VIP home page Giter VIP logo

ember-animated-outlet's Introduction

Ember Animated Outlet Build Status

Ember Animated Outlet is a plug'n'play module to support animated route transitions in Ember.js.

The module is maintained by Billy's Billing online accounting software. We use it ourselves in our upcoming HTML5 mobile app.

Works with Ember.js 1.0.0. Has also been tested with Ember.js 1.3.0-beta (as of https://github.com/emberjs/ember.js/commit/0fcc6f8d236152439c68034d87ff74d133cf8b50).

Demo

You can see a live demo here: ember-animated-outlet-demo.herokuapp.com.

How to use

It's very easy to use Ember Animated Outlet and get full-fledged animation transitions in your Ember.js app.

Include Javascript and CSS files in your HTML page

Download the latest version of ember-animated-outlet.js (or build it yourself), and include it in your HTML page after the ember.js file.

You also need to download and include the latest version of ember-animated-outlet.css in the <head>.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="/vendor/ember-animated-outlet.css"/>
    <!-- Add your own stylesheets here  -->
</head>
<body>
    <!-- Add your Handlebars templates here  -->

    <script src="/vendor/jquery.js"></script>
    <script src="/vendor/handlebars.js"></script>
    <script src="/vendor/ember.js"></script>
    <script src="/vendor/ember-animated-outlet.js"></script>
    <!-- Add your own JavaScript files here  -->
</body>
</html>

Use {{animated-outlet}} instead of {{outlet}}

In those outlets where you would like to use animation, use the {{animated-outlet}} helper instead of {{outlet}}, which you would normally use. You need to give the outlet a name. Example:

<h1>Ember Animated Outlet Example</h1>
{{animated-outlet name="main"}}

Use link-to-animated instead of link-to

When you want to use the animations from your Handlebars templates, you can use link-to-animated. The syntax for link-to-animatedis:

{{#link-to-animated "invoices.show" invoice animations="main:slideLeft"}}Show Invoices{{/link-to-animated}}

Where:

  • invoices.show is the route
  • invoice is the model
  • main:slideLeft is the animation

When you are not using a model, the syntax is:

{{#link-to-animated "index" animations="main:fade"}}Introduction{{/link-to-animated}}

Use transitionToAnimated instead of transitionTo

In your JavaScript code where you would normally write transitionTo in your routes to transition to another route, you should use transitionToAnimated instead. transitionToAnimated takes an extra argument, animations, which should be the second argument right after the name of the route to transition to.

animations should be a hash with outlet names (the one you set in {{animated-outlet}}) as keys and effect names as values.

App.ApplicationRoute = Ember.Route.extend({
    showInvoice: function(invoice) {
        this.transitionToAnimated('invoices.show', {main: 'slideLeft'}, invoice);
    }
});

There are *Animated versions of all the different ways you can transition between routes:

Class Normal method Animated method
Ember.Route transitionTo(name, model) transitionToAnimated(name, animations, model)
Ember.Route replaceWith(name, model) replaceWithAnimated(name, animations, model)
Ember.Controller transitionToRoute(name, model) transitionToRouteAnimated(name, animations, model)
Ember.Controller replaceRoute(name, model) replaceRouteAnimated(name, animations, model)

You can also programmatically enqueue an animation for an outlet. A good example is when manually manipulating the history.

App.ApplicationRoute = Ember.Route.extend({
    goBack: function(invoice) {
        Ember.AnimatedContainerView.enqueueAnimations({main: 'slideRight'});
        history.go(-1);
    }
});

You can have as many {{animated-outlet}}s as you would like. In most cases a route transition will only include one animation. But since the animations argument is a hash, you can enqueue multiple animations:

App.ApplicationRoute = Ember.Route.extend({
    showInvoice: function(invoice) {
        this.transitionToAnimated('invoices.show', {main: 'slideLeft', invoice: 'fade'}, invoice);
    }
});

That's all it takes!

List of available effects

You can use the following effects:

Effect name Description
fade The old view will be faded out, revealing the new view underneath it. Uses CSS transitions.
flip Using CSS3 to perform a 3D flip.
slideUp A slide animation where the views slide towards the top side of the screen. Uses CSS transitions.
slideRight A slide animation where both views slide towards the right side of the screen. Uses CSS transitions.
slideDown A slide animation where both views slide towards the bottom side of the screen. Uses CSS transitions.
slideLeft A slide animation where both views slide towards the left side of the screen. Uses CSS transitions.
slideOverUp Same as slideUp, but original view remains in place. Uses CSS transitions.
slideOverRight Same as slideRight, but original view remains in place. Uses CSS transitions.
slideOverDown Same as slideDown, but original view remains in place. Uses CSS transitions.
slideOverLeft Same as slideLeft, but original view remains in place. Uses CSS transitions.

Is your favorite effect missing? Fork the repo, send a pull request, and make other folks happy, too :-)

Tested in

  • OSX
    • Chrome 26
    • Safari 6.0.2
    • Firefox 19
  • iOS
    • Chrome 25
    • Safari 6.0

If you experience issues in any browser, please file an issue.

Things to be aware of

  • All child views of an App.AnimatedContainerView need to be explicitly defined, since the animations only work with non-virtual views. This means that if you have a route called invoices.show and you expect to animate into it, you need to define the view for it: App.InvoicesShowView = Ember.View.extend()
  • The {{animated-outlet}} helper should be contained in an element that has position: relative. The outlet element is automatically absolutely positioned (set to top:0 and left:0) and will automatically size itself to be 100% width and 100% height of the parent.
  • The animations use CSS transitions. There is no fallback for older browsers (yet).
  • Pressing the browser's back button will not perform any animation, unless you tap into the Ember code that handles the popstate/hashchange event.
  • Animations are not executed when transitioning to the same route with a different model. This is due to the way Ember reuses the same DOM element, and will likely not be fixed until animation support lands in Ember core in 1.1.

Building and testing

Setup

To be able to build and test you need to have the following installed:

  • Node.js
  • The NPM package grunt-cli (can be installed via npm install -g grunt-cli, see more here)
  • The NPM package bower (can be installed via npm install -g bower, see more here)

Run bower install and npm install from the project directory to install dependencies.

Building

You can build the project simply by running grunt in your terminal. If you want to let Grunt watch your files, so it automatically builds every time you change something, you can run grunt watch.

The build process will place the files ember-animated-outlet.js, ember-animated-outlet.min.js and ember-animated-outlet.css in the dist/ folder.

Testing

You can run tests by starting the test server:

node tests/server.js

And then open http://localhost:7846/ in your browser.

The test suite uses QUnit.

Todo

  • Include the view's name in "Ember.AnimatedContainerView can only animate non-virtual views. You need to explicitly define your view class"
  • Eliminate the need to concrete views
  • "Freeze" the exiting view, so its content won't be changed by e.g. a controller change.
  • Tap into the browser back button logic in ember to make it use animations too.
  • Option to ignore all animations to allow users who don't like it to disable it.
  • Tests
    • Is there a better way than to use setTimeout to wait for animations to finish?
  • Write missing jsdoc for some classes
  • Documentation of using Ember.AnimatedContainerView programmatically

ember-animated-outlet's People

Contributors

arcreative avatar ghedamat avatar jakecraige avatar kalmanh avatar maerten avatar mjackson avatar niklas avatar olivia avatar sebastianseilund avatar tricknotes avatar zeppelin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-animated-outlet's Issues

bindings are updated in both views when transitioning between child routes with dynamic segments

Hi all,

first I want to thank the developers of this module as it's simply amazing :)

I just started using it in a client app and it feels so nice!

The issue I'm facing now is kind of tricky and I would appreciate
some feedback to see if my intuition is correct
or if I'm simply doing something wrong here...

I've used the demo app as "fiddle", If you look at

http://animated-outlet-dynamic-bug.herokuapp.com/invoices/101

(the code for this example is at ghedamat/ember-animated-outlet-demo@9ae3981)

and you try to navigate between two segment routes (i.e clicking on
one, two or three)
you'll notice that the animations are not working as expected.

I would argue that Ember is updating the bindings before the animation
is started hence the page first updates, and then moves
(note that because of that the transition from one or two to three is
not apparently working as it's a fade)

I'm not sure on what would be a possible way to solve this.
I guess there should be a way to "unbound" the view that is being
removed but no clear idea so far.

Thoughts?

Issues on Android (redraw bug)

Hello

on Android devices ( 4.2 here ) we are experiencing issues with animated-outlet. What works well under iOS, does not under Android:\

  • the view to be faded in is visible during the fade in
  • after the fade in ends, the fade-in-dom element should get replaced by the real one
  • after this happens, the screen is white ( the dom inserted dom elemented seems not to get drawn )
  • now applying anything that forces the browser to redraw that container, shows is up eg 👍

var $var = $('#main-content');
$var.hide();
$var.get(0).offsetHeight;
$var.get(0).style.webkitTransform = 'scale(1)';

eventhough this is (AFAICS) a known webkit redraw bug, this might be something we should implement in ember-animated-outlet

linkToAnimated helper as DIV

When I set the tagName to DIV, then it stops working. I think it's that line of code in the AnimatedLinkView:

var route = this.get('container').lookup('route:' + this.get('namedRoute'));

It somehow returns undefinded.

Can somebody confirm this? (Setting the tagName to a div is straightforward) How can this be fixed?

Edit: I just wanted to mention that my routes have the same parent route. Transitioning to other routes works. Also: Why is it, that Ember's own LinkView calls transitionTo on the router and here we call it on route?

LinkToAnimated?

This is cool stuff! Is there a way to use the animation from when I'm using a linkTo? Is there something like a

{{#linkToAnimated posts.index}}Show the posts{{/linkToAnimated}}

Needed updated documentation.

Was working through an example and determined that this.transitionToRouteAnimated(view, animation, model); was the correct choice for me because I was working within an Ember.Controller. It didn't work.

The animations didn't work until I omitted a model. I suggest that you update documentation saying that model may be omitted.

transition.retry() how to animate?

loginSucceeded: function() {
var attemptedTransition = this.get('session.attemptedTransition');
if (attemptedTransition) {
attemptedTransition.retry();
this.set('session.attemptedTransition', undefined);
} else {
this.transitionToAnimated(Ember.SimpleAuth.routeAfterLogin, {main: 'flip'});
}
},

Handlebars subexpressions (queryParams) not working

I am working with the latest canary using emberjs.com/guides/routing/query-params/ and it seems the animated outlets don't support that yet (or I suppose subexpressions in general, as documented on http://handlebarsjs.com/expressions.html at the very end of the page.)

This is an example:

{#link-to-animated 'videos.index' (query-params coll=nameSlug) class='tag' animations="main:slideDown"}}{{nameCapital}}{{/link-to-animated}}

It throws me the following errors:

Uncaught Error: More context objects were passed than there are dynamic segments for the route: videos.index 

Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.

Uncaught Error: Assertion Failed: Error: Assertion Failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property ...<omitted>...s. 

As soon as I change it to normal link-to everything works fine.

Is there any workaround to render animation when using a new model in the same route?

Hi,

I need to render a slide left animation when transitioning to a new model on the same route - I know you mention this isn't possible in the readme, but is there a workaround (maybe force ember to use the route instead of just changing model for example) or do you have any guidance on directions for possible PR to add that functionality to the plugin?

Many Thanks!

Dan

"Blinking" original outlet content.

Reproduction, tested in Chrome 31, OS X 10.8:

Go to: http://ember-animated-outlet-demo.herokuapp.com/

Paste into your console:

App.__container__.lookup("route:application")._actions.goToInvoices = function() {
  this.transitionToAnimated('invoices', {main: 'slideOverLeft'});
}

Note that the original content on the screen blinks just before the animation begins.

Expected behavior: buttery smooth, no blinking. :)

(I'm not in need of a fix, just drawing your attention to this in case you hadn't noticed.)

link-to-animated always interprets route name argument literally

With link-to I can pass a variable containing the route name:

   {{link-to view.routeName content ...}}

Which takes the value in the view's routeName and uses that.
But with link-to-animated, the given argument is always interpreted as a string, so

   {{link-to-animated view.routeName content ... }}

Throws the error: "Uncaught Error: There is no route named view.routeName"

Is Ember Animated Outlet dead?

Is this project moving forward as I would like to use it in Ember but it doesnt seem to support any recent versions.

I have read the discuss posts etc and seen a few other ways to accomplish this but I like this implementation and was hoping it would be continuing.

translate3d Transforms break Bootstrap Modals

I'm not sure if this is a Bootstrap issue, or an issue here, but the following CSS properties on .ember-animated-container cause Bootstrap modals to break.

-webkit-transform:translate3d(0, 0, 0);
-moz-transform:translate3d(0, 0, 0);
-ms-transform:translate3d(0, 0, 0);
-o-transform:translate3d(0, 0, 0);
transform:translate3d(0, 0, 0);

Animations without position:absolute?

Is it possible to use ember-animated-outlet without an absolute positioned div?

The Problem with that is, that it is almost impossible to have any elements displayed below the animated div (e.g. a footer or a second, non-animated outlet). Also keeping in mind, the height of the animated outlet changes depending on the route you are on.

Or what would currently be the best solution for that?

Communicate animating state to animated views, possibly w/ events

I started playing around with this last night and it's very promising. Thanks for sharing it.

One concern I have is that I would like to animate a view when it is activated or deactivated without using the *-animated/*Animated helpers. I didn't find a way to detect whether that is the case or not.

My first idea is to set a private _isAnimating flag on the old & new views during the transition (just like the animated container view) and let them fire events or add parameters to the event to signal whether or not the transition is animated. I'm unsure if the event should be fired on the view or it's controller. My instincts say it should be fired on the view.

My inspiration here is the Cocoa Touch API which has lifecycle methods on UIViewController with a param to indicate animation. e.g. -viewWillAppear:(BOOL)animated and -viewDidAppear:(BOOL)animated, and similar methods for disappearing.

Does that sound reasonable? I can work on a pull request if there's interest. Or maybe there's a better or different way to achieve the same.

Show part of next/previous view

This is more a question than anything.

I have some kind of tutorial to onboard user, I want to show part of the next/previous views to the user and slide to the next view when the complete the step.

Is there any way to do this with an animated outlet? I guess you need to precreate/prepopulate the views to handle the animation anyway.

Thanks,
Julien.

Screen flickering in Safari on Mac OS

The slide transitions cause flickering in Safari. If I remember correctly this can be solved by using translate3d(X, 0, 0) instead of translateX, which also triggers hardware acceleration on iOS.

p.s. this library is awesome

The didInsertElement method does not work correctly.

App.LayoutView = Ember.View.extend({
    layoutName: 'layout',

    didInsertElement: function() {
        this._super();
        Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
    },

    afterRenderEvent : function() {
       var contentHtml = $('#content').html()
        console.log(contentHtml)
        new IScroll('#content', {
            scrollbars: true,
            mouseWheel: true,
            interactiveScrollbars: true,
            shrinkScrollbars: 'scale',
            fadeScrollbars: true
        }
    }
});

The content Html is the old view html, is there any way to resolve this problem?

'routeArgs' on linkView changed to 'loadedParams' in Ember 1.7/Canary

Hey there! I love ember-animated-outlet and appreciate all the hard work you've put into it. I'm from the Ember release team.

Someone recently opened an issue here: emberjs/ember.js#5283

I did some digging and in the following commit, this computed property changed to loadedParams. Since this is a private API, we probably won't be putting in back in Ember Core. (@machty might reopen the issue on the ember.js repo if that's the case).

This is just a heads up to let you know this private API changed for the next release of Ember.

Thanks!

emberjs/ember.js@f7f7748#diff-25e24f888eb418fd3daaf17d5dae0a69R495

No animation for some transitions

Hi, first of all I'm not sure if I'm doing something wrong here. If you look at the code below, animations work when transitioning from index to page, page to index but don't work for page to page.

After some digging in I found that currentViewWillChange, currentViewDidChange are not fired not sure why.

I'm using emberjs 1.0.0-rc.6.1

My router:

App.ApplicationRoute = Ember.Route.extend({
  events: {
    showHome: function() {
      this.transitionToAnimated('index', {main: 'slideRight'})
    },
    showPage: function(page) {
      this.transitionToAnimated('page', {main: 'slideLeft'}, page);
    },

Part of the view:

<ul class='nav'>
  <li><a {{action showHome}}>HOME</a></li>
  {{#each page in controller}}
    {{#view App.MenuItemView}}
      <a {{action showPage page}}> {{page.title}} </a>
    {{/view}}
  {{/each}}
</ul>

Animations works only with visited routes

In my Ember App i'm experimenting this behaviour: the linkToAnimated works only if the route is already been visited it works, if not it doesn't.

I mean, that initially nothing works, but if i manually type the url of a page in the browser, than the link to that route start to work...

How to precompile animated-outlet enbled handlebar template to js file?

Hi, nice work!

I got a compile error when I using ember-animated-outlet within a generator-ember project.

Here is source

 {{#each item in controller}}
     <li class="list-group-item">{{#link-to-animated "yellow" animations="main:slideLeft" item}}{{item}}{{/link-to-animated}}</li>
 {{/each}}

When I run grunt serve, grunt run task to compile handlebar template into js file.

Here goes output.

Running "concurrent:server" (concurrent) task
    Warning: Running "emberTemplates:dist" (emberTemplates) task
    >> Error: Parse error on line 23:
    >> ...main:slideLeft" item}}{{item}}{{/link-to
    >> -----------------------^
    >> Expecting 'EQUALS', got 'CLOSE'
    Warning: Ember Handlebars failed to compile app/templates/application.hbs. Use --force to continue.

    Aborted due to warnings. Use --force to continue.

        Aborted due to warnings.

So, Is there any way to precompile animated-outlet enbled handlebar template to js file?

LIkely autoruns after animations

Extra autoruns are likely causing some perf issues specially on older devices.

We are going to experiment with better async for autoruns to prevent this issue, but currently (especially in mobile browsers), wrapping the following callback(s) in Ember.run will likely improve some situations.

External templates with Handlebars fail

Presumably it works fine with embedded templates in script tags, but not standalone. Is there a way of plumbing in the outlet extensions so that I can compile the templates with Grunt?

Uncaught Error: Handlebars error: Could not find property 'linkToAnimated' on object <(generated stories controller):ember298>.

Define your own outlet view to define different animations

I have tried to animate outlet with a different approach.

Any opinions emberjs/ember.js#2542

Now, for example you could build custom animated views as:

  <div id="content">
    {{outlet view=App.FadeView}}
  </div>
var get = Ember.get, set = Ember.set;
App.FadeView = Ember.ContainerView.extend({

  classNames: ['animated-outlet'],

  outletName: null,
  outletContent: null,

  init: function () {
    this._super();
    this._outletContentAfter();
  },

  _outletContentAfter: Em.observer(function() {

    var newContent = get(this, 'outletContent');
    if (newContent) {

      var newView = Em.ContainerView.create({

        classNames: ['fade-container'],
        classNameBindings: ['isOut'],
        isOut: false,

        currentView: newContent,
        transitionEnd: function() {
          this.removeFromParent();
        }
      });

      var oldView = this.objectAt(0);
      if (oldView) {
        set(oldView, 'isOut', true);
      }
      this.pushObject(newView);
    }
  }, 'outletContent')

});
.fade-container {
  z-index: 1;
  opacity: 1;
  transition: opacity 1s ease-in-out;
}

.fade-container.is-out {
  z-index: 2;
  opacity: 0;

}

De-sassify

First off, very cool stuff! Love to see a fleshed out solution to a problem that everyones trying to solve the right way.

I'm of the mindset though that we shouldn't have a dependency on CSS (much less sass). Lots of jQuery-esque plugins do have a CSS component, but that's usually because that CSS is crossing into aesthetic territory, whereas something like an outlet fade/slide/whatever should be programmatically guaranteed and managed by the code.

Any thoughts on this? I've taken a similar approach with this work in progress, leaving CSS only to describe what the node looks like, but handling the zooming, transitions, etc., all in code.

Properties on undefined object / "More context objects" issues

The linkToAnimated handlebars helper seems to be passing along less arguments than it should to create the link. But when fixing that, the actual click handler gets more arguments than it expects ("More context objects…").

I think this is the fix, works for both {{#linkToAnimated 'mymodel' this …}} and {{#linkToAnimated 'mymodel' myvariable …}}: https://gist.github.com/natevw/b959531b141522c178e4

[sorry for the lame patch instead of a pull request, came out of some quick debugging for a client]

port to ember1.0

Hi all,

I recently ported a simple app where I'm using ember animated outlet to 1.0

I've encountered some small problems as the {{link-to}} behavior changed with the last releases.

As I've been able to get the animated outlet working again in my app with few changes I'm currently working on porting the whole plugin to 1.0 altogether,

If you agree I'll likely open a PR as soon as I'm at a decent state and ask for some feedback..

A lot of the changes are minor tweaks to the tests, but I would love some input :)

Thanks!

Error Using linkToAnimated

I am getting a handlebars error with the default startup Ember bundle. Upon replacing my linkTo with linkToAnimated I get:

Uncaught Error: Handlebars error: Could not find property 'linkToAnimated' on object <(generated application controller):ember219>.

Ember 1.10

Any chance to get this running with the latest Ember version?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.