SVG Shape Morphing using Anime.js Engine
SVG shape morphing/animation using anime js javascript animation engine.
In this tutorial, we’ll explore how to animate SVG shapes using the Anime.js engine. We’ll create smooth transitions between two SVG shapes while ensuring they have the same number of points. Follow along to master this technique and make your web content more dynamic!
Important: Ensure that all the shapes have the exact same number of points/vertex.
Prerequisites:
Before we dive into the tutorial, make sure you have the following:
- Basic understanding of SVG (Scalable Vector Graphics)
- Familiarity with HTML, CSS, and JavaScript
- An SVG editor (we’ll use Figma and the Figma Blogs plugin)
- Anime.js library (we’ll include it via a CDN link)
Step 1: Creating SVG Shapes
To start, design two SVG shapes using your preferred SVG editor. In this tutorial, we’ll use Figma and the Figma Blobs plugin to draw the shapes. Ensure that both shapes have the same number of points or vertices.
Shape 1
Shape 1 SVG HTML
<svg
width="232"
height="232"
viewBox="0 0 232 232"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M113.681 0.405432C140.791 -3.61542 160.464 23.2193 181.59 38.9367C201.162 53.4982 228.319 65.6645 231.728 88.2299C235.11 110.615 205.981 125.609 197.917 147.016C190.002 168.028 203.149 195.378 185.5 210.948C167.802 226.561 138.392 218.909 113.681 221.331C85.0062 224.141 53.4846 240.496 29.4373 226.245C5.43627 212.021 -4.40523 180.183 1.82604 155.042C7.65038 131.543 46.4045 127.901 59.0751 106.666C68.0264 91.6647 52.4372 72.3657 60.3771 56.9151C72.1732 33.9606 85.8165 4.53841 113.681 0.405432Z"
fill="#9400D3"
fill-opacity="0.63"
/>
</svg>
Shape 2
Shape 2 SVG HTML
<svg
width="232"
height="232"
viewBox="0 0 232 232"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M96.4471 0.00485847C112.78 0.353955 120.743 23.3279 136.438 28.208C167.018 37.7165 211.516 12.3999 228.811 41.1618C244.16 66.6863 199.506 91.5715 192.201 120.942C184.183 153.181 206.944 194.97 184.759 218.286C163.155 240.991 125.431 230.683 96.4471 221.576C72.4011 214.02 51.329 195.995 39.0405 172.5C29.0207 153.343 43.8906 128.944 37.1449 108.193C30.1072 86.544 -4.46888 76.2006 0.483266 53.8921C5.28215 32.2741 36.9775 36.7542 55.2855 26.4735C69.8111 18.3169 80.0668 -0.345241 96.4471 0.00485847Z"
fill="#8DD5E6"
/>
</svg>
Shape2 Step 2: Setting Up HTML Structure
Construct the basic HTML structure for your SVG animation. Here, we’ve included the SVG element and the initial path for Shape 1.
HTML Structure
<svg
id="svg"
width="232"
height="232"
viewBox="0 0 232 232"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
id="svg_path"
fill-rule="evenodd"
clip-rule="evenodd"
d="M113.681 0.405432C140.791 -3.61542 160.464 23.2193 181.59 38.9367C201.162 53.4982 228.319 65.6645 231.728 88.2299C235.11 110.615 205.981 125.609 197.917 147.016C190.002 168.028 203.149 195.378 185.5 210.948C167.802 226.561 138.392 218.909 113.681 221.331C85.0062 224.141 53.4846 240.496 29.4373 226.245C5.43627 212.021 -4.40523 180.183 1.82604 155.042C7.65038 131.543 46.4045 127.901 59.0751 106.666C68.0264 91.6647 52.4372 72.3657 60.3771 56.9151C72.1732 33.9606 85.8165 4.53841 113.681 0.405432Z"
fill="#9400D3"
/>
</svg>
Let’s implement JavaScript event handling to trigger the shape animation. We’ll use the Anime.js library for smoother transitions. Replace the path values with the respective Shape 1 and Shape 2 path data.
const paths = [
"M113.681 0.405432C140.791 -3.61542 160.464 23.2193 181.59 38.9367C201.162 53.4982 228.319 65.6645 231.728 88.2299C235.11 110.615 205.981 125.609 197.917 147.016C190.002 168.028 203.149 195.378 185.5 210.948C167.802 226.561 138.392 218.909 113.681 221.331C85.0062 224.141 53.4846 240.496 29.4373 226.245C5.43627 212.021 -4.40523 180.183 1.82604 155.042C7.65038 131.543 46.4045 127.901 59.0751 106.666C68.0264 91.6647 52.4372 72.3657 60.3771 56.9151C72.1732 33.9606 85.8165 4.53841 113.681 0.405432Z",
"M96.4471 0.00485847C112.78 0.353955 120.743 23.3279 136.438 28.208C167.018 37.7165 211.516 12.3999 228.811 41.1618C244.16 66.6863 199.506 91.5715 192.201 120.942C184.183 153.181 206.944 194.97 184.759 218.286C163.155 240.991 125.431 230.683 96.4471 221.576C72.4011 214.02 51.329 195.995 39.0405 172.5C29.0207 153.343 43.8906 128.944 37.1449 108.193C30.1072 86.544 -4.46888 76.2006 0.483266 53.8921C5.28215 32.2741 36.9775 36.7542 55.2855 26.4735C69.8111 18.3169 80.0668 -0.345241 96.4471 0.00485847Z",
];
Animating the SVG Shape
In this step, we’ll define the function to animate the SVG shape using Anime.js. The svgMorphing function will change the d attribute of the path element to morph the shape smoothly.
let svg = document.getElementById("svg");
let destination_path;
const colors = ["#9400D3", "#8DD5E5"];
svg.addEventListener("mouseover", () => {
svg_path.attributes["fill"].value = colors[1];
destination_path = paths[1];
svgMorphing(destination_path);
});
svg.addEventListener("mouseleave", () => {
svg_path.attributes["fill"].value = colors[2];
destination_path = paths[0];
svgMorphing(destination_path);
});
Now, create the svgMorph function to animate the SVG shape. In this function we will use anime.js enigne’s timeline function to animate the SVG shape. svgMorphing function
function svgMorphing(path) {
let timeline = anime({
duration: 750,
targets: "#svg_path",
d: [
{
value: path,
},
],
easing: "easeOutCubic",
});
}
Bring It All Together
Finally, integrate the HTML structure, JavaScript event handling, and shape animation function to create an attractive SVG shape animation.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#svg_path {
transition: all 0.75s;
}
</style>
</head>
<body>
<svg
id="svg"
width="232"
height="232"
viewBox="0 0 232 232"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
id="svg_path"
fill-rule="evenodd"
clip-rule="evenodd"
d="M113.681 0.405432C140.791 -3.61542 160.464 23.2193 181.59 38.9367C201.162 53.4982 228.319 65.6645 231.728 88.2299C235.11 110.615 205.981 125.609 197.917 147.016C190.002 168.028 203.149 195.378 185.5 210.948C167.802 226.561 138.392 218.909 113.681 221.331C85.0062 224.141 53.4846 240.496 29.4373 226.245C5.43627 212.021 -4.40523 180.183 1.82604 155.042C7.65038 131.543 46.4045 127.901 59.0751 106.666C68.0264 91.6647 52.4372 72.3657 60.3771 56.9151C72.1732 33.9606 85.8165 4.53841 113.681 0.405432Z"
fill="#9400D3"
></path>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<script>
const paths = [
"M113.681 0.405432C140.791 -3.61542 160.464 23.2193 181.59 38.9367C201.162 53.4982 228.319 65.6645 231.728 88.2299C235.11 110.615 205.981 125.609 197.917 147.016C190.002 168.028 203.149 195.378 185.5 210.948C167.802 226.561 138.392 218.909 113.681 221.331C85.0062 224.141 53.4846 240.496 29.4373 226.245C5.43627 212.021 -4.40523 180.183 1.82604 155.042C7.65038 131.543 46.4045 127.901 59.0751 106.666C68.0264 91.6647 52.4372 72.3657 60.3771 56.9151C72.1732 33.9606 85.8165 4.53841 113.681 0.405432Z",
"M96.4471 0.00485847C112.78 0.353955 120.743 23.3279 136.438 28.208C167.018 37.7165 211.516 12.3999 228.811 41.1618C244.16 66.6863 199.506 91.5715 192.201 120.942C184.183 153.181 206.944 194.97 184.759 218.286C163.155 240.991 125.431 230.683 96.4471 221.576C72.4011 214.02 51.329 195.995 39.0405 172.5C29.0207 153.343 43.8906 128.944 37.1449 108.193C30.1072 86.544 -4.46888 76.2006 0.483266 53.8921C5.28215 32.2741 36.9775 36.7542 55.2855 26.4735C69.8111 18.3169 80.0668 -0.345241 96.4471 0.00485847Z",
];
const colors = ["#9400D3", "#8DD5E5"];
let svg = document.getElementById("svg");
let svg_path = document.getElementById("svg_path");
let destination_path;
svg.addEventListener("mouseover", () => {
destination_path = paths[1];
svg_path.attributes["fill"].value = colors[1];
svgMorphing(destination_path);
});
svg.addEventListener("mouseleave", () => {
destination_path = paths[0];
svg_path.attributes["fill"].value = colors[1];
svgMorphing(destination_path);
});
function svgMorphing(path) {
let timeline = anime({
duration: 750,
targets: "#svg_path",
d: [
{
value: path,
},
],
easing: "easeInQuad",
});
}
</script>
</body>
</html>
Final Result
See the Pen SVG Shape Morphing by yogesh (@yogesh_devaliya) on CodePen.
Additionally you can animate SVG shape using the othe tools/plugins like SnapSVG, Greensock GSAP, MorphSVG, KUTE.js, d3 etc…
Congratulations! You’ve successfully created an SVG shape animation using JavaScript and Anime.js. Feel free to customize this technique to fit your specific needs and create even more captivating animations on your website.
If you found this article/tutorial insightful then feel free to share with others!