# The Observable Future of Animations

Canonical: https://davidk.dev/talks/the-observable-future-of-animations/
Video: https://www.youtube.com/watch?v=jW4nzdVU6hk
Speaker: David Khourshid (@DavidKPiano), creator of XState
Type: Conference talk · Event: DevFest Florida 2017 · Year: 2017 · Duration: 30:47 · Views: 104 (as of 2026-10-19)
Topics: Reactive programming, CSS & animation

## Summary
UI animations can be an incredible asset to the user experience, but the handoff between prototyping complex motion interactions to implementing them in code is not always the smoothest transition. That's what Google's new Material Motion library aims to solve. In this talk, we'll discuss how thinking about animations as reactive streams of data can make even the most complex animations easy to de

## Key takeaways (quoted from the transcript)
- About the observable future of animations, this is sort of a play on words. (0:00)
- We realized that animations are just a function of state and time, and this states could include what happens, you know, when new actions come in, so actions change states and do the time action animations move over time. (16:00)
- I guess you could just copy the code from the mouse move and put in the touch move. (18:00)
- RX CSS give it that mouse observable, which emits X and Y values, and then I could just move things using those values. (25:00)
- My goal is to create a visual interface for editing reactive animations, not just static animations, but animations that depend on, you know, just a number of other values. (30:00)

## Chapters
- 0:00 Introduction
- 6:00 We have collections of values, and we have values…
- 11:00 You know, I can't just pre-programmed three rooms to four rings…
- 13:00 We have operators such as math…
- 16:00 The second thing I'm going to do is I'm going to…
- 28:00 My goal is to create a visual interface for editing reactive…

## Transcript
[0:00] My name is David Corr seed and I'm gonna be talking to you today. About the observable future of animations, this is sort of a play on words. It's observable in the fact that it's what we could tell right now is going to be happening regarding the future of animations. But also we're going to be talking about some reactive concepts, such as observables and things like that. So, first of all, how many of you are actually doing in the nations, in your applications, your projects, and so what?

[0:00] What, libraries or frameworks are using? Just show that, what, which one? Angular is not an animation framework, but that's okay, okay, React animations Angular. We have G SAP velocity. CSS is sort of, you know, the default one, and also really small library called Anime, which personally I like. And this is a current state of animations where we have a start points and we have an end point, and then we have the animation that plays from the starts to the end.

[1:00] However, when you think about web experiences and interfaces, you find that things don't happen. Like from point A to point B. That the user could always do something different and can always change the behavior of an application dynamically. And so when things move on, you know. And in applications such as when you're swiping from screen to screen. It's not an A to B animation, it's more like a whatever is happening right now.

[1:00] And so last night I was reading something called the future of interaction design. I don't know how many of you have heard of Breath Viktor, but he has a really good video called Inventing on principle. And in this video he talks about what the future of user interfaces could be like. Because he's, frankly, a guy who is just not accepting of the status quo of how user interfaces are right now. Even with a really cool, you know, iPad and touch interfaces.

[2:00] Essentially, we're just moving our finger on a glass and we can't feel any of the things that are really under that class. And so, you know, he's sort of thinking of a future where things are more like real life. And so that's why I want to talk about today, because real life, according to Newton, and pretty much. Everything else is based on the fact that for every action we do, and these accidents could be anything like, you know, taps, clicks, events, just anything you do, and anything you react to as well.

[2:00] Every single one of these actions causes a reaction, but these reactions are also actions in themselves. So these reactions could cause reactions upon themselves, and a reaction could cause, you know, reactions on, you know, many different things. And so I was thinking a while ago, how does this translate to animations, especially when we're talking about user interfaces? And I found the paper written in 1997 about functional reactive animations, that sort of talks about this exact same topic, so let's get into it.

[3:00] What are reactive animations exactly? According to this paper, a reactive animation is one that involves discrete changes based on events that could be continuous or discrete themselves. And just to give you a little bit refresher, discrete means something that happens at distinct moments of time. Where you could actually measure it, continuous is something that is continuously happening, so you can't really measure it with, you know, any sort of digital precision. So it's sort of the difference between digital and analog.

[4:00] And so we could take those continuous events that could happen at any time and have discrete reactions based on those. And so in this paper, he also says that. By allowing programmers such as you all to express the what of an interactive animation, which you know it's really a declarative concept, one can hope to, on it, automate the how of its presentation. And so the reason that I quote these two grass is because they're the only two I understood in the entire paper, but I encourage you to read it.

[4:00] Now. You might be asking, Okay, this? You know? This idea sounds cool, but why do we want to do interactive, reactive animations well on the web? The simple answer is because native is already doing it. Honestly, they're kicking our asses. We have Android/IOS, just with these really smooth animations, these are not exactly real-life animations. There are more concepts. But a native developer can easily see that and be like, yeah, this is what our app would look like.

[5:00] I mean, you look at Snapchat and or even Instagram, all of these apps have some sort of interactivity. To them, where? When you move your finger across the screen, when you do something, even with the new iPhone, when you stare at it, or something that it actually reacts to what you're doing in real time. And so with the addition of physics and all of that, it becomes a really engaging experience for the user.

[5:00] And that's extremely important because we want to model our user interface animations as close to real life as possible. And so that's why I'd like to go and dribble and look at all of these design concepts, because these, these visions, they're. They might not be ideal, they might not be. This is exactly what we have to do.

[6:00] But to me, there's parts that you could pick from that are a step in the right direction. So let's get into this whole reactive thing. How many of you have used RxJS before? Okay, so about half of you are going to be bored for the next five minutes, but that's okay. In JavaScript, in pretty much any programming language, and that's important because this applies to pretty much every programming language. We have values.

[6:00] These are single, just items of data, such as the number of boolean, a string, even the single object can be considered just a single value. Now, what happens when this value comes over time? Well, that's a promise. Or in other languages, are called futures or tasks, but they're that single value that happens after a set amount of time, and they could never happen. You know, you might get an error, or they could happen immediately, but the fact is that, you know, you're going to get it eventually.

[7:00] Now also, we have the concept of collections or a race. And so when the REA is just a bunch of these single values. And this is pretty much where I would say, like 80, 90 percent of programming knowledge stops. Like, we have these future values, right? We have collections of values, and we have values, and our programs are made up of all these. And if we need to do anything crazier with time, then we'll just chain promises together, or we'll do callbacks passing back and forth.

[7:00] But there's a fourth abstraction that combines, you know, this idea of collections and getting values over time, and so that's an observable and. So with an observable, we get each item after a certain period of time. Again. They could happen immediately, they could happen over, you know, seconds or minutes, or even years. And observables can, you know, they could error out, they get completes. But observables are collections of values that are time-based async, they're immutable - so if you have a stream of values, you can't really change that stream of values.

[8:00] Because you know, it happens over time, right? So you know, you get a value, and that value is exactly the value that occurred. You can't go back in time and change stuff. If we could, then we would have done it a year ago. I'm sorry I shouldn't have said that. And they can be subscribed to as well. Observables can do one of three things they could complete, which means every single one of the items has been emitted.

[8:00] They can be indefinite, which means that things are just going to keep being emitted from the observable. Or they can produce an error, and so with the completion and errors, observables just die. And we can use RxJS, which is a very popular library based on the reactive ex extensions, to create these observables, and this isn't something new. Reactive EX has been around for about half a decade, since 2009. So this is something that's been used in many languages and is definitely a really well developed library and set of standards.

[9:00] So if you do npm install' RxJS save and just import Arcs from Arcs J/S, there you go. That's all you have to do to start off and start using RxJS in your project. If you use Angular, you know that the latest version, Mingler, which is 11. I don't know. Angular loves reactive extensions, and it uses it in a lot of places. I, I do not. I don't love Angular, I use React, but you know, I could see that, you know, using RxJS makes developing an Angular probably a lot better than you know.

[10:00] Passing callbacks, having to listen for promises, having the chain promises together, it's just a simpler abstraction. So it's you create an observable. All we have to do is pass an observer to this arcs observable creates, and this observer can be passed the next value. And so for this, I'm just creating an. Interval in which I push values every second. Now, the beauty of arcs J/S is that. All of this and all the most common things that you might want to do.

[10:00] To create an observable can be abstracted in a single line, for example, this one can just be observable interval of 1000 as in milliseconds. You could also create an observable from an event, which is also a very common use case. And so, for example, this one. I tell it. I just want to capture all the mouse moves that happen on the body.

[11:00] And we're gonna see how this is useful for animations in a minute. But we also have something called operators, which operate on these values, such as you would offer Ray. You have liked things like map and filter and reduce. And so we could take, for example, the X and Y values of the mouse as it moves across the screen. All right, blowing the demo. So as a quick example, I made this responsive house, where if you move the dial, the house just grows and shrinks.

[11:00] And I wanted to listen to inputs from this range over here, so over here, I'm doing our Excel observable dot from a from events range input. I'm mapping it to the values that are emitted from that. And I'm gonna start with 6, because actually starting with the big house is a bad idea, but I started with 6 anyway. And so I could subscribe to that observable and in my update function. That's where I'm setting all this data about how many rooms there are, and that's how I control it with CSS.

[12:00] And so the reason that I did it that way, and I didn't do it by hard coding every single state was. Because if I wanted to jump from six rooms to three rooms, I wanted it to be able to do it smoothly. And so, you know, I can't just pre-programmed three rooms to four rings than four to five, etc. So you could also create observables from events patterns when you're using API's that aren't really exactly native events, and this is extremely useful.

[12:00] I'm using something called Hammer J/S, which is a very powerful tool for abstracting things like touches, pinches, pans, zooms, things like that thing. Like any interactions that happen with your finger and of.

[13:00] Course this doesn't operate on, you know, normal events, it has this cost custom on. And then you pass it a string of things you want to listen to, and then you just give it to the handler. Back to our X, and then our X will make an observable that emits values for every single one of these events emitted. Now. The great thing about this is that typically when we're creating reactive anim, our so-called reactive animations.

[13:00] Right now, if we don't do this, then we're doing all the updating inside of this handler. We're like, okay, once we get one of these, then I want to start moving something or doing something. But that's sort of the abstracted equivalents of hard-coding. Instead of telling my app what to do in an imperative sense, like, once I get an events, start moving this. Instead, I want to say, just tell me when I get events, I'll handle it later.

[13:00] And so that's what RxJS does. So, we have operators such as math, the same that you would see in arrays. Except, of course, you can see that these happen over time. And so we have filters as well, and this makes it really intuitive to work with arcs jeaious for some of the operators. But because we're working over time, we have other things that we can't really do with arrays, such as, you know, delaying by a hundred milliseconds.

[14:00] And then one of my favorite operators is Scan, which sort of acts like a Redux reducer. All it does is it takes a previous value and the current value, and it combines it together and then that's what it emits. So, for example, this one is taking the previous value, which is the number, the next value, which is another number, adding them together. So one plus one is two, I don't know why happening about that, two plus one is three, three plus five is eight and so on, and so you can see.

[15:00] This function could be used as an updating function which observes actions that happen from anywhere and is able to update the state of your application. In a very declarative, non imperative, fully functional way. That was a lot of buzzwords, but you know, hopefully you get the idea. It could also operate on multiple streams, just like you could operate. You know, I raise. I guess. You could do multiple operations on multiple arrays.

[15:00] But, for example, I'm taking two streams of data and I'm merging them together into a single stream of data. We'll see how that's useful in a minute. But to help visualize this, there's also what's called marble diagrams. Honestly, I would have called it observables, but you could. You could drag these around and you could visualize in real time what each of these operators are doing in. So this comes really in handy, even when you're dealing with more advanced operators, such as with latest.

[16:00] From distinct until changed stuff like that.

[16:00] So let's rethink, you know what animations are, instead of animations being a set of sequences from point A to point B. We realized that animations are just a function of state and time, and this states could include what happens, you know, when new actions come in, so actions change states and do the time action animations move over time. So we're gonna do a little example here. And so first I'm starting with this.

[16:00] Here's my goal I want to move this goats picture and I want to rotate it with my mouse. So the first thing I'm going to do is I'm going to use the from event and take the document. And just measure which position my mouse is in whenever I move my mouse. And you can see, that's pretty straightforward with RxJS and observables, so instead of, you know, putting it directly to the screen whenever the events happens.

[17:00] I'm instead going to create it an observable and subscribe to it whenever it gives me a value, and in that subscription, that's when I'm gonna put it on the screen. So the second thing I'm going to do is I'm going to take that exact same mouse move observable, and I'm going to move this photo when I move my mouse. And so the difference here is, instead of just putting the numbers on the in the SUBSCRIBE function.

[17:00] I'm calculating how far the mouse is from the center and then I'm rotating it accordingly. So I would rotate X by, you know, if it's going to the left, you rotate to the left, it's going to the right, you rotated to the right, and same with top down. Now I want to make this. Work on touch devices too, so we could use another operator that we talked about, which is merge. And so, I have two operators or two observables now, one for mouse moves and one for touch moves.

[18:00] I want to combine those two, and I want you to, you know, take a moment and think about how would you do this without using observables? I mean, we could attach the movement of this directly to where you're moving your mouse. But then if someone says, Hey, I want to make this work on touch devices - then you're screwed. You're like, how are you going to? I guess you could just copy the code from the mouse move and put in the touch move.

[18:00] But then, you know, your co-workers will be like, you know, this isn't dry or whatever, so I'm just doing this. I'm combining these moves, the mouse moves and touch moves using our X dot observable dot merge. And then, just as proof that this works now, either using my mouse or touching it moves exactly like I wanted to. Well, almost exactly. There's something else I wants to do. The motion that I'm using when moving my mouse, or, you know, moving my finger, is very rigid.

[19:00] When I stop my finger, the animation stops, and personally I don't like that. You know, things don't stop immediately in real life, you know, they just keep going, they slow down to a stop. You know, Newton's second, third, one of those laws. So what I'm gonna do is I'm gonna create an animation frame observable, which, you know, of course, when you're doing animations, you want to have everything happen every 16 points, six-six milliseconds, or basically every time your screen refreshes.

[20:00] And so one cool trick I learned from Ben Lesh, who actually works at Google and hire me because I'm remote, is. You could use interval, you know of zero, and then you could add a scheduler, a scheduler. Sort of a more advanced concept with arcs, J/s. But basically, it says, I'm going to tell you when to emit the values. So instead of emitting it immediately, it sort of like it bounced out of the club.

[20:00] Who, you know, lets everyone in, just like, you know, every thirty seconds or so, instead just letting everyone in immediately. And so this is. Gonna get us exactly the same behavior that we want. And then I'm gonna use this operator dot with latest from so to understand what this with latest from operator is. All it does is it takes from a second observable. It's going to take that value and sort of carry it along with its original values.

[21:00] So the top one, you can sort of imagine that as the animation frames, the bottom one can be. Our mouse moves, our touch moves, and so with latest, from is going to repeat each of those values, which is exactly what we want. And here's why I wants to do what's called, as I found out, LARPing, or linear interpolation. This is a really common technique, especially in video game developments, where you could create smooth animation from point A to point B.

[21:00] In in actually a very simple way. The way it works is that we're taking the Delta, the difference between where you're starting and where you're ending, and then we're dividing it in a fraction. And so instead of going immediately from A to B, you go smoothly from A to B. So just to demonstrate that, let's say that we have two values, 200 and 300, and so the Delta is what 100, right?

[21:00] Let's say that we want to, you know? Move it only a tenth of the way each time, so we take that Delta, multiply it by a tenth and so that's 10. We add that to our starting value, which is 200, and so now we see that it moved a little bit closer. And then lather, rinse, repeat. You're going to get a smooth motion that goes from point A to point B, and that depends on, you know, the numbers that you choose.

[22:00] So one, obviously, if you do one, that's going to go from point A to point B immediately. 0.5 lil little slower and points to. The slower you get, the slower it's going to move there. Does this concept sort of make sense? EARNG Okay, awesome, because I did it in colors. For whatever reason, that's actually harder to understand. So anyway, I'm gonna use this loop function and I'm going to use Scan in order to update my values.

[22:00] So remember, what Scan does is it takes the original state, and then it takes, you know? Whatever happens, like any actions that are emitted, which are our mouse, moves, and it moves, or it updates the states based on those actions. And so by using Lourve, we're saying, whenever we get a mouse move, move a tenth of the way to the mouse. Don't move all the way to the mouse, but just a tenth of the way.

[23:00] And if you keep your mouse still, just keep moving a tenth and the tenth. And intent until you get closer and closer to the maps, and of course, if you move, move your mouse, that value updates, so it's going to move, you know, closer and closer to the mouse. So now, to illustrate that, I added lerp, that function right there, we're doing scan lerp, and everything else remains the same. And now when I move my mouse, it's gonna move very, very smoothly.

[23:00] So, you know, if I'm doing a rate of point zero five, if I do point zero one, it's gonna go like, really, really, really, really slow. And you see it updates whenever I move my mouse to. So, reactive animations don't just need to be for motion. This is a really cool example that someone made Lizzy Linhart. Where we're actually using the mouse movement to change the color. And this is actually a really cool trick where you could manipulate the hue saturation values just based on your mouse movements and create some really cool effects doing that.

[24:00] And she's using a library that I actually created called RX CSS, which uses RxJS and it makes it really easy to pass CSS variables. The values that are emitted from any observable that you know you have. So, for example, let's say I wanted to get all those mouse values and move them into CSS where I could, you know, play around with them. So this is all I have to do. RX CSS give it that mouse observable, which emits X and Y values, and then I could just move things using those values.

[25:00] And so this makes scalable animations really, really easy to do, you know, using RxJS and CSS. And so, essentially, what's happening here is we're using JavaScript just to provide the stream of values, and then we're passing them over to CSS. Custom properties. And essentially, we get reactive styles as a results of. This now. So one example of this here, in fact, like, yeah, it's really small, you can't really see it. I know it's like, that, deal with it.

[25:00] But over here, I made this dog animation and someone told me the dog is a little bit hyperactive, but you know, it's cool. And so at first I was offended. I'm like, come on, I worked really hard on this animation. But then I had an idea. I was like, what if I added a brain slider over there? That could change the duration of the animation, pass it to CSS variables and essentially dynamically change the animation based on, you know, whatever you specify.

[26:00] So I did that, and to a PC, I was able to. You know, make the dog move a lot slower now, I forgot to, you know, prevent this from going the other way so the dog could actually go really fast. But yeah, and so here's another example where we're actually doing some more advanced things with RxJS, where actions don't just include the mouse move, but they include mouse down and mouse up.

[27:00] By combining this, you could see that we could move this ball in a really smooth motion. Using completely declarative code, where all of the code that's used to render the circle and to move the circle is all contained in one subscribe function. Which means if you don't want smooth animation, you could just, you know, remove that observable and use, you know, just the normal mouse move observable. And you could also edit values one by one, so you could see sort of how this is a very powerful concept for creating reactive animations.

[27:00] And so here's another one where, instead just changing the numbers, whenever I move this dial, it moves the numbers in the, you know, very smooth format. So why would you animate with observables? Well, three reasons they're declarative, they're composable in that you could create observables from other observables, and they're immutable.

[28:00] So you know that nothing is going to change, you know, behind your back. Reactive X is not a framework. And you can use RxJS pretty much anywhere, especially with Angular, but it's also possible to use arcs just with Reactant View. Also, there's a ton of implementations, it doesn't matter which language you're on, there's a bunch of Kotlin. Talks today. So it's really cool to see calling actually uses or can use reactive X as well.

[28:00] And so can Java, but I don't think Android developers like Java anymore, it's all about Kotlin, which is good Java, the scary. Now. Google is actually working on the project right now, called Material Motion. And what this is? It's a set of standards where they use observables in order to create animations. And it's for all three platforms the web, Android and Swift, and it provides an interface to basically do that. Now, they're not using RxJS, in fact, they created their own observable implementation that fits in the tweet, which isn't really that impressive anymore.

[29:00] And yes, so this is just sort of an example of what they're working on. I'm not going to go over the code because I don't understand it either. Pop Motion is another library that's coming up as beta, and they are, they have an ARCS inspired API. Again, they're not really using RxJS to create these, and so, like these animations are dynamic. So if I hit lightly, you know, if I hit it harder, it gets a little bit bigger.

[29:00] I thought that was cool. Also, I'm creating a library right now that actually does use RxJS to create reactive animations. And if you want to know more information, just follow me at the Avett K piano. Because it's not quite ready yet. But my goal is to create a visual interface for editing reactive animations, not just static animations, but animations that depend on, you know, just a number of other values. And so, you know, look out for that in the future, probably 2018.

[30:00] And so I want to thank you. All I own to have time for questions, but there's a bunch of resources here. I'll make these slides public and please talk to me during lunch if any of this interests you. Because, you know, I'd like to pick your brain, I'd like you to pick my brain. We could pick each other's brains, all right, so thank you all very much [Applause].
