【问题标题】:How to create an animation from a sequence of SVG with identical element ids如何从具有相同元素 ID 的 SVG 序列创建动画
【发布时间】:2019-09-02 19:26:38
【问题描述】:

我正在尝试从一系列 SVG 文件创建一些 2D 动画。

所有 SVG 文件都具有相同数量的元素,并且所有对应的元素都具有相同的元素 id。我想创建动画,其中每个 svg 都被视为一个关键帧,并且通过在关键帧之间插入具有相同 id 的元素来生成动画。

我已经研究过使用 snap.svg,但我不确定如何跨不同的 svg 文件链接对象。

【问题讨论】:

  • 或许将它们依次显示为图像。
  • 我需要一个在帧之间平滑过渡的解决方案。
  • 如果您想将所有内容放在同一个文档中,您将需要唯一的 ID。
  • 您可以使用 Snap.load() 依次加载每个图像,但不能附加片段。抓取新图像片段中的路径字符串,并将原始图像动画到新路径字符串(即动画 d attr)。动画完成后,重复下一张图片(或将它们全部加载到创建路径字符串数组或其他内容中)。

标签: javascript svg snap.svg


【解决方案1】:

我会这样做:

  1. 我准备了一个 svg 根元素,在里面,一个在另外几个 svg 元素之上,每个元素都有 id

  2. 在 css 中我添加了这个:除非 svg 元素是目标 display: none;

svg > svg:not(:target) {
        display: none;
} 
  1. 假设您的 svg 文件是:https://domain/.../rects.svg,如果您想定位其中一个 svg 元素,请使用 svg 的 id,如下所示:https://domain/.../rects.svg#svg_id

这是根 svg 的样子:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="-50 -50 100 100">
  <defs>
   <rect id="theRect" x="-30" y="-30" width="60" height="60" fill="none" stroke="red"></rect> 
  </defs>
  <style type="text/css">
 <![CDATA[  
    svg > svg:not(:target) {
    display: none;
    }
     ]]> 
</style>


<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_0">
    <use xlink:href="#theRect" transform="rotate(0)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_1">
    <use xlink:href="#theRect" transform="rotate(6)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_2">
    <use xlink:href="#theRect" transform="rotate(12)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_3">
    <use xlink:href="#theRect" transform="rotate(18)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_4">
    <use xlink:href="#theRect" transform="rotate(24)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_5">
    <use xlink:href="#theRect" transform="rotate(30)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_6">
  <use xlink:href="#theRect" transform="rotate(36)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_7">
    <use xlink:href="#theRect" transform="rotate(42)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_8">
    <use xlink:href="#theRect" transform="rotate(48)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_9">
    <use xlink:href="#theRect" transform="rotate(54)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_10">
    <use xlink:href="#theRect" transform="rotate(60)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_11">
  <use xlink:href="#theRect" transform="rotate(66)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_12">
    <use xlink:href="#theRect" transform="rotate(72)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_13">
    <use xlink:href="#theRect" transform="rotate(78)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_14">
  <use xlink:href="#theRect" transform="rotate(84)"></use>
</svg>
</svg>

这就是我制作动画的方式:

let i = 0; 
function Frame(){
  let n = i % 15;
  requestAnimationFrame(Frame);
  theImg.setAttribute("src", `https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/rects.svg#_${n}`);
  i++
 }

Frame()
img{border:10px solid #d9d9d9}
&lt;img id="theImg" width="100" height="100" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/rects.svg#_0" /&gt;

粗略地说,由于所有这些 svg 元素都在同一个文件中,因此您将无法多次使用相同的 id。你需要独特的ids。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2017-06-13
    • 2018-11-02
    • 2017-06-09
    • 1970-01-01
    相关资源
    最近更新 更多