Morph SVG with <animate> SVG or CSS transition

Viewed 444

I'm struggling to make an animation work. I've created two SVG shapes in Illustrator with the same amount of path points. Now i want to code a morphing animation. My first try was an animate object as suggested here:

<span class="svgspan">
              <svg class="svg1" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
                xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 398 369.4"
                style="enable-background:new 0 0 398 369.4;" xml:space="preserve">
                <style type="text/css">
                  .st0 {
                    fill: #FFFFFF;
                  }
                </style>
                <path id="pfad" class="st0" d="M398 184.7c0 51-20.7 97.2-54.1 130.6s-79.6 54.1-130.6 54.1s-97.2-20.7-130.6-54.1s-54.1-79.6-54.1-130.6
                        S49.3 87.5 82.7 54.1S162.3 0 213.3 0s97.2 20.7 130.6 54.1S398 133.7 398 184.7z">
                <animate id="trs" begin="500ms" fill="freeze" attributename="d" dur="2s" from ="M398,184.7c0,51-20.7,97.2-54.1,130.6s-79.6,54.1-130.6,54.1s-97.2-20.7-130.6-54.1s-54.1-79.6-54.1-130.6
                S49.3 87.5 82.7 54.1S162.3 0 213.3 0s97.2 20.7 130.6 54.1S398 133.7 398 184.7z" to="M195 369.4c-48.4-78-140.4-118.3-182.3-200.3C-3.8 131.7-6.1 85 17.2 50C57.9-16 157.7-15.8 199.1 49.4
                        c32.3-51.6 107.8-65.7 155.7-27.5c54.5 39.2 53.8 119.8 15.8 170.4c-49 65.4-124.1 107-167.6 177.1H195z"></path>
              </svg></span>

I got an animation, but it didn't morph but instantly switch to the second path.

My next approach was a css animation like this:

#pfad {
  d: path('M195,369.4c-48.4-78-140.4-118.3-182.3-200.3C-3.8,131.7-6.1,85,17.2,50C57.9-16,157.7-15.8,199.1,49.4c32.3-51.6,107.8-65.7,155.7-27.5c54.5,39.2,53.8,119.8,15.8,170.4c-49,65.4-124.1,107-167.6,177.1H195z');
  transition: 1s;
}

This didn't work either. I even got an 'Unknown property: d' error in VS Code and Chrome:

Chrome Error VS Code Error

It would be nice if someone could help me get this working.

Edit: The anchor points are in the right position now i guess, but i still have the same problem. New anchor points:

<path id="pfad" class="st0" d="M199,369.4c-57.6-0.5-110.6-27.4-144.1-69.2c-25.4-31.6-40.6-71.8-40.6-115.5C14.3,82.7,97,0,199,0
                s184.7,82.7,184.7,184.7c0,33.7-9,65.3-24.8,92.5C326.9,332.3,267.3,369.4,199,369.4C198.4,369.4,199.6,369.4,199,369.4z">
                <animate id="trs" begin="500ms" fill="freeze" attributename="d" dur="2s" from ="M199,369.4c-57.6-0.5-110.6-27.4-144.1-69.2c-25.4-31.6-40.6-71.8-40.6-115.5C14.3,82.7,97,0,199,0
                s184.7,82.7,184.7,184.7c0,33.7-9,65.3-24.8,92.5C326.9,332.3,267.3,369.4,199,369.4C198.4,369.4,199.6,369.4,199,369.4z" to="M199,369.4C150.6,291.4,54.8,251,12.9,169C-3.6,131.6-5.9,84.9,17.4,49.9c40.7-66,140.5-65.8,181.9-0.6
                C231.6-2.3,307.1-16.4,355,21.8c54.5,39.2,53.8,119.8,15.8,170.4C321.8,257.6,242.5,299.3,199,369.4L199,369.4z"></path>```
2 Answers

Like the comments suggest, it is a good idea to be precise with the point in the path. So, your code is ok. It is just the path that need a helping hand.

I copied your path to Inkscape and make the two shapes there.

path {
  fill: red;
}
<span class="svgspan">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="200" height="200">
    <path id="pfad" class="st0"
      d="M 500,1000 C 220,1000 0,780 0,500 0,220 220,0 500,0 c 280,0 500,220 500,500 0,280 -220,500 -500,500 z">
      <animate id="trs" begin="1s" fill="freeze" attributename="d" dur="2s"
       from ="M 500,1000 C 220,1000 0,780 0,500 0,220 220,0 500,0 c 280,0 500,220 500,500 0,280 -220,500 -500,500 z"
       to="M 500,1000 C 420,820 0,600 0,300 0,0 380,-120 500,150 620,-120 1000,0 1000,300 c 0,300 -420,520 -500,700 z" />
    </path>
  </svg>
</span>

The main condition for the implementation of smooth animation path changes
using the attribute d are:

  1. Equal number of nodes in both shapes
  2. Exact match of the node type (A; C; Q), respectively, for each point in the initial and final position of the path These conditions can be met in different ways, but it is better to do this in the vector editor.

You must have the same number of node points by the heart and the circle

Below is a screenshot from Inkscape. Drag matching points from the outline of the heart to the outline of the circle

enter image description here

@chrwahl did this work in his answer while solving this problem
All credits to @chrwahl for a job well done

@jayjay9601 comments

I'll definitely try that even though i would prefer the html/css-only version

Below is the complete CSS animation code using the d attribute:

.svgspan {
width:30vw;
height:30vh;
}
#pfad{
  fill: crimson;
  transition: all 1s ease-in-out;
}
#pfad:hover {
d: path("M 500,1000 C 420,820 0,600 0,300 0,0 380,-120 500,150 620,-120 1000,0 1000,300 c 0,300 -420,520 -500,700 z"); 
fill: red;
}
<div class="svgspan">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" >
    <path id="pfad" class="st0"
      d="M 500,1000 C 220,1000 0,780 0,500 0,220 220,0 500,0 c 280,0 500,220 500,500 0,280 -220,500 -500,500 z">
      
    </path>
  </svg>
</div>

Related