【问题标题】:SVG circle move(animateMotion) under the path路径下的SVG圆形移动(animateMotion)
【发布时间】:2021-07-25 10:58:55
【问题描述】:

我必须编写一个代码,圈子应该在一些路径下,下面是 SVG

<g>
    <g>
        <path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13"/>
    </g>
    <g>
        <path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13"/>
    </g>
</g>

<circle r="20" fill="blue">
    <animateMotion dur="5s" repeatCount="indefinite"
      path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13" />

https://codepen.io/lzwdct/pen/poRYVXZ

想象路径就像车道,而圆圈经过路径下方(如桥),它不应该出现在桥下。

有什么方法可以实现吗?

【问题讨论】:

标签: svg svg-animate svg-animationelements


【解决方案1】:

SVG 蒙版的工作方式有点奇怪。它所应用的元素只会在遮罩为白色的地方渲染,而在遮罩为黑色(或只是不是白色)的地方,它将被隐藏。 SVG 蒙版的另一个奇怪效果是,如果您正在为元素设置动画并将蒙版应用于正在设置动画的元素,则蒙版将随元素一起移动。

考虑到第一部分很简单,只需在蒙版内添加一个与 SVG 本身大小相同的白色矩形,并使用较小的黑色形状进行蒙版。解决移动遮罩的方法是将遮罩应用到动画元素而不是 &lt;g&gt; 标记,该标签包裹了动画元素。

但是,如果您希望圆圈“在”某个部分“下方”然后“在”同一部分“上方”,那么您还需要在蒙版内进行一些动画处理。在此示例中,我在蒙版的 rect 子项(进行蒙版的黑色部分)内使用 animateTransform 在圆圈通过“桥下”后将其缩小,但您也可以轻松地使用 CSS 关键帧。

我强烈建议您也减少视图框,因为与可用空间相比,您的视觉元素非常小,在我刚刚估计的示例中,但最好的方法是在 Illustrator 中重新渲染您的图形并更好地裁剪画板到你的对象。

如果 SVG 将内联在 HTML 中,则不需要 Illustrator 生成的大多数附加标记。除了我的示例中显示的 viewBox 之外,您可能会丢失几乎所有内容,因为这些其他属性大多仅在 SVG 呈现为图像时使用,希望这会有所帮助。

svg {
  max-width: 500px;
}

.st0,
.st1 {
  fill: none;
  stroke: #8ea5ae;
  stroke-width: 50;
  stroke-miterlimit: 10;
}

.st1 {
  stroke-linecap: round
}

.st2 {
  fill: none;
  stroke: #758992;
  stroke-width: 50;
  stroke-miterlimit: 10;
}
<svg viewBox="0 0 1015 855">
  <mask id="myMask">
    <!--   Pixels under white are rendered   -->
    <rect x="0" y="0" width="1015" height="855" fill="white" />
    <!--   Pixels under black are hidden   -->
    <rect class="moveme" x="315" y="335" height="150" width="150" transform="rotate(45 395 395)">
      <animateTransform attributeName="transform"
                          attributeType="XML"
                          type="scale"
                          keyTimes="0; 0.25999; 0.26; 1"
                          values="1; 1; 0; 0"
                          dur="5s"
                          additive="sum"
                          repeatCount="indefinite"/>
    </rect>
  </mask>
  
  <path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13" />
  <path class="st1" d="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
            c29.29-29.29,76.78-29.29,106.07,0" />
  <path class="st2" d="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
            s179.15-68.34,247.49,0" />
  <path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91 c-48.89-48.89-128.09-48.95-176.91-0.13" />
  <path class="st2" d="M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07 s-76.78-29.29-106.07,0" />
  <path class="st1" d="M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49 s-179.15-68.34-247.49,0" />
  <!--   Group the circles and apply the mask to the group, not the circles   -->
  <g mask="url(#myMask)">
    <circle r="20" fill="blue">
      <animateMotion dur="5s" repeatCount="indefinite" path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13" />
    </circle>
    <circle r="20" fill="blue">
      <animateMotion dur="5s" repeatCount="indefinite" path="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
            s179.15-68.34,247.49,0 M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07
            s-76.78-29.29-106.07,0" />
    </circle>
    <circle r="20" fill="blue">
      <animateMotion dur="5s" repeatCount="indefinite" path="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
            c29.29-29.29,76.78-29.29,106.07,0 M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49
            s-179.15-68.34-247.49,0" />
    </circle>
  </g>
  
  <!-- uncomment the rect below to visualize the animation applied to the mask -->
  <!-- <rect x="315" y="335" height="150" width="150" fill="#f00" opacity=".1" transform="rotate(45 395 395)">
    <animateTransform attributeName="transform"
                          attributeType="XML"
                          type="scale"
                          keyTimes="0; 0.25999; 0.26; 1"
                          values="1; 1; 0; 0"
                          dur="5s"
                          additive="sum"
                          repeatCount="indefinite"/>
  </rect>-->

</svg>

【讨论】:

  • 太棒了……clip-path 的动画问题和蒙版一样吗?
  • 是的,如果它们直接应用于动画对象,它们都会随着动画对象移动。但两者都可以应用于父 &lt;g&gt; 标签来解决问题。然而,剪辑路径的工作方式与蒙版完全不同。 Sarah Drasner 解释得比我还好css-tricks.com/masking-vs-clipping-use
  • @JHeth 你能解释一下 animateTransform 中的值是什么意思吗?
  • 当然,valueskeyTimes 一起工作可以更好地控制动画事件的时间线。 keyTimes 属性对应于values 属性中的值。所以keyTimes 设置每个值的时间,values 提供在每个特定键时间应用的值序列。您可以在spec 中阅读有关这些属性的更多信息
  • 非常感谢@JHeth。我还发布了一个与此相关的新问题,您有解决此问题的想法吗? stackoverflow.com/questions/67513369/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
相关资源
最近更新 更多