Animating complex SVG in React
Learn how to animate complex SVG in React using styled-components library.
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.
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!
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