Hooks in react-spring, a tutorial
First of all, you would think of react-spring as being render-props driven. Render props are expressive, explicit, and usually very easy to use. But since it is internally steered imperatively, supporting hooks was just a matter of a couple of lines added to its core. The export is now live under email@example.com. If you want to use hooks, you will need react and react-dom alpha, otherwise it won’t run. Both apis, the imperative one and hooks, are explained in full detail here.
useSpring turns any data into animated data, with a single line. Throw in whatever you want, numbers, colors, percentages, anything really, just drop it in and place the output into your view. Like so:
So let’s make some cool looking goo with this, whatever the purpose …
Let’s start by importing a few essentials. We’re going to use React of course, and since we plan using side-effects (mouse-events) we fetch
useEffect while we’re at it.
useSpring is the hook we’re going to animate with.
Forming a trail
Next we’re going to create a pure function, this is critical, you can only use hooks in functions, and they need to be declared in top-function scope.
useSpring creates a persistent hook that takes raw values and returns animated values, which are later bound to a view. You can update your spring by overwriting the hook, it will remember previous values and animate adaptively. Additionally
useSpring returns an updater, similar to
useState, with the distinction that the
set function will not cause the component to render, which is useful in situations where you are dealing with event input. We want the spring to update, and the view to animate, without refreshing the component on every mouse-move.
One goo-drop follows the mouse, while the others should trail, we do this by referencing the animated values so that one spring naturally follows the output of another.
Finally we define a basic function that takes
[x, y] and forms a css-transform-statement, we need this for interpolation later on. A little trick that i learned once, you can stack transforms, so we shift blobs to mouse-coordinates first, then shift them half their size back so that they are cursor-centric.
Handling the mouse
useEffect is Reacts way of creating a side-effect. We would like to register an event-handler on mount and unregister it on unmount, additionally we need to listen for mouse-movements in order to update our spring, this is where the
set function mentioned above comes into play. Notice how we only need to update the first spring, since the others will follow naturally (with slightly slower spring configs).
 in the end of
useEffect prevents React from running it every update, think of it as
componentWillUnmount combined into one effect.
Creating an SVG filter
This step is straight forward, we drop an SVG with a gaussian blur and a color matrix into the scene. Everything is explained here in detail. In synthesis, all we do is animate a couple of shapes while the SVG filter will later do its thing and make it appear as if they would merge together.
A small warning while we’re at it, sadly some browsers still struggle with filters or can’t process them on the GPU (which can make it very slow). I wouldn’t exactly recommend putting this on your website.
Rendering out the animated blobs
This is the last step and we’re already done. Here we simply define a couple of divs and animate their transforms. We are extending the divs from
animated which allows react-springs to animate outside of react. We take the transform that we defined earlier, apply it, and this is it. Wasn’t so hard, was it?
Et voilà, and this is how it looks …