Animating complex SVG in React

Learn how to animate complex SVG in React using styled-components library.

Dimitri Ivashchuk
5 min readNov 19, 2018

Working with SVG in React

Dealing with SVG in React for me has always boiled down to importing the logo or an icon into component and using it in the src attribute of the image.

In this blog-post I will cover another way of working with SVG elements in React and show you the ways to animate complex SVGs using styled-components. All the necessary code is provided in the end of the post via Codesandbox.

The way of using SVG in the example above limited the possibilities of styling individual SVG layers and required to explicitly declare SVG in component to utilize all the benefits of styled-components as can be seen from the example below.

Importing SVGs as React components

After one of the latest releases of React it's finally possible to import SVG as a React component and use styled helper to style it instead.

Now it’s not necessary to have a full-blown SVG code in your components and animating parts of SVG is as simple as using css transitions for specific parts of our icon which can be achieved by using class names. Of course the most fun part of SVG animations is the possibility to animate individual paths, shapes and texts.

Let’s try to recreate React logo animation from latest version of create-react-app boilerplate with styled-components and using SVG as a React Component rather than <img>.

Preparing working environment

In this tutorial we use simple example of create-react-app. Be sure to use version later than 2.0.0 of create-react-app to follow along. To bootstrap a project with create-react-app follow simple instructions from this repo or just run the commands from the next code-block in terminal of your choice. Note that you need to have Node installed to use npm commands.

This will create a new React project we will work with. If you have never worked with React I highly encourage you to check out the docs so you can better follow the next steps.

Animating react logo with styled-components

In App.js import styled components and import React logo as React Component.

Declare styled version of our Logo where we will write our styles. We will add some CSS to adjust size and position.

Delete img logo and use our StyledLogo instead of it.

Nothing is supposed to change by now except lack of rotating animation. We can quickly fix that by importing keyframes helper from styled-components and add this simple animation.

Now you see that everything look as good as it looked originally. You may ask

Why would we even import SVG like that as it makes the workflow more complex?

The answer is simple, if you are a fan of styled-components and love animations it's really easy to animate complex SVGs (ones that consist of several elements as I've already mentioned above). Moreover we get almost unlimited flexibility in terms of adjustment of the animations and any other CSS styles based on props!

Animating individual SVG elements

We are lucky and can proceed with tutorial with the same Logo as it has couple of building blocks that can be animated separately. Namely those are circle and lines that together form react logo.

Let’s define the SVG parts we want to animate and give appropriate class names to them. In logo.svg lets add the following classes that correspond to elements of our SVG.

Now we are ready to add two keyframes that we will use for those two blocks of our SVG. In App.js let's add the following keyframes and use them in our StyledLogo declaration.

Note how we added animation-play-state: paused to trigger on our circle hover. It's here to show that although SVG is grouped, all the animations that correspond to specific class are independent and won't ruin neither animation applied to the group like rotate nor to specific parts of it like fade and pulse. To test it just hover the inner circle of the logo and you will see that only that animation will stop.

Animated React Logo

Wrap up

So in this tutorial we covered the new way of importing SVG, basic animations with styled-components and css-transitions and the way to independently animate individual parts of our complex SVG component. Keep in mind that using classes with styled-components is not the most preferred way and you could achieve the same result by explicitly declaring SVG in the component and use SVG selectors to create styled versions of all paths and shapes like styled.path or styled.circle. Using our example from the start it would look like this:

However it’s more verbose and requires to keep SVG code directly in the component.

As promised here is the code!

Working code for the tutorail

I’ve also added configurability to our animations by creating an arrow function that accepts props and returns styled-components keyframes. This allows to set the ad hoc values for specific CSS properties. But as it is more complex topic I will write another post dedicated to it, for now feel free to look at this code and use it if you find it helpful!

Thanks for reading! I hope you’ve enjoyed reading this post as much as I’ve enjoyed writing it! If you have any questions or want to bring up a discussion don’t hesitate to reach out to me on twitter.

I highly encourage you to try styled-components for styling react applications, I've been using it for the past year and can say that I'm in love with this technology!

Originally published at divdev.io

--

--

Dimitri Ivashchuk

JS developer💻| Writer📝|Tutor👨🏻‍💻| React⚛️| Firebase🔥| Gatsby.js🍸| Github: https://github.com/d-ivashchuk Blog: http://divdev.io