svg animatetransform在firefox上运行但不在chrome / ie上

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了svg animatetransform在firefox上运行但不在chrome / ie上相关的知识,希望对你有一定的参考价值。

我正在使用间隔方法来转换时钟的指针。时钟在Firefox中正常工作,但在Chrome和IE中没有。

而且,控制台上没有错误。但转换属性似乎是及时更新,但ui没有得到更新。

var clock = document.querySelector('#clock');
var hands = [];
var cx = 110;
var cy = 110;

function init() {
  hands.push(clock.querySelector('#second > *'));
  hands.push(clock.querySelector('#minute > *'));
  hands.push(clock.querySelector('#hour > *'));

  setInterval(function () {
     transformHands();
   }, 1000);
};

function transformHands() {
  var now = new Date();
  var hours = 360 * now.getHours() / 12 + now.getMinutes() / 2;
  var minutes = 360 * now.getMinutes() / 60;
  var seconds = 360 * now.getSeconds() / 60;
  
  hands[0].setAttribute('from', shifter(seconds));
  hands[0].setAttribute('to', shifter(seconds + 360));
  hands[1].setAttribute('from', shifter(minutes));
  hands[1].setAttribute('to', shifter(minutes + 360));
  hands[2].setAttribute('from', shifter(hours));
  hands[2].setAttribute('to', shifter(hours + 360));
}

function shifter(value){
  return [value, cx, cy].join(' ');
}

init();
body {
  background-color: #eee;
}

div.container {
  border: 5px solid #333;
  display: block;
  width:220px;
  height:220px;
}

svg {
  display: block;
  position: relative;
  width:100%;
  height: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

#border {
  stroke: #333;
  stroke-width: 5px;
  fill: #eee;
}

#digits > line {
  stroke: #333;
}

#digits > text {
  fill: #333;
  font-size: 12px;
  font-weight: bold;
  text-anchor: middle;
  dominant-baseline: central;
}

#hour {
  stroke: #333;
  stroke-width: 5px;
}

#minute {
  stroke: #333;
  stroke-width: 3px;
}

#second {
  stroke: dodgerblue;
  stroke-width: 2px;
}

#cap {
  stroke: dodgerblue;
  stroke-width: 2px;
  fill: #eee;
}
<div class='container'>
    <svg id='clock' width='220' height='220'>
        <g id='face'>
            <circle id='border' cx='110' cy='110' r='95'></circle>
        </g>
        <g id='digits'>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(30 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(60 110 110)'></line>
            <text x='192.5' y='110'>III</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(120 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(150 110 110)'></line>
            <text x='110' y='192.5'>VI</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(210 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(240 110 110)'></line>
            <text x='27.5' y='110'>IX</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(300 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(330 110 110)'></line>
            <text x='110' y='27.5'>XII</text>
        </g>
        <g id='hands'>
            <line id='hour' x1='110' y1='110' x2='110' y2='55'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate'></animateTransform>
            </line>
            <line id='minute' x1='110' y1='110' x2='110' y2='44'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate'></animateTransform>
            </line>
            <line id='second' x1='110' y1='110' x2='110' y2='33'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate'></animateTransform>
            </line>
            <circle id='cap' cx='110' cy='110' r='3'></circle>
        </g>
    </svg>
</div>

我不知道我错过了什么。任何帮助将不胜感激。

请在这里查看演示https://codepen.io/rkpaswan_in/pen/aqPPVQ

答案

IE / Edge不支持SMIL动画。如果你想在IE中使用它,你需要使用FakeSmile polyfill。

至于Chrome,我想如果修改属性,它不会更新动画。你应该report that to Chrome

虽然有一个简单的解决方案。将您的begin属性设置为"indefinite"

<animateTransform ... begin="indefinite"></animateTransform>

然后在设置属性后开始运行动画。

hands[0].beginElement();

var clock = document.querySelector('#clock');
var hands = [];
var cx = 110;
var cy = 110;

function init() {
  hands.push(clock.querySelector('#second > *'));
  hands.push(clock.querySelector('#minute > *'));
  hands.push(clock.querySelector('#hour > *'));

  setInterval(function () {
     transformHands();
   }, 1000);
};

function transformHands() {
  var now = new Date();
  var hours = 360 * now.getHours() / 12 + now.getMinutes() / 2;
  var minutes = 360 * now.getMinutes() / 60;
  var seconds = 360 * now.getSeconds() / 60;
  
  hands[0].setAttribute('from', shifter(seconds));
  hands[0].setAttribute('to', shifter(seconds + 360));
  hands[0].beginElement();
  hands[1].setAttribute('from', shifter(minutes));
  hands[1].setAttribute('to', shifter(minutes + 360));
  hands[1].beginElement();
  hands[2].setAttribute('from', shifter(hours));
  hands[2].setAttribute('to', shifter(hours + 360));
  hands[2].beginElement();
}

function shifter(value){
  return [value, cx, cy].join(' ');
}

init();
body {
  background-color: #eee;
}

div.container {
  border: 5px solid #333;
  display: block;
  width:220px;
  height:220px;
}

svg {
  display: block;
  position: relative;
  width:100%;
  height: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

#border {
  stroke: #333;
  stroke-width: 5px;
  fill: #eee;
}

#digits > line {
  stroke: #333;
}

#digits > text {
  fill: #333;
  font-size: 12px;
  font-weight: bold;
  text-anchor: middle;
  dominant-baseline: central;
}

#hour {
  stroke: #333;
  stroke-width: 5px;
}

#minute {
  stroke: #333;
  stroke-width: 3px;
}

#second {
  stroke: dodgerblue;
  stroke-width: 2px;
}

#cap {
  stroke: dodgerblue;
  stroke-width: 2px;
  fill: #eee;
}
<div class='container'>
    <svg id='clock' width='220' height='220'>
        <g id='face'>
            <circle id='border' cx='110' cy='110' r='95'></circle>
        </g>
        <g id='digits'>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(30 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(60 110 110)'></line>
            <text x='192.5' y='110'>III</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(120 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(150 110 110)'></line>
            <text x='110' y='192.5'>VI</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(210 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(240 110 110)'></line>
            <text x='27.5' y='110'>IX</text>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(300 110 110)'></line>
            <line x1='110' y1='22' x2='110' y2='33' transform='rotate(330 110 110)'></line>
            <text x='110' y='27.5'>XII</text>
        </g>
        <g id='hands'>
            <line id='hour' x1='110' y1='110' x2='110' y2='55'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate' begin="indefinite"></animateTransform>
            </line>
            <line id='minute' x1='110' y1='110' x2='110' y2='44'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate' begin="indefinite"></animateTransform>
            </line>
            <line id='second' x1='110' y1='110' x2='110' y2='33'>
                <animateTransform attributeName='transform' attributeType='XML' type='rotate' begin="indefinite"></animateTransform>
            </line>
            <circle id='cap' cx='110' cy='110' r='3'></circle>
        </g>
    </svg>
</div>

以上是关于svg animatetransform在firefox上运行但不在chrome / ie上的主要内容,如果未能解决你的问题,请参考以下文章

SVG animateTransform 同时旋转和缩放同一个对象?

如何正确使用 animateTransform cx cy 值?

使用动画变换旋转地球 svg

CSS动画冻结

csharp AnimateTransform.cs

SVG入门