沿不同路径同步两个 SVG 动画
Sync two SVG animations along different paths
希望我解释正确。
我有两个脉冲动画,它们 运行 沿着两条不同的路径。我玩过动画的持续时间,但我似乎可以让它们在它们加入的地方“同步”,这样只有一个圆圈到达顶部。
这可能吗?
这是我的代码:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
viewBox="0 0 120 120"
version="1.1"
id="svg11"
sodipodi:docname="testAn.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs15" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1600"
inkscape:window-height="837"
id="namedview13"
showgrid="false"
inkscape:zoom="2.4857496"
inkscape:cx="201.80878"
inkscape:cy="187.12268"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg11" />
<g
id="g140"
transform="translate(35.662173,31.252367)">
<path
id="theMotionPath-sa"
d="M 10,10 V 40 H 52"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle119"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle121"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle123"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle125"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
</g>
<g
id="g57"
transform="translate(15.662173,36.252367)">
<path
id="theMotionPath-ch"
d="M 10,35 H 30 V 3"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle36"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle38"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle40"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle42"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
</g>
</svg>
希望这是有道理的!
你的主要问题是你的点以不同的速度移动,因为运动路径的长度不同。我认为最明智的解决方案是定义三个 单独的运动路径,一个用于左右腿,一个用于向上的腿。然后,为您的动画计时,使左右腿的动画 end 同时在中心点,并且 start 在向上的腿也是同样的时间。
这需要仔细规划运动速度和时间,并隐含地了解路径长度。为了更容易遵循推理,我已经解决了您的 SVG 的转换问题,并稍微重新定位和调整了路径的大小。另外,我已经反转了右腿的方向,这样你就不需要反转运动的方向——省得你拼出 keyPoints
/keyTimes
属性。
这是我得到的:
id d length dur
theMotionPath-left M 25 70 H 45 20 1.5s
theMotionPath-right M 85 70 H 45 40 3s
theMotionPath-up M 45 70 V 40 30 2s
不同腿的速度确实完全匹配,只是近似匹配。但这并没有威慑力,重要的是所有点 reach/leave 每一秒都是中心点。
但是左腿有问题。 repeatCount="indefinite"
表示动画结束后立即重新开始。从 1.5 秒开始的运动将在 3 秒结束,然后在 4.5 秒、6 秒、7.5 秒后再次运动,......每秒钟运动将 不 根据需要与其他部分匹配。
解决这个问题的方法是在每个动画开始之间增加一个延迟:运行 1.5 秒,等待 1.5 秒,再次 运行 等。
这可以用一个技巧来完成。可以 bind the start of an animation to the end of another animation - 或同一动画的不同 运行。省略 repeatCount
属性,但定义 list begin
次:
<animateMotion id="leftDot1" dur="1.5s" begin="1.5s;leftDot1.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
1.5s后,第一次启动动画,另外每次id为leftDot1
的动画(本身)结束,等待1.5s,然后再次启动。
<svg width="300" height="300" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path id="theMotionPath-left" d="M 25 70 H 45"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot1" dur="1.5s" begin="1.5s;leftDot1.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot2" dur="1.5s" begin="2.5s;leftDot2.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot3" dur="1.5s" begin="3.5s;leftDot3.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
</g>
<g>
<path id="theMotionPath-right" d="M 85 70 H 45"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="0s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="1s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="2s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
</g>
<g>
<path id="theMotionPath-up" d="M 45 70 V 40"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="2s" begin="3s">
<mpath xlink:href="#theMotionPath-up" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="2s" begin="4s">
<mpath xlink:href="#theMotionPath-up" />
</animateMotion>
</circle>
</g>
</svg>
只是根据@ccprog 的回答构建,您还可以使用 keyTimes
和 keyPoints
来改变水平和垂直部分的动画速度。您需要了解几件事:
首先,需要将#theMotionPath-ch
的d
属性设置为d="M 10,35 H 30 V 5"
,使其到达与另一条路径相同的垂直点
然后,计算每条路径相对于其长度变化的点:#theMotionPath-sa
中的0.4167和#theMotionPath-ch
中的0.4。
最后加一个keyTime
(我设置在0.6
,意思是在0.6 * 3s = 1.8s
和前面对应的keyPoint
步骤。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
viewBox="0 0 120 120"
version="1.1"
id="svg11"
sodipodi:docname="testAn.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs15" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1600"
inkscape:window-height="837"
id="namedview13"
showgrid="false"
inkscape:zoom="2.4857496"
inkscape:cx="201.80878"
inkscape:cy="187.12268"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg11" />
<g
id="g140"
transform="translate(35.662173,31.252367)">
<path
id="theMotionPath-sa"
d="M 10,10 V 40 H 52"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle119"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle121"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle123"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle125"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
</g>
<g
id="g57"
transform="translate(15.662173,36.252367)">
<path
id="theMotionPath-ch"
d="M 10,35 H 30 V 5"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle36"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle38"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle40"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle42"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
</g>
</svg>
看了例子后我想到只要每个动画的时间保持不变并且 的间隔每个动画 运行 也保持不变那么路径不会有任何区别。唯一会改变的是动画的速度。
这是另一个示例:
<svg width="300" height="300" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- Edit This Path . -->
<path d="M 10,60 H 60 " stroke="#4789D0" stroke-width="1" fill="none" id="M-Right"/>
<path d="M 60,60 v -50 " stroke="#4789D0" stroke-width="1" fill="none" id="M-Up"/>
<path d="M 60,60 h 30" stroke="#4789D0" stroke-width="1" fill="none" id="M-Left"/>
<!-- Here is a green circle which will be moved along the motion path. -->
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c1" begin='0s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c2" begin='1s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c3" begin='2s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c4" begin='3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc1" begin='c1.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc2" begin='c2.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc3" begin='c3.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc4" begin='c4.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc1" begin='c1.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc2" begin='c2.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc3" begin='c3.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc4" begin='c4.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
</svg>
您可以编辑长度,但它仍会保持同步
希望我解释正确。 我有两个脉冲动画,它们 运行 沿着两条不同的路径。我玩过动画的持续时间,但我似乎可以让它们在它们加入的地方“同步”,这样只有一个圆圈到达顶部。 这可能吗?
这是我的代码:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
viewBox="0 0 120 120"
version="1.1"
id="svg11"
sodipodi:docname="testAn.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs15" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1600"
inkscape:window-height="837"
id="namedview13"
showgrid="false"
inkscape:zoom="2.4857496"
inkscape:cx="201.80878"
inkscape:cy="187.12268"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg11" />
<g
id="g140"
transform="translate(35.662173,31.252367)">
<path
id="theMotionPath-sa"
d="M 10,10 V 40 H 52"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle119"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle121"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle123"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle125"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="1;0"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
</g>
<g
id="g57"
transform="translate(15.662173,36.252367)">
<path
id="theMotionPath-ch"
d="M 10,35 H 30 V 3"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle36"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle38"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle40"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle42"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;1"
calcMode="linear"
keyPoints="0;1"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
</g>
</svg>
希望这是有道理的!
你的主要问题是你的点以不同的速度移动,因为运动路径的长度不同。我认为最明智的解决方案是定义三个 单独的运动路径,一个用于左右腿,一个用于向上的腿。然后,为您的动画计时,使左右腿的动画 end 同时在中心点,并且 start 在向上的腿也是同样的时间。
这需要仔细规划运动速度和时间,并隐含地了解路径长度。为了更容易遵循推理,我已经解决了您的 SVG 的转换问题,并稍微重新定位和调整了路径的大小。另外,我已经反转了右腿的方向,这样你就不需要反转运动的方向——省得你拼出 keyPoints
/keyTimes
属性。
这是我得到的:
id d length dur
theMotionPath-left M 25 70 H 45 20 1.5s
theMotionPath-right M 85 70 H 45 40 3s
theMotionPath-up M 45 70 V 40 30 2s
不同腿的速度确实完全匹配,只是近似匹配。但这并没有威慑力,重要的是所有点 reach/leave 每一秒都是中心点。
但是左腿有问题。 repeatCount="indefinite"
表示动画结束后立即重新开始。从 1.5 秒开始的运动将在 3 秒结束,然后在 4.5 秒、6 秒、7.5 秒后再次运动,......每秒钟运动将 不 根据需要与其他部分匹配。
解决这个问题的方法是在每个动画开始之间增加一个延迟:运行 1.5 秒,等待 1.5 秒,再次 运行 等。
这可以用一个技巧来完成。可以 bind the start of an animation to the end of another animation - 或同一动画的不同 运行。省略 repeatCount
属性,但定义 list begin
次:
<animateMotion id="leftDot1" dur="1.5s" begin="1.5s;leftDot1.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
1.5s后,第一次启动动画,另外每次id为leftDot1
的动画(本身)结束,等待1.5s,然后再次启动。
<svg width="300" height="300" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path id="theMotionPath-left" d="M 25 70 H 45"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot1" dur="1.5s" begin="1.5s;leftDot1.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot2" dur="1.5s" begin="2.5s;leftDot2.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion id="leftDot3" dur="1.5s" begin="3.5s;leftDot3.end + 1.5s">
<mpath xlink:href="#theMotionPath-left" />
</animateMotion>
</circle>
</g>
<g>
<path id="theMotionPath-right" d="M 85 70 H 45"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="0s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="1s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="3s" begin="2s">
<mpath xlink:href="#theMotionPath-right" />
</animateMotion>
</circle>
</g>
<g>
<path id="theMotionPath-up" d="M 45 70 V 40"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="2s" begin="3s">
<mpath xlink:href="#theMotionPath-up" />
</animateMotion>
</circle>
<circle r="2" cy="0" cx="0" style="fill:#4789d0">
<animateMotion repeatCount="indefinite" dur="2s" begin="4s">
<mpath xlink:href="#theMotionPath-up" />
</animateMotion>
</circle>
</g>
</svg>
只是根据@ccprog 的回答构建,您还可以使用 keyTimes
和 keyPoints
来改变水平和垂直部分的动画速度。您需要了解几件事:
首先,需要将
#theMotionPath-ch
的d
属性设置为d="M 10,35 H 30 V 5"
,使其到达与另一条路径相同的垂直点然后,计算每条路径相对于其长度变化的点:
#theMotionPath-sa
中的0.4167和#theMotionPath-ch
中的0.4。最后加一个
keyTime
(我设置在0.6
,意思是在0.6 * 3s = 1.8s
和前面对应的keyPoint
步骤。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
viewBox="0 0 120 120"
version="1.1"
id="svg11"
sodipodi:docname="testAn.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs15" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1600"
inkscape:window-height="837"
id="namedview13"
showgrid="false"
inkscape:zoom="2.4857496"
inkscape:cx="201.80878"
inkscape:cy="187.12268"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg11" />
<g
id="g140"
transform="translate(35.662173,31.252367)">
<path
id="theMotionPath-sa"
d="M 10,10 V 40 H 52"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle119"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle121"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle123"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
<circle
id="circle125"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="1;0.4167;0"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-sa" />
</animateMotion>
</circle>
</g>
<g
id="g57"
transform="translate(15.662173,36.252367)">
<path
id="theMotionPath-ch"
d="M 10,35 H 30 V 5"
inkscape:connector-curvature="0"
style="fill:none;stroke:#4789d0;stroke-width:1" />
<circle
id="circle36"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="0s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle38"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="1s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle40"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="2s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
<circle
id="circle42"
r="2"
cy="0"
cx="0"
style="fill:#4789d0">
<!-- Define the motion path animation -->
<animateMotion
keyTimes="0;0.6;1"
calcMode="linear"
keyPoints="0;0.40;1"
repeatCount="indefinite"
dur="3s"
begin="3s">
<mpath
xlink:href="#theMotionPath-ch" />
</animateMotion>
</circle>
</g>
</svg>
看了例子后我想到只要每个动画的时间保持不变并且 的间隔每个动画 运行 也保持不变那么路径不会有任何区别。唯一会改变的是动画的速度。
这是另一个示例:
<svg width="300" height="300" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- Edit This Path . -->
<path d="M 10,60 H 60 " stroke="#4789D0" stroke-width="1" fill="none" id="M-Right"/>
<path d="M 60,60 v -50 " stroke="#4789D0" stroke-width="1" fill="none" id="M-Up"/>
<path d="M 60,60 h 30" stroke="#4789D0" stroke-width="1" fill="none" id="M-Left"/>
<!-- Here is a green circle which will be moved along the motion path. -->
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c1" begin='0s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c2" begin='1s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c3" begin='2s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="c4" begin='3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Right"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc1" begin='c1.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc2" begin='c2.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc3" begin='c3.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="vc4" begin='c4.begin+3s' dur='3s' repeatCount="indefinite" keyPoints="0;1" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Up"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc1" begin='c1.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc2" begin='c2.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc3" begin='c3.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
<circle cx="" cy="" r="2" fill="#4789D0" >
<!-- Define the motion path animation -->
<animateMotion id="lc4" begin='c4.begin+0s' dur='3s' repeatCount="indefinite" keyPoints="1;0" calcMode="linear" keyTimes="0;1"> <mpath xlink:href="#M-Left"/> </animateMotion>
</circle>
</svg>
您可以编辑长度,但它仍会保持同步