2012-04-09 144 views
1

我试图使用SVG <set>标记对动画进行动画翻转,但即使指定了dur =“1s”,转换也是即时的(在Firefox,Safari,Opera和Chrome中)。SVG <set>标记的dur属性不生成

<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规范?有没有更好的方法来解决这个问题?

+1

摄制情况:http://jsfiddle.net/4xx5p/(这是在Safari以及Firefox的真) – Phrogz 2012-04-10 00:59:59

+0

感谢您验证它不会在Safari工作,要么;我刚刚在Opera和Chrome中进行了测试,我也在那里得到了相同的行为。 – yasashiku 2012-04-10 03:55:33

回答

3

SVG 1.1 Specification描述:

的“设置”元件提供的一个简单的装置只设置属性的指定的持续时间的值。
...
to = "<value>"在'set'元素的持续期间指定属性的值

(重点煤矿。)

正如你所看到的,<set>元素的duration是不是一个过渡时间,但效果相当多长时间才能被应用。如果您删除end属性,您将看到颜色从红色变为绿色,持续1秒and then revert为原始值。

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


编辑:下面是使用自定义数据来注释SVG元素,并使用该数据来创建你想要的<animate>元素,基于元素的填充一次性执行的脚本的例子。您可以查看这个例子住在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> 
+0

谢谢;关于如何在没有初始颜色的先验知识的情况下恢复原状的想法? – yasashiku 2012-04-10 04:08:29

+0

@yasashiku个人而言,我只是JS要么控制颜色,要么(更简单)根据属性动态地创建''元素。如果这是你的一个选择(如果JS可用),你需要帮助,我可以修改我的答案的细节。 – Phrogz 2012-04-10 12:09:26

+1

...不要说,我已经创建了一个例子,并且无论如何编辑了这个问题。希望这有助于。 – Phrogz 2012-04-10 12:39:26

1

使用“价值观”和“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>