27

Is it possible to use SVG to animate the d attribute of <path>?

I can draw both a diamond and a circle as a path made of eight bezier curves:

<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
    <script>
      jQuery(function($){
        var a = 50;

        var draw = function(b, c, d, e, f){
          return [
            'M', a, 0, 

            'C', b, c, ',', d, e, ',', f, f,
            'C', e, d, ',', c, b, ',', 0, a,

            'C', -c, b, ',', -e, d, ',', -f, f,
            'C', -d, e, ',', -b, c, ',', -a, 0,

            'C', -b, -c, ',', -d, -e, ',', -f, -f,
            'C', -e, -d, ',', -c, -b, ',', 0, -a,

            'C', c, -b, ',', e, -d, ',', f, -f,
            'C', d, -e, ',', b, -c, ',', a, 0,
          ].join(' ');
        };

        $('#diamond').attr({ d: draw( 5*a/6,          a/6,                    2*a/3,         a/3,            a/2 ) });
        $('#circle' ).attr({ d: draw(     a, a*Math.PI/12, (2 + 1/Math.sqrt(2))*a/3, a*Math.PI/6, a/Math.sqrt(2) ) });
      });
    </script>
  </head>
  <body>
    <svg width="200" height="200">
      <g transform="translate(100,100)">
        <path id=diamond fill="blue" stroke="black"/>
      </g>
    </svg>
    <svg width="200" height="200">
      <g transform="translate(100,100)">
        <path id=circle fill="red" stroke="black"/>
      </g>
  </body>
</html>

I'd like to animate the transformation from one to the other.

I could simulate this in javascript (just by linearly interpolating the bezier curve parameters at certain times), but I want to know if there's a way to do it with SVG.

(The circle and diamond are just an example - in reality I'd like to transition between two arbitrary solids made of the same number of bezier curves).

rampion
  • 87,131
  • 49
  • 199
  • 315

1 Answers1

31

It's possible. There are lots of examples of animating the d element of a path here: http://hoffmann.bplaced.net/svgtest/index.php?in=attributes#pathd including animating bezier curves. You should be able to adapt one for your specific use case.

This is path15 without the arc flag animation. The large arc flag can only be 0 or 1 so animating it linearly doesn't make a lot of sense.

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="400px" height="400px" viewBox="-500 100 1500 1500">
<path id="p1"
    d="M 100 100 A 200 400 30 1 0 600 200 a 300 100 45 0 1 -300 200"
    stroke="blue" fill="none"
    stroke-width="4" />
<animate xlink:href="#p1"
    attributeName="d"
    attributeType="XML"
    from="M 100 100 A 200 400 30 1 0 600 200 a 300 100 45 0 1 -300 200"
        to="M 300 600 A 300 400 -20 1 0 400 200 a 200 600 -50 0 1 100 400"
    dur="10s"
    fill="freeze" />
        
</svg>
 
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • 1
    I'm only seeing transforms here - I don't know how I would use those to perform interpolation (like I can [do in javascript](https://gist.github.com/1378906)) – rampion Nov 19 '11 at 14:56
  • 1
    Looks like I spoke a little soon. It seems like all animation isn't supported yet in my browser (FF8): [path15](http://hoffmann.bplaced.net/svgtest/path15.svg) just blinks from one state to another, while [path16](http://hoffmann.bplaced.net/svgtest/path16.svg) does a smooth transformation. – rampion Nov 19 '11 at 15:07
  • You just provide the endpoints and the tag will interpolate automatically, that's what many of the examples are doing. You can use keyTimes and/or keySplines if you want more control. – Robert Longson Nov 19 '11 at 15:10
  • 1
    path15 tries to animate the large arc flag from 0 to 1. If you keep the flag the same value it will interpolate fine. – Robert Longson Nov 19 '11 at 15:12
  • 2
    Is it possible to do path animation without SMIL as it is deprecated and has bad browser support? I mean animation using styles - is it possible? – Qwertiy Oct 29 '15 at 16:48
  • 1
    @Qwertiy For path animation, you will probably need to look at [snap.svg](http://snapsvg.io/) or [GreenSock](https://greensock.com/get-started-js) as suggested [here](https://css-tricks.com/smil-is-dead-long-live-smil-a-guide-to-alternatives-to-smil-features/#article-header-id-4). A head start on snap.svg is available [here](https://github.com/codrops/AnimatedSVGIcons). – Tim Malone Jan 18 '17 at 00:23
  • I just copied the code into my svg element and I could not see anything moving. – Dávid Konkoly Mar 09 '21 at 21:35
  • @DávidKonkoly The snippet animates for me in Firefox, Safari and Chrome. – Robert Longson Mar 09 '21 at 22:40