SVG Morphing (the easy way and the hard way)
This is an exploration of two approaches of morphing svg from one shape into another, and the trade-off of each one of them.
We’ll morph a cup into another.


SVG code of both cups:
The easy way:
One of the most popular libraries that can achieve that is Snap.svg.
we’ll do the following:
- Add Snap.svg library either with just the simple url
<script src=”https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
, ornpm install snapsvg
, and either import it, if your using ES6, or concat it using gulp/grunt concat. - Add the path for “#simple-cup”.
- Add the path for “#fancy-cup”.
- Add
opacity=”0”
for the “#fancy-cup”, as its purpose is to get the d attribute from it. - Add this code.
See the full code/demo here.
So, it’s pretty straight forward:
- Select the svg.
- Select the paths.
- Get the d (description) of the paths.
- Animate the d of one of them to the other.
- Add a callback that animates it back to the d of the first path, which has a callback as well that calls the first function when it finishes.
- And so on and so forth.
Advantages:
- Can morph any shape into any other shape, you’re not limited to certain amount of points.
- Having callbacks when the animation ends.
- Having list of predefined easing algorithms (mina.linear, mina.backin, mina.bounce, mina.easein, mina.easeinout, mina.easeout, mina.elastic).
Disadvantages:
- Having to include 80.44kb (28.59kb gzipped) file in you site.
- Defining animation in JS, instead of establishing SOC (separation of concerns).
- Depending on JS will make the animation fall if JS files either fail to load, or have an error that prevents the rest of the code from being evaluated.
The hard way:

Using <animate>, we’ll define the points a path animate from and to. The limitation here is that the shapes you’re morphing between have to have the same amount of points, which is somehow tricky.
So, we’ll need to do the following:
- Drag the two svgs to an SVG editor (Sketch/Illustrator).

- Start with the complex one, dragging its points to form the less complex one.
- Double click to see all the points.

- Click on any point if necessary to change the curves of that point.

- When you reach the shape B from shape A, export it as svg.
- Open that svg in any editor.
- Copy the path.
- Given that you have the points of the original shape, put that code inside the path tag (shape A)
<animate dur=”5s” repeatCount=”indefinite” attributeName=”d” values=”shapeAPoints;shapeBPoints;shapeAPoints”>
- After we’ve added the dur (duration), attributeName that we want to animate, and the repeatCount, in addition to the set of values we’re animating between, we’ll add those values
fill=”freeze” calcMode=”spline”
to make the easing function (cubic Bézier function) work, and the easing algorithm itselfkeySplines="0.4 0 0.2 1; 0.4 0 0.2 1"
, to generate your custom easing algorithm, you can go here.
I’m so sorry, I had the whole process recorded, but I’ve accidentally lost it :(.
See the full code/demo here.
Advantages:
- No libraries at all.
- Having the “look & feel” code defined were it should be, to achieve separation of concerns.
- A lot less memory consumption.


Disadvantages:
- The tedious process of converting a shape to another.
- Converting shape to another while keeping the same amount of dots is not always possible.
- Lacking callbacks when it finishes.
Conclusion:
Either use Snap.svg, and be able to morph any shape into another without limitations, but you’ll have to load an 80kb library, or use <animate> and deal with a tedious process of manually converting points from a shape to another.
One last thing…
If you liked this article, click the💚 below so other people will see it here on Medium.