Jump to content

| GreenSock

MorphSVGPlugin morphs SVG paths by animating the data inside the "d" attribute. The video explains more (but uses the GSAP 2 formatting):

It has never been easier to morph between SVG shapes. First, let's cover what this new plugin can do:

  • Morph <path> data even if the number (and type) of points is completely different between the start and end shapes! Most other SVG shape morphing tools require that the number of points matches.
  • Morph a <polyline> or <polygon> to a different set of points
  • There's a utility function, MorphSVGPlugin.convertToPath() that can convert primitive shapes like <circle>, <rect>, <ellipse>, <polygon>, <polyline>, and <line> directly into the equivalent <path> that looks identical to the original and is swapped right into the DOM.
  • Draw the resulting shape to <canvas> (via a render function or set a MorphSVGPlugin.defaultRender)
  • Use either linear interpolation (the default) or a newer "rotational" type to get more natural looking morphs
  • Optionally define a "shapeIndex" that controls how the points get mapped. This affects what the inbetween state looks like during animation.
  • Instead of passing in raw path data as text, you can simply feed in selector text or an element and the plugin will grab the data it needs from there, making workflow easier.

How does it work?

MorphSVGPlugin does a ton of heavy lifting so that you don't have to. You can morph a circle into a hippo with a single line of code:

gsap.to("#circle", {duration: 1, morphSVG:"#hippo"});

MorphSVGPlugin finds the path with the id of "circle" and the path with the id of "hippo" and automatically figures out how to add enough points to the circle and position them properly so that you get a super smooth transition to the hippo shape. It will rip through all that ugly path data, convert everything to cubic beziers, and dynamically subdivide them when necessary, adding points so that the beginning and ending quantities match (but visually it looks the same). It’s all seamless under the hood, of course. And since MorphSVGPlugin is so tightly integrated into GSAP, sequencing multiple morphs is a breeze. Watch how easy it is to make that circle morph into a hippo, star and elephant.

tl.to(circle, {morphSVG: "#hippo", duration: 1}, "+=1")
  .to(circle, {morphSVG: "#star", duration: 1}, "+=1")
  .to(circle, {morphSVG: "#elephant", duration: 1}, "+=1")
  .to(circle, {morphSVG: circle, duration: 1}, "+=1");


MorphSVGPlugin needs to know what shape to morph to (and optionally which shapeIndex to use). When only specifying a shape, MorphSVGPlugin can take a wide range of values. Selector string

gsap.to("#circle", {morphSVG:"#hippo", duration: 1});

An SVG element

var endShape = document.getElementById("hippo");
gsap.to("#circle", {morphSVG: endShape, duration: 1});

Points for <polyline> or <polygon> elements:

gsap.to(“#polygon”, {morphSVG:"240,220 240,70 70,70 70,220", duration: 2});

Strings for <path> elements

gsap.to(“#path”, {morphSVG:"M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10", duration: 2});

*Note: if the shape you pass in is a <rect>, <circle>, <ellipse> (or similar), MorphSVGPlugin will internally create path data from those shapes.


The shapeIndex property allows you to adjust how the points in the start shape are mapped. In order to prevent points from drifting wildly during the animation MorphSVGPlugin needs to find a point in the start path that is in close proximity to the first point in the end path. Once that point is found it will map the next point in the start path to the second point in the end path (and so on and so on). Due to the complexity of vector art there will be times that you may want to change which point in the start path gets mapped to the first point in the end path. This is where shapeIndex comes in. In order to specify the shapeIndex you need to use an object {} with shape and shapeIndex properties. The following code will map the third point in the square to the first point in the star.

gsap.to("#square", {morphSVG: {shape: "#star", shapeIndex: 3, duration: 2}});

findShapeIndex() utility

Experimenting with shapeIndex can be a bit of a guessing game. To make things easier we have created a stand-alone utility function called findShapeIndex(). This function provides an interactive user interface to help you visualize where the start point is, change it and preview the animation. You can load findShapeIndex() from: https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/findShapeIndex.js Once its loaded you simply tell it which shapes to use.

findShapeIndex("#square", "#star");

Or pass in raw data:

findShapeIndex("#square", "M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10");

The best way to get started is to drop your SVG into the pen above and alter the IDs to match your svg. Be sure to watch the video above which clearly illustrates how shapeIndex and findShapeIndex() work. Additional Notes

  • shapeIndex only works on closed paths.
  • if you supply a negative shapeIndex the start path will be completely reversed (which can be quite useful).

Converting SVG shapes to paths

Technically it’s only feasible to morph <path> elements or <polyline>/<polygon> elements, but what if you want to morph a <circle> or <rect> or <ellipse> or <line>? No problem - just tap into the utility method and have the plugin do the conversion for you:

You can pass in an element or selector text, so you could also have it convert ALL of those elements with one line:

MorphSVGPlugin.convertToPath("circle, rect, ellipse, line, polygon, polyline");

This literally swaps in a for each one directly in the DOM, and it should look absolutely identical. It’ll keep the attributes, like the “id” attribute. So after the conversion, you should be able to target the elements pretty easily, just as you would before.

<!-- An svg  Like this: -->
<rect id="endShape" width="100" height="100" fill="red"/>
<!-- becomes -->
<path id="endShape" fill="red" d="M100,0 v100 h-100 v-100 h100z"></path>

Rotational Morphs? Canvas?


View the official docs here for a full breakdown of the API. To learn how to include MorphSVGPlugin into your project, see the GSAP install docs.


Get your hands on MorphSVGPlugin

MorphSVGPlugin is a bonus plugin for Club GreenSock members ("Shockingly Green" and "Business Green" levels). It's our way of showing our gratitude to those who are fueling innovation at GreenSock. To download MorphSVGPlugin, just log into your account dashboard and grab the latest version of GSAP. Try MorphSVGPlugin for free on CodePen! There's a special [fully-functional] version of MorphSVGPlugin that we link to in our demos in our MorphSVGPlugin Collection on CodePen, so feel free to fork any of them, add your own SVG graphics, and take MorphSVGPlugin for a spin. CodePen is a fantastic way to experiment. We highly recommend it. Note: the special version of the plugin will only work on the CodePen domain. To find out more about the many benefits of being a Club GreenSock member swing on by the club page and be sure to check out the other premium plugins.


  • Like 3
  • Thanks 1

Get an all-access pass to premium plugins, offers, and more!

Join the Club

With great power comes great responsibility. Tween wisely.

- Team GreenSock

User Feedback

Recommended Comments

Awesome work, Jack! This is the single best example of shape tweening I've seen, regardless of platform or application (looking at you, flash). I bet you'll get a lot of new memberships because of this feature alone.
Link to comment
Share on other sites

Absolutely, @grayghost. http://codepen.io/GreenSock/pen/WQjRXE?editors=001 Caveat: the flapping cape effect is a mix of MorphSVGPlugin and some custom sine wave trigonometry applied in an onUpdate. :)
Link to comment
Share on other sites

Incredible! Absolutely stunning. This will give addicted GreenSock users like me many more ideas. This in combination with other gsap plugins is getting the web to next levels. Many thanks!!
Link to comment
Share on other sites

I would love to see a video or article that describes how the sine effect works or was conceived. As a person who codes yet sucks at math, I for one am extremely interested things like this and would love to understand it better.
Link to comment
Share on other sites

I am completely astonished by this plugin. Furthermore, the video explaining how it works is one of your best.

Congratulations !
Link to comment
Share on other sites

As iansvo said, please make a tutorial video on your Youtube channel to explain how to use basic trig functions in javascript to create such effects !!!
It's a serious need for many of us to improve our animation skill set.

Anyway big thanks :)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now