沿不同路径同步两个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>

希望这很有道理!

解决方法

您的主要问题是,由于运动路径的长度不同,因此点的移动速度不同。我认为最明智的解决方案是定义三个单独的运动路径,一个用于左腿和右腿,一个用于上腿。然后,对动画进行时间调整,以使动画在左腿和右腿同时在中心点结束,并在向上同时在 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

不同腿部的速度确实完美匹配,仅近似一致。但这并没有威慑力,重要的是所有点都在每秒钟达到/离开中心点。

不过,左腿有问题。 repeatCount="indefinite"表示动画在完成后立即重新开始。从1.5s开始的动作将在3s处结束,然后在4.5s,6s,7.5s等之后再次出现。。。每秒钟的动作会与其他部分匹配。

解决此问题的方法是在每个动画开始之间增加一个延迟:运行1.5秒,等待1.5秒,再次运行等。

这可以通过技巧来完成。可以bind the start of an animation to the end of another animation-或同一动画的不同运行。忽略repeatCount属性,但定义一个{em}列表 begin次:

      <animateMotion id="leftDot1" dur="1.5s" begin="1.5s;leftDot1.end + 1.5s">
        <mpath xlink:href="#theMotionPath-left" />
      </animateMotion>

1.5秒后,动画将首次开始播放,此外,每次ID为leftDot1(本身)的动画结束时,动画都会等待1.5秒,然后再次开始播放。

<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的答案开始构建,您还可以使用keyTimeskeyPoints来更改水平和垂直部分中动画的速度。您需要了解以下几点:

  • 首先,您需要将#theMotionPath-ch的{​​{1}}属性设置为d,以使其到达与其他路径相同的垂直点

  • 然后,计算每条路径相对于其长度变化的点:d="M 10,35 H 30 V 5"中为0.4167,#theMotionPath-sa中为0.4。

  • 最后,添加一个额外的#theMotionPath-ch(我将其设置为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>

您可以修改长度,但仍会保持同步

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...