Toura/mulberry — Issue #301: Built-in transitions
Author: mrdanimal
Created: 2012-01-26 17:09:45+00:00
State: open

We have a few built-in animations, but they are mostly one-off implementations, and there is no clear API for developers to customize them or apply them to arbitrary elements within their application. Other frameworks generally provide this functionality, so developers expect this to be part of a mobile framework, and this seems like a blank spot in our functionality that needs to be filled in. The common animations I'm thinking of are:

* slide-in
* slide-over
* pop-out
* fade-in
* fade-out

I want to avoid handling animations in Javascript and keep the separation between application logic and presentation logic as clear as possible. The application should still be able to simply say "show this, hide that", etc, and not care about the implementation. So I propose we create a set of Sass mixins that can be applied to any Screen, Region, or Component (and possibly Page).

These all inherit from `toura._View` so they expose hide/show methods that simply toggle the class 'hidden' on the element. The simplest implementation of a transition mixin would override the meaning of this class.

Example implementation:

```scss
@mixin fade($class-name: hidden) {
opacity: 1;
-webkit-transition: opacity .3s ease-in;

&.#{$class-name} {
opacity: 0;
display: block !important;
}
}
```

Example usage:

```scss
.component.detail-title {
@include fade(hidden);
}
```

I have a quick implementation I hacked up for the Boston presentation (https://github.com/mrdanimal/mulberry/tree/boston-presentation-fades). Go to the puppies page -> tap on the image -> within the detail screen, tap on the image to display the header and footer. The header should fade in and out nicely.

The exact naming convention and syntax is TBD. We may want to pass other parameters to determine speed, direction, etc.

More complex sliding animations require more than a single classname to be toggled. For example, within `toura.containers._Viewport` we run through a two step sequence: 'pre-slide', then either 'slide-left' or 'slide-right'. This could be handled in a generic way within the `_View#hide` and `_View#show` methods ('step-1', 'step-2', 'step-' that will give the mixins as many hooks they need.

TBD:
So far I've been able to get animations to work on elements with `display: block`, but not with `display: -webkit-box`. The animations simply don't occur. It's not clear what the issue is -- whether it's 1) a problem inherent with flex-box elements, or 2) with my implementation of the animations. I'm leaning towards #2. I haven't spent all that much time digging into it, but I believe this is a solvable problem.

The sliding animations for pages also deals with DOM setup/teardown. We currently assume that within a page, the entire DOM for all screens, regions, and components is all created at once, so transitions that apply to them can be simpler. This may mean we leave page transitions alone for now, so that we don't have to deal with the issues of dealing with `webkitAnimationEnd` event handling. But, it might be trivial deal this within the `_View#show` and `_View#hide` though, and screen/region/component transitions just wouldn't take advantage of it. Once I get deeper into the implementation, it'll be clearer which path to take.