3

Consider any animated SVG defined as HTML <svg> tag. How do I draw the SVG's content at a specific time index to a canvas using client-side JS?

What I am looking for is a function drawAnimatedSVG(fromSVG, toCanvas, animationOffset) that I can invoke with an SVG and Canvas DOM Node and number specifying the amount of secods (as floating point value) elapsed since the animation's beginning. The drawn result should only be a still image. I know that an SVG Element has a setCurrentTime method, but I can't figure out how to get the actual image at a specific time.

Please note that just waiting or delaying is not an option for me, as the SVGs I am dealing with contain animations lasting for minutes. That's why this answer does not help me.

Example SVG:

<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <rect width="100" height="100" rx="15" />
   <circle r="5" fill="blue">
   <animateTransform 
    attributeName="transform" 
    type="translate"
    from="10,10" to="90,90"
    begin="0"  dur="2" repeatCount="0" />
   <animateTransform 
    attributeName="transform" 
    type="translate"
    from="90,90" to="10,90"
    begin="2" dur="2" repeatCount="0"/>
   <animateTransform 
    attributeName="transform" 
    type="translate"
    from="10,90" to="10,10"
    begin="4" fill="freeze"
    dur="2" repeatCount="0"/>
  </circle>
</svg>
muffel
  • 7,004
  • 8
  • 57
  • 98
  • Did you try this [vivus-instant](https://maxwellito.github.io/vivus-instant/) ? – Sarath Damaraju Oct 14 '19 at 07:32
  • @SarathDamaraju thanks for the link, but it uses CSS-based animation for SVG, and I have to deal with an existing code base that generates pure SVG animations like in the example – muffel Oct 14 '19 at 07:35
  • generate SMIL using javascript perhaps? Call getCurrentTime to find out where you are in the animation. – Robert Longson Oct 14 '19 at 08:40
  • 1
    (1/2) The answer you linked probably got misled by a browser bug, [drawImage cannot draw animated images](https://html.spec.whatwg.org/multipage/canvas.html#image-sources-for-2d-rendering-contexts%3Acanvasimagesource-3), only the first frame should get drawn. This means that for what you want, you'd need to **generate the markup** of your still frame. I don't know an easy way to do so. With SVG2 some animatable properties values are now easily accessible through `getComputedStyle` but that's true only in some browsers, and anyway some animatable properties like `viewBox` won't be there. – Kaiido Oct 14 '19 at 11:37
  • 1
    (2/2) That means we would have to walk through the whole svg in search of all animated properties before getting their current values through the IDL and set it as attribute values. [Here I scribbled the first two steps](https://jsfiddle.net/23o89rhu/), however given the incredible heterogeneity of APIs for SVGAnimatedXXX, parsing the animated values is a dictionary nightmare I'll let to the ones with more time than myself. Maybe that would be worth forcing the use of a library like fakeSmile so the attributes get set directly. – Kaiido Oct 14 '19 at 11:37

0 Answers0