Color interpolation

Matt Perry

In this tutorial, we're going to build the Color interpolation example step-by-step.

This example is rated intermediate difficulty, which means we'll spend some time explaining the Motion APIs we've chosen to use, but it assumes familiarity with JavaScript as a language.

Here's a live demo of the example we're going to be creating:

Loading...

Introduction

The Color interpolation example shows a side-by-side comparison of how Motion and the browser's native Web Animations API interpolate colors differently. This example uses the animate function from Motion to create smooth color transitions that avoid the dimming effect common in browser-based animations.

When animating between two colors, browsers typically interpolate in the sRGB color space, which can create an unnatural dimming effect in the middle of the transition. Motion uses linear RGB color space instead, resulting in more vibrant and visually accurate color transitions.

Get started

First, let's set up the HTML structure with two color swatches - one for the browser's animation and one for Motion's animation:

<div class="container">
    <div class="swatch-container">
        <div class="swatch waapi"></div>
        <div class="label">Browser</div>
    </div>
    <div class="swatch-container">
        <div class="swatch motion"></div>
        <div class="label">Motion</div>
    </div>
</div>

<style>
    /** Copy styles from example source code */
<

This creates two identical color swatches that we'll animate using different methods.

Let's animate!

Import from Motion

Start by importing the animate function:

<script type="module">
    import { animate } from "motion"
</script>

Create the browser animation

First, let's create the browser's native animation using the Web Animations API to see the dimming effect:

document
    .querySelector(".waapi")
    .animate(
        [
            { backgroundColor: "#ff0088" },
            { backgroundColor: "#1e75f7" },
        ],
        {
            duration: 2000,
            iterations: Infinity,
            direction: "alternate",
            easing: "linear",
        }
    )

This animates the backgroundColor from pink to blue and back, repeating infinitely. The direction: "alternate" option makes the animation reverse on each iteration, and easing: "linear" ensures a constant speed throughout.

Create the Motion animation

Now let's create the same animation using Motion:

animate(
    ".motion",
    {
        backgroundColor: ["#ff0088", "#1e75f7"],
    },
    {
        duration: 2,
        repeat: Infinity,
        repeatType: "reverse",
        easing: "linear",
    }
)

Motion's syntax is slightly different - it uses a selector as the first argument, the animation values as the second, and options as the third. Notice the duration is in seconds (2) rather than milliseconds (2000), and we use repeat and repeatType instead of iterations and direction.

Understanding the difference

Watch both swatches animate and you'll notice something interesting: the browser's animation appears to dim in the middle of the transition, creating a muddy, desaturated color between pink and blue. Motion's animation maintains vibrant colors throughout the entire transition.

This happens because browsers interpolate colors in the sRGB color space, which doesn't account for how human perception works. Motion uses linear RGB color space, which produces color transitions that look more natural and vibrant to our eyes.

Conclusion

We've built a visual comparison that demonstrates Motion's superior color interpolation. By animating the same color transition using both the Web Animations API and Motion, we can see how Motion's linear RGB interpolation maintains color vibrancy throughout the animation, while the browser's sRGB interpolation creates an unnatural dimming effect. This is just one example of how Motion goes beyond the browser's capabilities to create more polished, professional animations.

Motion is supported by the best in the industry.