【问题标题】:Click through series of images with SVG "animate"单击带有 SVG“动画”的一系列图像
【发布时间】:2017-05-10 08:14:43
【问题描述】:

假设我有一个包含几个顶级“g”元素的 SVG 图像,如下所示:

<svg>
<g id="id1">...</g>
<g id="id2">...</g>
<g id="id3">...</g>
...
</svg>

现在我想只显示开头带有id1 的那个,随着用户反复点击图像(类似于PowerPoint 演示文稿)滑过id2id3 等等。我尝试了这是第一步:

 <animate xlink:href="#id2" attributeName="opacity" from="0" to="0"  dur="0s" begin="0s"/>
 <animate xlink:href="#id3" attributeName="opacity" from="0" to="0"  dur="0s" begin="0s"/>
...

 <animate xlink:href="#id2" attributeName="opacity" from="0" to="100" dur="0.25s"  begin="click" id="anim1"/>
 <animate xlink:href="#id1" attributeName="opacity" from="100" to="0" dur="0.25s"  begin="anim1.begin" id="anim2"/>
...

第一行应该使除了id1 图像之外的所有图像都透明 - 这工作正常。接下来的两行应该使id1 透明并显示id2 - 这是行不通的。我假设具有较高 id 的透明图像位于较高级别(在 z 方向上)并阻止较低图像的点击事件。但我不知道如何让它们完全“消失”或其他什么。

也许还有更好的方法可以做到这一点......?

【问题讨论】:

  • 另外,如果我建议的方法有效,我真的不知道如何处理更多图像。所以也许有一种完全不同的方式来做到这一点......?
  • 就我个人而言,如果 JavaScript 可用的话,我会使用它,有一些库可以提供帮助,例如 Snap.svg 或 SVG.js。 Chrome 正在弃用它对 SVG Animate 的支持(它有一个 polyfill)。我认为正在推广的路线是针对 CSS 动画或 Javascript。 stackoverflow.com/questions/30965580/…
  • Javascript 不是一个选项,我必须使用 SVG。我有一个 SVG 图形框,这是我唯一可以进行更改的地方。它周围的所有 HTML 都是固定的。
  • 虽然,等等……这不是重点……你的意思是,我应该提供上面提到的 SVG 图像,然后使用 Javascript 来翻阅“g”?我可以做到……但那会怎样?我的 Javascript 很差...
  • 你需要something.click,其中something 是你点击的元素的id。 begin="click" 不起作用。

标签: animation svg


【解决方案1】:

您可以使用 SMIL 动画来做到这一点。对于每个状态,我们只需要几个 &lt;set&gt; 元素。两者中的每一个都由单击触发。一个显示下一组,另一个隐藏最后一组。

<svg>
  <g id="id1">
     <rect width="100%" height="100%" fill="red"/>
  </g>
  <g id="id2" display="none">
     <rect width="100%" height="100%" fill="orange"/>
  </g>
  <g id="id3" display="none">
     <rect width="100%" height="100%" fill="yellow"/>
  </g>
  <g id="id4" display="none">
     <rect width="100%" height="100%" fill="green"/>
  </g>

  <set xlink:href="#id2" attributeType="XML" attributeName="display" 
       to="block" begin="id1.click" />
  <set xlink:href="#id1" attributeType="XML" attributeName="display" 
       to="none" begin="id1.click" />

  <set xlink:href="#id3" attributeType="XML" attributeName="display" 
       to="block" begin="id2.click" />
  <set xlink:href="#id2" attributeType="XML" attributeName="display" 
       to="none" begin="id2.click" />

  <set xlink:href="#id4" attributeType="XML" attributeName="display" 
       to="block" begin="id3.click" />
  <set xlink:href="#id3" attributeType="XML" attributeName="display" 
       to="none" begin="id3.click" />

  <set xlink:href="#id1" attributeType="XML" attributeName="display" 
       to="block" begin="id4.click" />
  <set xlink:href="#id4" attributeType="XML" attributeName="display" 
       to="none" begin="id4.click"/>

</svg>

使用 Javascript 也很容易 - 也许更灵活。

// Get the SVG element
var mysvg = document.getElementById("mysvg");

// Get all the G elements that are children of our SVG
var groups = mysvg.querySelectorAll("g");

// Which G is currently shown
var current = 0;

// Show that G and hide the others
showGroup(current);

// Add the click event handler to the SVG
mysvg.addEventListener("click", groupSwitcher);



// Define the click handler that we will attach to the SVG.
function groupSwitcher(evt)
{
  // When we receive a click, select the next group
  current += 1;
  // Wrap naround to the beginning if we go past the last one
  if (current === groups.length)
    current = 0;
  
  // Show the new group (and hide the old one);
  showGroup(current);
}


// The function that shows one group and hides the others.
function showGroup(groupNumber)
{
  for (var i=0; i < groups.length; i++) {
    if (i === groupNumber) {
      // If this is the one we want to show then make it visible
      groups[i].setAttribute("visibility", "visible");
    } else {
      // It's one of the others, hide it
      groups[i].setAttribute("visibility", "hidden");
    }
  }
}
<svg id="mysvg">
  <g id="id1">
     <rect width="100%" height="100%" fill="red"/>
  </g>
  <g id="id2">
     <rect width="100%" height="100%" fill="orange"/>
  </g>
  <g id="id3">
     <rect width="100%" height="100%" fill="yellow"/>
  </g>
  <g id="id4">
     <rect width="100%" height="100%" fill="green"/>
  </g>
</svg>

【讨论】:

  • 对于 FF,问题是它不支持 0s 动画。而且它不默认为 fill="freeze",这是按照 1.1 规范(不知道 SVG2 也不知道) 0s)jsfiddle.net/5up5mztq
  • 如果您的持续时间为 0 秒,请使用 而不是
  • SVG 规范 SMIL 章节:dur... 指定呈现时间中的简单持续时间的长度。值必须大于 0。
  • 啊哈!感谢 Kaiido 和@Robert。我已经修复了 SMIL 版本。
  • 看起来不错,我试试看!谢谢!抱歉,由于缺乏声誉,无法投票给您...
猜你喜欢
  • 2020-08-01
  • 1970-01-01
  • 2014-06-06
  • 2013-08-19
  • 1970-01-01
  • 2016-01-12
  • 2012-04-19
  • 2013-12-25
  • 1970-01-01
相关资源
最近更新 更多