简体   繁体   中英

how do I get the start animation time for an HTML/SVG document?

As of right now, it seems that firefox does not support the use of ISO8601 date-time strings in the begin= attribute of an <animateTransform> tag ( SVG spec ). For example: this document should represent a second hand synchronized with UTC, but in firefox it does not animate at all.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns="http://www.w3.org/2000/svg"
   width="400"
   height="400"
   version="1.1">

  <g
     id="layer1">
    <circle cx="200" cy="200" r="180" style="fill:#ccf"/>
    <path
       style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
       d="M 200,200 200,30">
      <animateTransform
      attributeName="transform"
                          attributeType="XML"
                          type="rotate"
                          from="0 200,200"
                          to="360 200,200"
                          dur="60s"
                          begin="1970-01-01T00:00:00Z"
                          repeatCount="indefinite"
      />
      </path>
  </g>
</svg>

If we change begin= to 0 then it animates, but it isn't synchronized with wall clock time. In order to synchronize with wall clock time, I think we have to calculate the value for begin relative to document start time.

I will be adding animated elements to the document over time as I fetch data via AJAX, so the code to compute the begin attribute has to work at any time in the document's life cycle. If we add this script tag to the animation it should make the nature of the problem a little clearer:

<script type="text/javascript">
function computeAnimationBegin()
{
    // This is a toy function to illustrate the problem
    var d1= new Date()
    //console.log(d1.getTime())
    d1.setSeconds(0)
    d1.setMilliseconds(0)
    return d1.getTime()
}

function wallclockToDocumentTime(t1)
{
   //  what magic goes here??
}

function adjustAnimation()
{
    var elt = document.getElementById("a")

    var t1 = computeAnimationBegin()
    var val = wallclockToDocumentTime(t1)
    console.log(val)
    elt.setAttribute("begin", val)
}

window.onload = function() {
    setInterval(adjustAnimation, 5*1000)
}
</script>

In javascript, how do I map from a wall clock time to a value suitable for use in the begin attribute?

What I ended up doing was using "offset-value". Mozilla Description of Offset-Value

Basically, it lets you specify an animation to begin at a particular amount of seconds relative to when the page was loaded.

What I specifically did was have a variable store when "zero" is (that is, either in window.onload or whatever piece of javascript).

Then, for each animation I wanted to add the page, I would keep track of a second variable which is the wall-clock-time I wanted the animation to start at. Then, I would set the begin of the svg to:

var begin = (animation_start_time - page_load_time)/1000;

So, in my case, I had SVGs being generated by a third party (in my case calls to a webserver), and didn't know ahead of time when things needed to be on screen and moving. So, I kept track of page_load_time, and every time I learned about a new SVG I had to make, I'd record animation_start_time, and be able to derive the offset-value from that.

It REALLY confused me at first, because I assumed that "offset-value" had a "zero" of animation creation time (and thus most things would have a value of zero). It seems super weird to me to have a zero of page load time (which you mostly won't even know the value of).

To give you the answer to your code question:

function wallclockToDocumentTime(t1)
{
   return (t1 - page_load_time)/1000 + "s"; //s added so it fits directly into svg
}

Oh, and if you're worried about window.onload happening AFTER something (it can happen in weird situations), you can set your page_load_time by putting:

<script type="text/javascript">
    // put this at the top so no other javascript can delay it
    page_load_time = Date.now();
</script>

before any other javascript (even refrences or libraries).

If I'm understanding you correctly you want to be able to set the begin time to "wall clock" time. But because begin is expected to be in milliseconds you need to calculate it. So I'd get the milliseconds for the time you want it to start at and subtract the current time.

var beginMS = new Date("yyyy-mm-dd hh:mm:ss").getTime() - new Date().getTime();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM