React-spring: on animations and hooks - Alec Larson @alecdotbiz at @ReactEurope 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Applause] what is react spring and how can it make our lives better as developers my name is Alec Larson and I'm co-author of react spring along with Paul Henschel who wrote the first major eight or eight major versions of react spring I joined the react spring organization at the beginning of April shortly after I began rewriting the animation controller for version 9 which is currently in beta apart for my work in open source I'm working on a few secret projects with my design minded co-founder Scotty Larson who is also my brother our latest project is light timer the best timer app that lives in your menu bar in addition to basic timers it comes with a stand and sit timer a focus and break timer and it's made with react it's animated with react spring and it's driven by react native Mac OS which is a community fork of react native that I helped maintain sign up for the beta at light timer com so animations are more important to us than you might think sure you could write an app without any animation and maybe even some people would use it ensure no animation is better than poor having poor animations that turn people off but taking the time to perfect your animations you can have a compounding effect on your business down the road animation isn't something you turn out for to make a difference in your project you need to harness your inner Picasso if you can't be passionate about the animations in your app why do you expect anyone else to care when you truly care about providing the best experience your animations become works of art animation builds trust especially when it's thoughtful enough to make an impression it shows that you care enough to put in the extra effort but remember there's also a fine line between inspiring and distracting your users with your animations good animation adds flair to the everyday actions your users take but great animation guides the the attention of your users to help them get things done faster figure out where you want your users focus and design your animations around that for example that's what I did with light timers website when I first implemented the entrance animation I had the logo fading in last the trick is to fade in the logo earlier so it's not stealing attention from the bottom half of the page notice how your eyes are attracted to the last moving component animation gives your web app a native feel because native apps are always animated and web apps are not typically animated using functions are another way to improve your web app also known as linear easing I think we all agree that it leaves a lot to be desired bezier easing like ease out quad can help what we can do better and that brings us to spring easing the best choice for animations in react today by default with react spring your animations don't have explicit durations or easing functions instead your animations are driven by spring physics and it's worth taking the time to understand why this is springs are physical they have mass tension velocity and friction when a spring has zero friction it never slows down its velocity remains constant as it would in the vacuum of space and because of this the circle always bounces back to where it started from friction decreases velocity over time in the real world nothing ever slows down according to some predefined easing function and your animations shouldn't either spring physics make your animations feel natural springs are responsive they can follow each other around constantly adjusting their velocity without sudden and unnatural changes in motion and because of this Springs are the only reliable way to gracefully transition from a swipe gesture to an animation Springs are intuitive once you have a firm grasp on how the physical properties of a spring affect its movement achieving the desired motion is easier than you might think tweak the friction here a little less tension there and you've got the perfect animation Springs are the feature look it's 2019 if you're not using Springs and only Springs by 2020 you probably won't survive the coming robot apocalypse and you can't say I didn't warn you either so Springs are clearly a great choice for animation but Springs aren't the only thing we want in an animation library we also want a clean API for managing our animations and now that we have react hooks that goal can finally be achieved with react spring so let's take a look at use spring which controls the animation of one or more values the use spring function takes a set of props and returns a plane object with animated values inside your animated values can be named anything if you put them in the to prop but you can also skip the to prop and pass through two values in directly for your for your components to be animated they must be wrapped with the animated function exported by react spring this lets your component update itself transplant transparently which is much more performant than re rendering on every animation frame the animated function is also exported as the function this is convenient when animating built-in components for example the div component is wrapped for you automatically and exposed on the animated function there's a small caveat with the animated function you should avoid wrapping composite components with it unless you're okay with rear-end during that component on every animation frame not every value can be animated but reacts spring welcome won't complain about it instead react spring falls back to basic assignment so what can be animated numbers can be animated strings can be animated like this CSS transform value or this string that contains two numbers or this hexadecimal color string and even named colors can be animated and last but not least arrays can be animated as long as they contain animated animatable values I want to make it clear that any prop can be animated with react spring not just style props for example even SVG props can be animated in most animation libraries you would need an explicit from value for this animation to work in react spring the to crop is used as the from value and no animation begins on the first render so as you can see here when we update the to prop are the width in this used spring call it animates but it didn't animate on the first render to start your animations on the first render you must include the relevance animated value in the front prop as I click these buttons know just how the animation is slower than in the previous example this behavior is customized with the config prop the concrete crop has default values for each of its properties so you're not required to define all of them the first of those properties is mass the default value for mass is 1 the more mass you give to something the more velocity it needs just to speed up and the more time it needs to slow down the next property is tension also known as stiffness higher tension makes friction less effective notice how the last spring has a slight bounce to it next is friction also known as the damping ratio higher friction means greater deceleration and less bouncing velocity is the initial speed and direction this property comes in handy for gesture based animations notice how the animation is all finished at the same time even though their velocities initial velocities are different let's see that again clamp prevents your animation from overshooting its final value the most common use case for clamping is when you're animating opacity this is without clamp so because you're using a spring animation there's that overshooting and it looks really bad the with clamp fades in and it's done and finally precision is used to determine when a spring has finished animating most of the time you won't need this for your convenience react spring provides some presets on the config export in this demo you can see each of the presets and how long it takes for their animations to finish the Gentle preset has the lowest tension of the presets the wobbly preset has the lowest friction the stiff preset has slightly higher tension than the default preset and also slightly lower friction the result is a faster spring that bounces a little bit and the slow preset has more than twice as much tension as the gentle preset and four times as much friction and finally the molasses preset has the same tension as the slow preset but twice as much friction so these can help you learn how the different properties affect the movement by passing a config function you can have different spring behavior for each of your animated values if you ever need them here are the config props supported by react spring that are not related to spring physics if you know adoration and easing or for then you know that a kitten dies every time they're used the decay prop is for animations that resemble curling like scroll animations the delay prop controls the number of milliseconds before the props are processed by the animation controller as your component is we rendered new delays are kicked off you can pass a function here too if you need to customize the delay of each animated value separately the immediate prop makes your animations instinct like the delay prop you can pass a function the canceled prop stops your animations instantly unlike the immediate prop your animated values will not jump to the end value the canceled prop can be a string if you want to stop a single animated value or it can be an array of strings the reset prop restarts your animations from their initial values as if it was the first render again finally the reverse prop treats the two prop like the front prop and vice-versa so these two examples are equivalent unfortunately they're cut off the remaining props of used spring are event listeners the on start prop is called whenever one of your animated values is about to start animating it's passed in animation objects which can help when debugging the on frame prop is called on every animation frame with the latest values and finally the unrest prop is called whenever the last animations have stopped or been finished the animated nodes returned by use spring have two methods the first method is get value which returns the latest value and then there's the interpolate method which effectively transforms the animated value on every animation frame the return value is a new animated node that can be passed to an any component also if you ever need to combine multiple animated nodes you can use the interpolate function exported by react spring by default use spring is in declarative mode it updates its animations on every render declarative mode should work perfectly in most cases but if you want to avoid rear-ending for some reason imperative mode lets you do just that pass a props factory instead of your typical props object the props factory is only called on the first render to update your animations you can call the update function with any props that you would normally pass to use spring with the stop function you can stop some animations by passing specific keys or you can stop all animations by passing nothing there's also an imperative ref mode where you pass a react ref in to use spring in this mode your animations must be started manually here's the interface of the use spring ref the controller's array is interesting controllers are the objects that manage your animations keep in mind there isn't much documentation on controllers yet because the hooks API usually gets the job done one of my favorite features in react spring is the ability to create scripted animations using an async function as the two problem the update function takes the same props that use spring does and it always returns a promise which resolves once all the animations have finished this lets you describe complex animation logic using async/await syntax there are three ways to chain animations together in react spring the first way is by an an async function is the to prop but that can be overkill if you don't need arbitrary logic between updates the second way is by passing an array of updates as the two prop so that would animate to X animate X to 100 first and then when that's done animate Y to 100 the objects in this array can have any use spring compatible prop like delay the from prop must be defined whenever the two prop is an array or function otherwise the animated nodes won't be created on the first render and thus your animated components won't be connected to your animation reacts spring ensures that only one async to function is running at any given time when a new to function has passed to use spring during a rerender the previous to function is interrupted to avoid this be sure to wrap your async function with the used callback hook the third way to chain your animations is with use chain when the use chain hook has passed just one array it starts the animations of the first dref and then when the first draft is done animating the second ref has its animations started you can pass an array of time steps if you want explicit delays know just how the delays are in seconds instead of milliseconds this makes use chain feel like a higher level of abstraction at least a little bit if any ref has an undefined delay and inherits is delay from the ref before it when you're trying to chain an emissions across many different components use chain isn't ideal on light timers website I have a chain of animations but it's not implemented with use chain because that would require passing refs up the component tree to the nearest common ancestor and that gets messy pretty quick instead I'd I group the delays into an object this way you can easily get an overview of when which animations start when and tweaking the delays is super easy in the future react sprinting could make this even better by providing a context based API for animation timelines what's more infuriating than waiting for a transition to finish just so you can interact with something on the page almost nothing right and when it transitions interrupted there better not be any visual jumps the huge transition exalts the problem declarative interruptible transitions it takes three arguments and returns an array it turns an array of transition objects the items argument can be anything an array of values or just one value note that this API could be changed in version 9 so your feedback on use transition would be priceless the transitions array should be mapped onto into an array of JSX elements and these elements will be animated as their associated items are added or removed each transition represents a value from the items argument the key and props of each transition object must be given to each JSX element for everything to work as intended to determine the key property of each item the key of argument is called when the key of argument is null the items are treated like keys first let's create a transition for a single component I'm using an array to tell which to tell you use transition when the component should be mounted or unmounted we can skip the key of argument since one can be since the value 1 can be used as a key and finally we pass some props that describe the transition the from prop must be defined with the initial values the enter prop is applied to any items that were just added this render likewise the leave prop is applied to any items that were just removed so this is a demo of the code from the previous slide the box is faded in when mounted and fade it out when I mounted its background color only changes on the first render so it's easy to notice when the component has been recreated notice how if I click fast enough there ends up being two boxes mounted at once to fix this set the unique prop to true this allows for components in the middle of their leave animation to be reused and here's a demo with multiple values in the items array I didn't get around to finishing this so the box is kind of jump when a box is added or removed but this demonstrates how use transition can easily manage animations for multiple items at once if you want to chain multiple animations for the enter or leave transition you can pass an array of updates the transitions of each item can be individually customized for example try passing a function as the enter prop and it will be called whenever an item is added you can even return an async function or an array of updates the ref prop triggers imperative ref mode which is identical to how used spring works the trail prop adds a stagger effect when multiple items are added at once their transitions won't happen at the same time the config prop lets you set the default spring behavior of each transition to customize the spring behavior of each item try passing a function the use trail hook lets you control multiple Springs with a single set of props every spring follows the first spring but with a short delay to create a effect the main difference from youth spring is that you need to pass a number as the first argument but the second argument of use trail is identical to the first argument of use spring use trail also returns an array of objects instead of a single object like use spring all right so here's an example of use use trail interaction the first face follows the mouse and the other faces follow the face in front of them and here is a more advanced example of use trail I think this is pretty cool because it shows how the leader of a used trail animation can trail and other animation which I or when I click the trail goes the other way next is the used spring soak which lets you control an array of Springs this is actually what powers the use spring hook under the hood it takes the number of Springs you want as well as an array or function it returns an array of objects that contain animated notes if you pass a function it's called once per spring with the springs index this also activates imperative mode which means you need to start the animations manually by calling the update function with a function argument you can decide which updates are necessary on a per spring basis and those are the five hooks exported by react spring if you have any ideas for hooks that would make react spring even easier to use open an issue so we can discuss it the more ideas the better reacts use gesture react use gesture is a package that provides declarative gesture handling and it works perfectly with react spring because it's by the same guy that wrote react spring when I throw one of these tarot cards reacts spring uses the gestures final velocity to determine the rotation as it flies off screen by using dependency injection reacts spring can support multiple platforms these are the entry points for each currently supported platform Dom react native canvas and WebGL react 3 fibre is a package that reacts spring uses to support WebGL it combines the react reconciler with three gjs for declarative 3d environments let's see how easy this effect is with react spring just kidding I forgot that slide ok currently animations in react native are driven by JavaScript this often leads to Genki animations because Java scripts can't send messages over the native bridge fast enough I'll be working on a native frame loop when I get home though that's pretty cool and react native will soon have the JSI which allows for custom native objects to be exposed to javascript hopefully this will make javascript in native messaging fast enough for sixty frames per second when I found react spring almost two months ago I was like this API is beautiful how does it work as I tried to understand the source code I was like this is pretty nice but this variable name is confusing and why is this like this and so a little by little I tweaked and reorganized the controller class that manages animations for the hook API fixing bugs and adding small features here and there apart from understanding the internals better so I can fix my own issues I also wanted to help lay a better foundation for future improvements because by this point it was obvious to me how valuable react spring is and then over a hundred forty commits and eight beta versions later I'm the new co-author of react spring and and even better version nine is around the corner with all kinds of goodies including reworked typescript definitions so tri version nine today by installing the next version from NPM and whether it's positive or negative your feedback is always appreciated there are more examples on react spring i/o the official documentation site like a google app and a list you can reorder by dragging people like those I think and there's more the react spring examples repository is a great place to experiment setting up a local playground he's as easy as running git clone and then yarn and I have some cool stickers to hand out thanks to my highest earner suka so come find me later for those and follow me on github at Alex Larson follow me on Twitter it's Alec Taub is where I'll be announcing a secret project later this year click the link in my pinned tweets if you need some shill house music to listen to while programming that mix and that tweet is from my youtube channel new loops we already have ten mixes ready for you so smash that subscribe button if you like what you hear and don't forget to sign up for light timer beta at light timer calm Thanks [Applause]
Info
Channel: ReactEurope
Views: 15,001
Rating: undefined out of 5
Keywords:
Id: 5QCYBiANRYs
Channel Id: undefined
Length: 30min 35sec (1835 seconds)
Published: Tue May 28 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.