Animate SVG

Animate SVG with CSS & JS

See the Pen CSS Scroll Color Animation by Ion Emil Negoita (@inegoita) on CodePen.

In this short tutorial I will be showing you how you can animate an SVG image using CSS and JS. This is a great exercise if you want to learn how CSS animations work and how to animate SVG elements. Additionally I will show you how to trigger the animations. I especially enjoy website animations driven by scrolling the page, so I will also include that in the tutorial.

Take a look at the code in the CodePen demo above. You can trigger the animation by scrolling, clicking on the SVG or pushing the PLAY button to play the animation continously.

What does this button do?

It sounds like a lot, but you’ll see it’s not as hard as it sounds.

Let’s get started!

How to Create an SVG Image for out SVG Animation

First, we’ll need an SVG image to animate. There are a lot of ways to create SVGs and it really depends on how good you are with apps like Inkscape, Adobe Illustrator or even one of the latest Photoshop versions. You have several options:

  1. Draw a vector image from scratch
  2. Start from a photo or image with your graphics and convert it to SVG. Here’s a very detailed tutorial on how to convert an image to vector using Photoshop
  3. Create an SVG design using an vector image generator (see below)

As I’m moderately talented at drawing and very lazy, I’ve decided to go for option 3 and generate a cool looking typography SVG design using the free online text in shape generator from MockoFun. This generator allows you to choose a shape, input your own text and it will generate a vector typography text in shape with 2 colors (that you can change).

I tried creating several designs and for this tutorial I went for the skull shape with the text “TEXT IN SHAPE MOCKOFUN”. I simply downloaded the result as SVG and I used it for this tutorial.

Here are some of my other designs:

text in shape
Download the SVG version
Download the SVG version
Download the SVG version

 

Ok, now that we have our SVG image we can move on to animating it.

Basics of Animating SVG with CSS

This is very important. To animate our SVG with CSS we need to use our SVG as an inline SVG.

What does that mean?

It means that you have to open up the SVG image using a text editor, grab the SVG definition from there and paste it right into your HTML page. Otherwise, you won’t be able to animate parts of the SVG.

When you open up the SVG created with MockoFun you will notice it’s made up of groups (<g/> tags) and paths (<path/> tags). We need to turn our attention to the paths as that’s what we’ll animate.

CSS for SVG works the same way as it does for HTML, BUT there are different properties that you can animate. I highly encourage you to take a look at this intro to CSS for SVG.

If you look in our CodePen JS code you’ll see the method updateSvgFill() that we’re basically changing the el.style.fill property to change the color of the SVG path element. fill is the color for the SVG path element just like background-color for HTML elements.

As you can see, basic SVG animation is similar to HTML CSS animation. Access the style of <path/> elements and change their values to animate them.

SVG Color Animation

So, now you know how to animate SVG style properties, so let’s see how the SVG color animation works in our case.

The SVG we are using has two <path/> elements: the background shape and the text inside the shape. We want to change the colors of these two paths. For the colors I’m using CSS hsl() values. HSL stands for Hue, Saturation and Lightness. This is a convenient way to work with colors especially when animating CSS colors.

This allows me to only change the hue of the color while keeping the saturation and lightness the same. The colors obtain will “feel” like they are from the same palette of colors.

So, within the updateSvgFill() method I’m only passing the newHue parameter each time I want to change the colors, while keeping the saturation and lightness the same:

const SATURATION = '100%';
const LIGHTNESS = '50%';

I’m making sure that the hue value is always a number between 0 and 360 – this is because the hue is an angle on the hue circle.

 

CSS HSL hue

 

Also, to make sure that the SVG background shape and SVG text inside shape are not the same color I’m offsetting their hue colors by 180°. Colors with 180° offset hues are called complementary (opposite on the color wheel). Complementary colors stand out when placed next to each other, so this trick will ensure the text inside the shape will be readable for our animation.

Here’s the code that does that:

currentHue = (newHue % 360 + 360) % 360;
const shapeHue = (180 + currentHue)%360;
const dynamicColor = `hsl(${currentHue}, ${SATURATION}, ${LIGHTNESS})`;
const shapeColor = `hsl(${shapeHue}, ${SATURATION}, ${LIGHTNESS})`
svgTexts.forEach(el => {
el.style.fill = dynamicColor;
});
svgShapes.forEach(el => {
el.style.fill = shapeColor;
});

Triggering the SVG Animations

Now we know what our SVG contains, how to change the colors of its elements, we just need a trigger for our animation.

Animate SVG

In the code provided I’ve actually included 3 ways to trigger the animation:

  1. A PLAY/PAUSE button to start or pause cycling through colors for the path elements
  2. Triggering a color change when holding down the mouse button anywhere on the page
  3. Changing the colors using the mouse scroll wheel

Let’s break it down.

The PLAY/PAUSE button

It looks like a button but is actually a disguised checkbox with two states, checked for when the animation should be playing and unchecked when the application should pause. The application is actually handled through the use of a timer setInterval() which will trigger a change every 100ms.

document.getElementById("playPauseCheckbox").addEventListener('change', event => {
let checkbox = event.target;
if (checkbox.checked) {
intervalId = setInterval(() => {
changeColorContinously();
}, 100);
} else {
clearInterval(intervalId);
intervalId = null;
}
});

The function changeColorContinously() uses a random value for the hue to set to the SVG like this:

function changeColorContinously(){
  updateSvgFill((Math.random()*360) %460);
}

Changing color on mousedown

We use the setInterval() function again to make color changes while the mouse click is held down and stop the animation when no longer holding down the mouse button.

let intervalId = null;
function handleMouseDown(event){
if (!intervalId) {
intervalId = setInterval(() => {
changeColorContinously();
console.log('Mouse is down');
}, 100);
}
}

function handleMouseUp(event){
clearInterval(intervalId);
intervalId = null;
}

CSS scrolling animation

This is probably my favorite way to trigger CSS animations: scrolling. Basically, we use the scrolling wheel of the mouse to change the colors of the SVG text and shape.

This is how we handle events from the mouse scrolling wheel:

 

const HUE_INCREMENT = 15
window.addEventListener('wheel', handleWheel, { passive: true });
...
// Event listener for mouse wheel events
function handleWheel(event) {
// event.deltaY is positive for scrolling down, negative for up
let newHue;
if (event.deltaY > 0) {
// Scrolling Down/Forward: Increase hue
newHue = currentHue + HUE_INCREMENT;
} else if (event.deltaY < 0) {
// Scrolling Up/Backward: Decrease hue
newHue = currentHue - HUE_INCREMENT;
} else {
// No vertical scroll detected (might be horizontal, ignore for now)
return;
}

updateSvgFill(newHue);

// Optional: Prevent the default page scrolling behavior
// Uncomment the next line if you ONLY want the color change
// and want to STOP the page from scrolling when the wheel is used.
// event.preventDefault();
}

This time, the change of the hue is not random, but incremental. We increment the hue by 15° (HUE_INCREMENT) each time we scroll down or decrease the hue when scrolling up. Pretty cool, right?

In Conclusion

So there it is: you now know how to create a SVG text in shape design and use CSS and JS to animate it. This is a pretty cool web design trick that you can easily integrate in your website. Drop me a comment if you have any questions.

John Negoita

View posts by John Negoita
I'm a Java programmer, been into programming since 1999 and having tons of fun with it.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top