So let’s make some cool looking goo with this, whatever the purpose …

Fetching hooks

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).

The [] in the end of useEffect prevents React from running it every update, think of it as componentDidMount and 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 …