SVG Shape Morphing using Anime.js Engine

SVG shape morphing/animation using anime js javascript animation engine.


SVG Shape Morphing using Anime.js 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:

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

Shape1

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

Shape2

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!