How to animate path shape without using SMIL?

2019-02-28 09:37发布

The snippet bellow shows the thing I want to do. But there are some problems:

  1. How to make this animation without using SMIL?
    SMIL is deprecated and has a bad browser support.
  2. How to make black path going through right end og the blue one?
    Red, blue and green paths have the same length.
  3. Animation should be repeated down - up - down - up and so on.

The first question is the main one. I have some ideas about the others but I can't apply them before the first question is solved. I wrote the other questions just to clarify what am I doing.

http://jsfiddle.net/2yLxpjaw/2/

svg {
    outline: 1px solid silver;
}

path {
    opacity: .25;
    fill: none;
    stroke-width: 16;
    stroke-linecap: round;
}

#test {
    opacity: .5;
}
<svg width="200" height="200">
    <path stroke="red" d="m 22 100 q 68 0 136 -68" />
    <path stroke="blue" d="m 22 100 q 68 0 156 0" />
    <path stroke="green" d="m 22 100 q 68 0 136 68" />
    <path id="test" stroke="black" d="m 22 100 q 68 0 136 -68" />
    <animate xlink:href="#test"
             attributeName="d"
             from="m 22 100 q 68 0 136 -68"
             to="m 22 100 q 68 0 136 68"
             dur="3s"
             repeatCount="indefinite" />
</svg>

PS: Same question in Russian.

3条回答
等我变得足够好
2楼-- · 2019-02-28 10:17

I too think that js will be required for this, but for this example, this is not so hard and can be included directly in your svg document :

svg {
    outline: 1px solid silver;
}

path {
    opacity: .25;
    fill: none;
    stroke-width: 16;
    stroke-linecap: round;
}

#test {
    opacity: .5;
}
<svg width="200" height="200">
    <path stroke="red" d="m 22 100 q 68 0 136 -68" />
    <path stroke="blue" d="m 22 100 q 68 0 156 0" />
    <path stroke="green" d="m 22 100 q 68 0 136 68" />
    <path id="test" stroke="black" d="m 22 100 q 68 0 136 -68" />
   <script type="application/javascript">
    // get your element
    var tst = document.querySelector('#test');
    // get the required segment (here the quadratic curve)
    var seg = tst.pathSegList[tst.pathSegList.length-1];
    // your required properties
    var start = -68,
        end = 68,
        dur = 3000;
     
    // the distance of our journey
    var dist = end-start;
    var speed = dist/dur;
    var startTime = performance.now();
    // set your animation function
    (function move(time){
      // request the next frame as soon as possible
      requestAnimationFrame(move);
      // get the position at our current time
      var pos = (time-startTime)*speed+start;
      // we finished th first animation
      if(pos > end){
        // reset and repeat
        pos = start; 
        startTime= time;
        }
      // update our point position
      seg.y = pos;
      })();
    </script>
</svg>

Ps: the comma in the d attribute is only allowed between two numbers (to separate vector values), your snippet won't work in FF.

查看更多
我想做一个坏孩纸
3楼-- · 2019-02-28 10:24

This can't be done with just svg as far as I know. And neither with CSS.

You could either use a SVG animation library like snap.svg or you could write your own little JS animation (e.g. with RequestAnimationFrame).

查看更多
看我几分像从前
4楼-- · 2019-02-28 10:26

To animate SVG you just need to use a SMIL polyfill.

A polyfill is a special javascript piece of code that provides support for features missing from a browser, translating the original encoding in one that the browser can understand.

The SMIL polyfill made by Eric Willigers does just that: it translates SMIL into Web Animations API that even the Microsoft browser supports. It is so efficient that Google Chrome developers decided to drop native SMIL support and focus on Web Animations, leaving to the Eric Willigers polyfill the task to play SMIL files in Chrome.

Someone wrongly interpreted this as a deprecation of SMIL by Chrome, and criticized the devs for this choice. But it was not a true deprecation, just a relocation of the job of interpreting SMIL on a polyfill level.

In fact the Chrome devs themselves cited the Willigers polyfill in the very official announce about their intent to deprecate SMIL.

So if you read around the web about the demise of SMIL, don’t worry. The “death” of SMIL was greatly exagerated. It’s more like a rebirth.

To use SMIL on all browsers, including IE and EDGE, you just need to add this javascript polyfill to your web page:

https://github.com/ericwilligers/svg-animation

Here is a demo page using the polyfill made by Tom Byrne, the author of the popular flash2svg exporter:

the page without the polyfill:
http://www.tbyrne.org/staging/smil-polyfill/tears.htm

and the same page with the polyfill:
http://www.tbyrne.org/staging/smil-polyfill/tears_polyfill.htm

If you look at the source it is pretty much self-explanatory.

Also the performances with the polyfill are often better than the original SMIL, because on many browsers Web Animations is hardware accelerated, while SMIL is usually not.

查看更多
登录 后发表回答