

React Tween State - tosh
https://github.com/chenglou/react-tween-state

======
peterhunt
I worked on this with Cheng Lou a while back.

Just to preemptively address a criticism: yes, this does frame-by-frame
animation in JavaScript, eschewing CSS animations. There are tricks you can
use (similar to what iScroll does or did) that can leverage CSS animation, but
it's likely that these won't be necessary or worth it.

The reason for this is that to truly solve animation you need to address
continuous touch gestures that seamlessly transition into and out of
animations (i.e. flick something, catch it with your finger mid-animation,
zoom it while rotating it, then let go and have it animate out). The only way
to do this is to use a programming language that can respond to events. Said
another way, you should never think of animations discretely (i.e. "slide in
from left") if you're thinking about building touch-based app. It won't feel
natural.

My old employer has a great video about this. Detailed discussion starts here
(there are two speakers that talk about it):
[http://youtu.be/OiY1cheLpmI?t=25m29s](http://youtu.be/OiY1cheLpmI?t=25m29s)

~~~
seanmcdirmid
> Said another way, you should never think of animations discretely (i.e.
> "slide in from left") if you're thinking about building touch-based app. It
> won't feel natural.

That kind of goes against thinking of animation as tweens. Instead, you want
something more physics based that can respond to touch in real time yet remain
controllable enough for user interface usage; e.g. verlet and/or inverse
kinematics.

~~~
peterhunt
Absolutely agree.

react-tween-state is less about the specific tweening function and more about
the idea of a numeric value changing over time that can be interrupted.
Instead of the standard Penner tweening functions you could just as easily
substitute in some physics (like [https://github.com/facebook/rebound-
js](https://github.com/facebook/rebound-js)). And with the DESTRUCTIVE mode of
react-tween-state you can seamlessly transition between direct manipulation
mode and inertia mode.

There's still a lot to do here, but I am pretty positive on the overall
approach.

~~~
seanmcdirmid
Reading the github page, though, this is really about tweening with no mention
of interruption. However, using Verlet (not Newtonian like rebound-js!) you
can easily combine both approaches since Verlet allows you to mess with a
position directly (velocity is implicit in position deltas, so really stable
although less accurate).

I wrote a rejected paper about this a few years ago; it might be useful as a
reference:

[http://research.microsoft.com/pubs/191705/uiphysics09.pdf](http://research.microsoft.com/pubs/191705/uiphysics09.pdf)

I wrote that when I was doing a lot of work with WPF, whose animation/data
binding system is fairly similar to what is being explored in Javascript today
(with frameworks like React). But beyond data binding and canned animations, I
think physics is the next step.

~~~
dandelany
Re: interruption, from the docs:

> stackBehavior (default: tweenState.stackBehavior.ADDITIVE). Subsequent
> tweening to the same state value will be stacked (added together). This
> gives a smooth tweening effect that is iOS 8's new default... The other
> option is tweenState.stackBehavior.DESTRUCTIVE, which replaces all current
> animations of that state value by this new one.

So DESTRUCTIVE is what allows interruption.

~~~
seanmcdirmid
This is not much different from WPF's animation support, and I don't think it
really helps. The interruptions are still not very natural looking. It was
definitely useless for Surface (the table, not the tablet) when I was doing UX
prototypes for it.

~~~
chenglou
Additive is a better "interruption" in a lot of cases from what I've seen.
Destructive was added after the fact for completeness. What do you think?

------
chenglou
What a pleasant surprise =).

What Pete said
([https://news.ycombinator.com/item?id=8670147](https://news.ycombinator.com/item?id=8670147))
is true. I'll just address the issue of interruption here that people asked me
about more than once: one of th major goals of this library is to enable
interruptible and additive animation (a-la ios). There's currently no easy way
to do this with CSS(1). Whether this by default uses a physics engine or not
is not important; it sure can, but I decided to keep it simple. And no, in all
likelihood this tiny lib doesn't beat the performance of other animation-
specific libraries or the GPU accelerated CSS animations, but I was aiming for
a good API first and foremost. I'll optimize accordingly.

(Also, check out my post here on the other problem with animation in gneneral:
[https://news.ycombinator.com/item?id=8561824](https://news.ycombinator.com/item?id=8561824))

(1) Imo, the danger of CSS is that it tends to get us 80% of the way there
with 20% of the effort, while not being able to provide us with the power of
achieving the last 20% at all.

------
doomlaser
I think it's crazy how one guy's static interpolation curves
([http://www.robertpenner.com/easing/](http://www.robertpenner.com/easing/))
keep showing up verbatim in an ever increasing array of tweening frameworks
over a decade since he first posted them.

These interpolation curves can be nice in a pinch, but like I said before, the
curves the curves are static, and so you can run into problems if you want to
interrupt an action with another, or layer multiple tweens together.

One particularly effective way to get natural eased motion is to use a
function that outputs something like the movement of a simple damped harmonic
spring. With a system like this, you specify a target position relative to the
current position, the sponginess of the spring, and the speed of which it
oscillates. This can give you very natural results and feels a lot closer to a
real physical system than a lot of these interpolation curves (EaseInOutExp,
etc).

Here's some code for a damped spring system that can work really well as an
alternative to predefined tween curves in user interfaces and games:
[http://www.ryanjuckett.com/programming/damped-
springs/](http://www.ryanjuckett.com/programming/damped-springs/)

And for more non-Penner interpolation alternatives, check out:
[http://sol.gfxile.net/interpolation/](http://sol.gfxile.net/interpolation/)

~~~
calebreach
I agree — transitions are a really bad way to think about animations. Another
approach is to think of an interpolation curve as the step response to an LTI
filter. This approach lets you turn any interpolation curve into a FIR filter
that can handle interrupted transitions seamlessly.

~~~
chenglou
Can you elaborate on this?

------
jimeuxx
I started learning React recently. I really like the way the code is laid out
and I enjoy writing it so far, but trying to use jQuery animations with React
seems to pretty much ruin that neatness and readability.

I did try the experimental CSSTransitionGroup, but it has some serious bugs,
and didn't seem designed for in-place transitions. It's hard to find a good
number of examples at this point though.

I came across the React Tween State GitHub page while googling, so I'll have
to try it out. If I can get comfortable with basic animations with React, I
think I'll be using it a lot more.

------
jbhatab
Great library, just made a video on it if anyone is interested in setting it
up.

[https://www.youtube.com/watch?v=9cY8-xCfU9E](https://www.youtube.com/watch?v=9cY8-xCfU9E)

------
cpayne
I don't understand - can someone explain???

~~~
tosh
React provides a very elegant way to update the DOM by deriving it from your
application's state.

Unfortunately how animations of UI elements should be done in this model isn't
as clear and elegant yet (as far as I understand).

This GitHub repository shows one way of how animations could/can be done in
React in a simple way.

------
acdlite
The way I've been doing UI animation in React so far is by checking for state
changes in `componentDidUpdate` and animating with Velocity.js, which works
surprisingly well.

This appeals to me way more. Only concern is performance.

------
rpwverheij
Awesome, just what I needed for a react project I'm starting on. thank you.

