Re: transitions vs. animations

On Apr 5, 2010, at 10:39 AM, Tab Atkins Jr. wrote:

> ...
> There are some places where we can change things, though.  We should
> be able to fully address #1 without relying on difficult hacks
> (anything requiring :not(:hover) as a basic mechanism is screwed up
> ^_^).  We should also be able to fully address #2.  I actually think
> we may be able to do this by making Transitions and Animations
> slightly *more* different.  Here's a sketch of how they would work:
> 
> /* In this example, the transition-property value (and its place in
> the shorthand) also take a function defining a set of keyframes to
> execute when a given property transitions. */
> .slider {
>  left: 0;
>  transition: left 1s, play(left, bounce) 1s;
> }

Why are you specifying a property in the play() function? It's encoded in the @keyframes rule, right? I think it would be a bad idea to try to pick out a single property animation from an @keyframes rule where multiple properties are specified. Also, is your new notation intended to avoid the need for an animation property specification? If so, I think that just makes things more confusing. Rewriting this as:

    transition: left 1s;
    animation: bounce 1s;

seems much more clear.

> 
> .slider:hover {
>  left: 400px;
> }
> 
> /* In this example, there is an animation run when you enter a state,
> while you are in the state (delayed by 1s, so as to wait until all
> transitions and play-ins are done), and when you leave the state.
> Also some transitions for good measure. */
> .tooltip {
>  opacity: 0;
>  display: none;
>  transition: opacity 1s, display 1s step-start;
> }
> 
> .tooltip.show {
>  opacity: 100%;
>  display: block;
>  play-in: rainbow 1s;
>  play-during: throb 5s 1s;
>  play-out: rainbow reverse 1s;
> }
> 
> 
> The changes are relatively minor here:
> 
> 1. Transition-property takes another value, which specifies a
> (property, keyframe) pair.
> 
> 2. Three new shorthand properties: play-in, play-during, and play-out.
> Play-in specifies animations to be run when the element begins to
> match the given selector.  Play-out plays when the element stops
> matching.  Play-during plays infinitely while the element matches.
> 
> 2. "infinite" is no longer a possible animation duration.  Instead,
> all keyframes given for the play-during property are assumed to run
> infinitely (and play-during doesn't accept an animation-play-count),
> and all keyframes given for the play-in and play-out properties are
> assumed to be finite.  Play-during simply doesn't *have* a play-count
> entry.

So if I want to repeat an animation 3 times (to get people to notice but not be too annoying) I would need to use JS or something? I don't think iteration-count is too complex a concept that it should be eradicated.

> 
> 3. Any place that accepts a keyframe must also accept a keyframe
> followed by the 'reverse' keyword, indicating that the keyframes
> should be run backwards.
> 
> 4. The operation of (and likely names of) the individual animation
> properties will have to be tweaked somewhat.  Rather than a single
> "animation" shorthand with "animation-*" subproperties, you'll have
> three shorthands and three separate groups of subproperties
> (play-in-name, play-during-delay, etc.).

You're suggesting 4 changes, each of which addresses a different issue that has been brought up about animations, to wit:

1) Combining transitions and animations

I think this is a generally bad idea and only leads (as we've seen in the examples given) to a more confusing design.


2) Support for looping animations with lead-in

This is an interesting issue that we should discuss as a separate topic.


3) Getting rid of iteration-count (not an issue I had ever heard before)

As I said, I don't think iteration-count adds much complexity so I don't think it should be removed.


4) Reversing transitions, although you are applying this to keyframe animations, another issue I had never heard before.

There has been discussion about this before. It's a useful issue to discuss, but not easy to resolve.


Generally, I'd much rather see these discussed as separate issues. Doing it like this makes it hard to avoid confusion. But I've given my opinions anyway :-)

> 
> 
> What's left to define:
> 
> 1. How a keyframe set takes default values when played in a
> transition.  Obviously 100% should default to the end-state.  What
> about times in the middle?  Basically, I'd like to be able to *either*
> do a simple transition taking a property (say, left) from value A to
> value B, or do a complex transition using keyframes to take the
> property from value A to value B with a complex path in between.  I'm
> not sure what's ideal here yet.

In discussing transitions with keyframes, my opinion has always been that this is an advanced enough technique that it's reasonable to get JavaScript involved to generate keyframes and kickoff an animation.

> 
> 2. How a keyframe-based transition and a standard transition interact
> on the same element.  We may want to say that they *can't* interact,
> and that transitioning both "left" and "play(left, bounce)" brings the
> same conflicts that transitioning "left" twice does, and so we resolve
> them in the same way (last one specified wins).  This would mean that
> in my first example I'd have to remove the "left 1s" bit and specify
> what to do with "left" in the bounce keyframes.  Alternately, since
> you can statically examine keyframes and see what properties are
> manipulated by one, perhaps just say that if a keyframe manipulates a
> property, it overrides any manipulation that would be done by earlier
> keyframes or transitions.  This is likely better, as it handles being
> able to hook multiple keyframes to the same property elegantly, and
> also fits with the idea that a plain transition is an
> instantaneously-produced trivial keyframe.

The current spec (which I obviously favor :-) already has well-defined rules for how animations override transitions. I think that model is sufficient.

> 
> 3. How animations of the various types (in, out, during) interact with
> eachother.  Does during always beat in?  Out beat during?  What about
> when you fill any of these?  I think this can be resolved fairly
> easily, if perhaps arbitrarily.
> 

Again, I think the current model presents a sufficient declarative syntax. More complex animations can (and I think should) be done with JavaScript intervention.

> 
> 
> A final use-case that hasn't been addressed is "one-shot" animations,
> which are useful for javascript.  Say you want to throb a button every
> time someone clicks on it.  This is an animation not tied to a state
> or a property value change, but rather to an action or event
> originating from elsewhere.  These would basically just be triggered
> by javascript.  My initial thought is to just do them as a normal
> animation tied to a class, and in js just quickly add and remove the
> class that triggers it.  This doesn't work, though, as removing an
> animation (or equivalently, making an element no longer match a
> selector providing an animation) stops the animation (I think?).  Can
> I just listen for the animationend event and remove the class then?
> This doesn't help me if I want to restart a running animation if the
> user clicks again, though.  Being able to directly trigger an
> animation through JS would be somewhat useful for this sort of thing.
> I suppose this can wait a bit, though.

Why all that complexity when iteration-count can handle it without any JS needed? Maybe I missing some other issues with iteration-count that make it insufficient?

-----
~Chris
cmarrin@apple.com

Received on Monday, 5 April 2010 21:38:58 UTC