Spring Physics

Spring Physics

Animations can be used to enhance the user experience and aesthetics of a software application. The fastest way to add animations to your website or web app is with CSS transitions and animations which will handle a majority of your basic animation needs.

If you want to implement animations of greater complexity, you can apply physics-based animations which feel much more organic than the time-based CSS animations. For React projects we can use react-spring and the useSpring hook for high quality spring based animations.

How & Why

What is a spring and why should we use it? From the react-spring docs:

The principle you will be working with is called a spring, it does not have a defined curve or a set duration. In that it differs greatly from the animation you are probably used to. We think of animation in terms of time and curves, but that in itself causes most of the struggle we face when trying to make elements on the screen move naturally, because nothing in the real world moves like that.

Here's a quick example of how you might use springs in your app:

import React from 'react'
import { useSpring, animated } from 'react-spring'

function App() {
  const style = useSpring({opacity: 1, from: {opacity: 0}})
  return <animated.div style={style}>I will fade in</animated.div>

With state:

import React, { useState } from 'react'
import { useSpring, animated } from 'react-spring'

function App() {
  const [isVisible, setIsVisible] = useState(false)
  const [style, setStyle] = useSpring(() => ({opacity: 1}))
  const toggleVisibility = () => setIsVisible(!isVisible)

  // Update spring with new style
  setStyle({opacity: isVisible ? 1 : 0})

  return (
    <animated.div style={style} onClick={toggleVisibility}>
      {isVisible ? 'I will fade out' : 'I will fade in'}

Watch The State of Animation in React form react-europe 2015 by Cheng Lou to learn more about springs.

In Action

I just launched sleeper, an ambient new tab browser extension for Firefox and Chrome. This is an open source project which you can check out on GitHub.

This project was inspired by the iOS 13 dark mode wallpapers. To bring the static wallpapers to life I use blobs to generate random blobs constrained by size, complexity, and contrast values. For animation, I generate two blobs and extract their SVG paths, then use react-spring to interpolate between the values.

I'm also using springs on this website to transition between icon states in the header navigation, and to reveal/hide the primary site navigation.

If you're looking to breathe some life into your React app, definitely check out react-spring!

CreatedApr 2020
UpdatedApr 2020