1

我正在尝试使用 SVG<set>标签为翻转设置动画,但即使我指定了 dur="1s",过渡也是瞬时的(在 Firefox、Safari、Opera 和 Chrome 中)。

<html>
<body>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red">
        <set attributeType="CSS" attributeName="fill" to="green" begin="mouseover" end="mouseout" dur="1s" />
    </circle>
</svg> 

</body>
</html>

我可以使用两个<animate>标签来实现我想要的效果,但我希望能够将过渡应用于可能具有不同初始颜色的多个元素,我希望保留这些元素(此方法要求我在第二个动画标签)。

<html>
<body>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red">
        <animate attributeType="CSS" attributeName="fill" to="green" begin="mouseover" dur="1s" fill="freeze" />
        <animate attributeType="CSS" attributeName="fill" to="red" begin="mouseout" dur="1s" fill="freeze"/>
    </circle>
</svg> 

</body>
</html>

<set>一个代码段中的标记保留了初始颜色,但过渡没有动画。如果我对 w3 规范的理解是正确的,那应该是 - 这看起来像是特定于浏览器的错误,还是我误解了 w3 规范?有没有更好的方法来解决这个问题?

4

2 回答 2

3

SVG 1.1 规范中所述:

'set' 元素提供了一种简单的方法,可以在指定的 duration 内设置属性的值。 …<br> 指定'set' 元素持续期间的属性值。
to = "<value>"

(强调我的。)

如您所见,duration元素<set>的 不是过渡时间,而是要应用效果的时间。如果删除该end属性,您将看到颜色从红色变为绿色 1 秒钟,然后恢复为原始值。

有关更多详细信息,请阅读SMIL 规范<set>中的元素。


编辑<animate>:这是使用自定义数据注释 SVG 元素的示例,以及使用该数据根据元素填充创建所需元素的一次性脚本。您可以在http://phrogz.net/svg/change-color-on-hover.svg查看此示例

<svg xmlns="http://www.w3.org/2000/svg" xmlns:y="yasashiku" viewBox="0 0 240 150">
  <title>Change Color on Hover</title>
  <style>
    circle { stroke:black; stroke-width:2px }
    circle:not([fill]) { fill:purple }
  </style>
  <circle cx="50"  cy="50"  r="40" fill="red"    y:hoverAnimFillTo="blue"  y:hoverAnimDur="0.3s" />
  <circle cx="100" cy="100" r="40" fill="red"    y:hoverAnimFillTo="green" y:hoverAnimDur="1s" />
  <circle cx="150" cy="42"  r="40" fill="orange" y:hoverAnimFillTo="yellow" />
  <circle cx="200" cy="100" r="40"               y:hoverAnimFillTo="steelblue" />
  <script>
    var els = document.getElementsByTagName('*'),
        y   = 'yasashiku';
    for (var i=els.length;i--;){
      var fillColor = els[i].getAttributeNS(y,'hoverAnimFillTo');
      if (fillColor){
        var dur = els[i].getAttributeNS(y,'hoverAnimDur') || '0.1s';
        createOn(els[i],'animate',{
          begin:'mouseover',
          attributeType:'CSS', attributeName:'fill',
          to:fillColor,
          dur:dur, fill:'freeze'
        });
        createOn(els[i],'animate',{
          begin:'mouseout',
          attributeType:'CSS', attributeName:'fill',
          to:els[i].getAttribute('fill') || computedStyle(els[i],'fill'),
          dur:dur, fill:'freeze'
        });
      }
    }
    function createOn(el,name,attrs){
      var e = el.appendChild(document.createElementNS(el.namespaceURI,name));
      for (var name in attrs) e.setAttribute(name,attrs[name]);
      return e;
    }
    function computedStyle(el,name){
      return document.defaultView.getComputedStyle(el,null)[name];
    }
  </script>
</svg>
于 2012-04-10T04:05:40.083 回答
3

使用“values”和“KeyTimes”属性?

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red">
    <animate attributeType="CSS" attributeName="fill" values="red;green;green;red" keyTimes="0;0.2;0.8;1" begin="mouseover" dur="2s" fill="freeze" />
    <animate attributeType="CSS" attributeName="fill" to="red" begin="mouseout" dur="1s" fill="freeze"/>
  </circle>
</svg>  

于 2014-11-12T09:35:01.430 回答