【问题标题】:Every instance of <use xlink:href...> animates?<use xlink:href...> 的每个实例都有动画?
【发布时间】:2018-03-12 18:21:48
【问题描述】:

我正在使用“use xlink:ref”标签来渲染在“defs”标签中定义的折线并为其设置动画。我还想使用 xlink:ref 来渲染相同的折线,但没有动画,即仅作为静态对象。但是我渲染动画的“use xlink:ref”的所有三个实例,即使没有与其中两个关联的动画!?我怎样才能让它的三个实例中只有一个动画?我不明白为什么 SVG 认为我希望其他 2 个实例进行动画处理。感谢您的帮助!

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg   xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    width="600" height="600" viewBox="0 0 600 600">

  <defs>
  <marker id="mCircle" markerWidth="160" markerHeight="160" refX="80" refY="80" markerUnits="userSpaceOnUse">
  <circle cx="80" cy="80" r="70" style="fill: red; stroke: black; stroke-width: 5px; opacity:0.2"/>
  </marker>

  <marker id="mMid" markerWidth="100" markerHeight="100" refX="50" refY="50" markerUnits="userSpaceOnUse" >
  <circle cx="50" cy="50" r="6" style="fill: black; stroke: none; stroke-width:4px; opacity:1"/>
  </marker>

  <path d="M 0,0  60,0  120,0  180,0 240,0 300,0 360,0" id="linered" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6"/>
  </defs>

  <use xlink:href="#linered" transform="translate(120, 280)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:orange;"/>
  <animate
  xlink:href="#linered"
  attributename="d"
  dur="2s"
  begin="1s;"
  values=	"M 0 0,      60 0,     120 0,     180 0,     240 0,     300 0,    360 0;
           M 180 0,    60 40,    120 -30,   180 60,    240 220,   300 60,   180 0;
           M 180 0,    60 -33,   120 60,    180 -90,   240 70,    300 0,    180 0;
           M 180 0,    60 40,    120 -30,   180 60,    240 220,   300 60,   180 0;
           M 0 0,      60 0,     120 0,     180 0,     240 0,     300 0,    360 0;"

  keySplines= "0 0.8 0.3 1;     0 0.8 0.3 1;    0 0.8 0.3 1;    0 0.8 0.3 1;"
  keyTimes=  "0;    0.33;    0.5;    0.66;     1"
  calcMode="spline"        
  repeatcount="4"
  />

  <g transform="translate(300 280)">
    <use id="static1" xlink:href="#linered" x="-180" y="0" transform="rotate(60)"  style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:blue;"/>

    <use id="static2" xlink:href="#linered" x="-180" y="0" transform="rotate(120)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:white;"/>
  </g>

</svg>

【问题讨论】:

  • (作为独立文件使用,属性区分大小写。因此我已将markerunits 更正为markerUnits。)您在哪里看到动画?此代码是 Firefox 和 Chrome 上的静态图片。

标签: animation svg href xlink


【解决方案1】:

首先,您的代码中存在一些与属性中的大写字母有关的错误。虽然 Chrome 似乎更宽容一些(如 SVG v2 中定义的那样),但其他浏览器仍然坚持 SVG v1.1,在这方面完全兼容 XML。所以你应该始终使用区分大小写的markerUnitsattributeNamerepeatCount 属性。

您的主要问题是 您正在制作动画:

<animate xlink:href="#linered" attributeName="d" ... />

您的动画引用&lt;path id="linered" /&gt; 元素,这是每个&lt;use&gt; 派生的模板。它们每个都复制整个模板,包括它的动画。

请注意,您的&lt;animate&gt; 标签是其旁边的&lt;use&gt; 标签的兄弟。两者都是自闭合标签,除了它们在源代码中彼此相邻的位置之外,这两者之间没有任何联系 - 但这是偶然的。

元素与其动画之间的联系只能通过两种方式建立。

  1. &lt;animate&gt; 元素是动画元素的子元素(此语法不要使用 xlink:href 属性):
<path ...>
  <animate ... />
</path>
  1. &lt;animate&gt; 元素,位于同一 svg 片段中的任何位置,引用动画元素:
<path id="target"... />
<!-- other content -->
<animate xlink:href="#target" ... />

如果您想为一个 &lt;use&gt; 元素设置动画,而不是其他元素,则需要为该元素设置动画。例如,您可以为&lt;use&gt; 元素上设置的transform 属性设置动画。但是您要设置动画的d 属性是引用的&lt;path&gt; 元素的一部分。

&lt;use&gt; 元素不是它所引用的内容的替代品,但从概念上讲,它是一个将其引用副本隐藏在内部的容器(在所谓的 Shadow DOM 中)。此副本不能使用 url 或 CSS 选择器引用。它不能单独设置动画。

唯一的解决办法是分别写下要动画的元素(注意id):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg   xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="600" viewBox="0 0 600 600">

  <defs>
  <marker id="mCircle" markerWidth="160" markerHeight="160" refX="80" refY="80" markerUnits="userSpaceOnUse">
  <circle cx="80" cy="80" r="70" style="fill: red; stroke: black; stroke-width: 5px; opacity:0.2"/>
  </marker>

  <marker id="mMid" markerWidth="100" markerHeight="100" refX="50" refY="50" markerUnits="userSpaceOnUse" >
  <circle cx="50" cy="50" r="6" style="fill: black; stroke: none; stroke-width:4px; opacity:1"/>
  </marker>

  <path id="linered" d="M 0,0  60,0  120,0  180,0 240,0 300,0 360,0" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6"/>
  </defs>

  <path id="linered-animated" transform="translate(120, 280)" d="M 0,0  60,0  120,0  180,0 240,0 300,0 360,0" style="marker-start: url(#mCircle); marker-end: url(#mCircle); marker-mid: url(#mMid); stroke-width: 12; fill:none; stroke-linejoin:round; stroke-linecap:round; stroke-opacity: 0.6;stroke-dasharray:222; stroke-dashoffset:-70px; stroke:orange;"/>
  <animate
  xlink:href="#linered-animated"
  attributeName="d"
  dur="2s"
  begin="1s;"
  values=   "M 0 0,      60 0,     120 0,     180 0,     240 0,     300 0,    360 0;
       M 180 0,    60 40,    120 -30,   180 60,    240 220,   300 60,   180 0;
       M 180 0,    60 -33,   120 60,    180 -90,   240 70,    300 0,    180 0;
       M 180 0,    60 40,    120 -30,   180 60,    240 220,   300 60,   180 0;
       M 0 0,      60 0,     120 0,     180 0,     240 0,     300 0,    360 0;"

  keySplines="0 0.8 0.3 1;     0 0.8 0.3 1;    0 0.8 0.3 1;    0 0.8 0.3 1;"
  keyTimes= "0;    0.33;    0.5;    0.66;     1"
  calcMode="spline"        
  repeatCount="4"
  />

  <g transform="translate(300 280)">
<use id="static1" xlink:href="#linered" x="-180" y="0" transform="rotate(60)"  style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:blue;"/>

<use id="static2" xlink:href="#linered" x="-180" y="0" transform="rotate(120)" style="stroke-dasharray:222; stroke-dashoffset:-70px; stroke:white;"/>
  </g>

</svg>

仅作为脚注,&lt;animate&gt; 元素中的 xlink:href 属性似乎在 Firefox 中存在一个错误,即动画永远不会应用于引用 &lt;use&gt; 元素。

【讨论】:

  • 感谢您的帮助!
  • 谢谢!我只是在概念上仍然很难。 标签中只有路径属性(无动画)。奇怪的是,没有 标签的 标签会产生动画效果。我认为,由于它们引用了 标签中的路径——它没有动画——除非它们也有一个 标签,否则它们不会动画。如果它以这种方式工作,我可以对已定义路径的每个 应用不同的(或不使用)ani(就像我可以对每个应用 x 和 y 一样),而不是为每个 ani 创建冗余路径。我说得有道理吗?有没有一种简洁的方法来概念化这个?
  • 我把 标签放到 中。我希望这没关系,因为它有效,并且在概念上对我来说更清晰,因为它强烈暗示每个 标记都链接到 标记 xlinks 到的 中的路径将进行动画处理。我曾认为 标签嵌套在它们动画的 中。我刚刚意识到它们不是嵌套的,而是分开的。这让事情变得更清楚了......但我仍然希望它按我的方式工作:^)。再次感谢您的帮助和时间。
  • 在我的回答中详细阐述了这个概念。
猜你喜欢
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
相关资源
最近更新 更多