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>

2 つのタグを使用して必要な効果を実現<animate>できますが、保存したい初期色が異なる可能性がある複数の要素にトランジションを適用できるようにしたいと考えています (この方法では、最初の色「赤」を2 番目のアニメーション タグ)。

<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' 要素は、指定された期間の属性の値を設定するだけの簡単な手段を提供します。 …<br> 「set」要素の期間中の属性の値を指定します。
to = "<value>"

(私のものを強調してください。)

ご覧のとおりduration<set>要素の は遷移時間ではなく、効果が適用される時間です。属性を削除するとend、色が赤から緑に 1 秒間変化した後、元の値に戻ります。

詳細については、 SMIL 仕様<set>の要素についてお読みください。


編集<animate>:カスタムデータを使用してSVG要素に注釈を付ける例と、そのデータを使用して要素の塗りつぶしに基づいて必要な要素を作成する1回限りのスクリプトを次に示します。この例は、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 に答える