路径下的SVG圆圈移动(animateMotion)
SVG circle move(animateMotion) under the path
我必须编写一个代码,圆圈应该在一些低于 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 蒙版的另一个奇怪效果是,如果您正在为元素设置动画并将蒙版应用于正在设置动画的元素,那么蒙版将随元素一起移动。
考虑到第一部分很简单,只需在蒙版内添加一个 SVG 本身大小的白色矩形,并使用较小的黑色形状来蒙版。解决移动蒙版的方法是不将蒙版应用于动画元素,而是将蒙版应用于包裹动画元素的 <g>
标签。
如果您希望圆圈在 'under' 一个部分然后 'over' 相同的部分,那么您还需要在蒙版内做一些动画。在此示例中,我在蒙版的矩形子项(进行蒙版的黑色部分)内使用 animateTransform
在圆圈通过 'under' 桥后将其缩小,您可以轻松地使用 CSS 关键帧。
我强烈建议您也减少视图框,因为与可用的 space 相比,您的视觉元素太小了,在我刚刚估计的示例中,但最好的方法是重新渲染您的图形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>
我必须编写一个代码,圆圈应该在一些低于 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 蒙版的另一个奇怪效果是,如果您正在为元素设置动画并将蒙版应用于正在设置动画的元素,那么蒙版将随元素一起移动。
考虑到第一部分很简单,只需在蒙版内添加一个 SVG 本身大小的白色矩形,并使用较小的黑色形状来蒙版。解决移动蒙版的方法是不将蒙版应用于动画元素,而是将蒙版应用于包裹动画元素的 <g>
标签。
如果您希望圆圈在 'under' 一个部分然后 'over' 相同的部分,那么您还需要在蒙版内做一些动画。在此示例中,我在蒙版的矩形子项(进行蒙版的黑色部分)内使用 animateTransform
在圆圈通过 'under' 桥后将其缩小,您可以轻松地使用 CSS 关键帧。
我强烈建议您也减少视图框,因为与可用的 space 相比,您的视觉元素太小了,在我刚刚估计的示例中,但最好的方法是重新渲染您的图形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>