Search code examples
htmlanimationsvgsvg-animate

Hide SVG element halfway animation


I have a repeating 20-second svg animation. Halfway (10 seconds) it should abruptly hide one path-element called leftside. When the animation finishes and repeats, it should show the element again. How can I achieve this?

Right now, I got the first loop working. But the reset when the animation repeats isn't working unfortunately.

This is what I have:

<svg class="svg-object" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1923 643" preserveAspectRatio="xMinYMin meet">
  <path id="motionPath" fill="none" stroke="#000000" stroke-miterlimit="10"
    d="M1438.8,348.8c6.2,189.4-75.3,34.5-157.8,28.3c-515.1,38.8-757.8,54.5-849.3,72.8
    c-17.9,10.9-13.4,91.9-14.9,155.8"
  />
  <g id="vehicle">
    <path id="rightside" d="M13,2c-0.6,0-1-0.4-1-1s0.4-1,1-1s8,0.4,8,1S13.6,2,13,2z"/>
    <path id="leftside" d="M8,2C7.4,2,0,1.6,0,1s7.4-1,8-1s1,0.4,1,1S8.6,2,8,2z"/>
  </g>
  
  <animateMotion id="movement"
          xlink:href="#vehicle"
          dur="20s"
          begin="0;movement.end+4s"
          fill="freeze"
          keyPoints="0;1;0"
          keyTimes="0;0.5;1"
          calcMode="spline"
          keySplines= ".6 .01 .2 1; 0.6 .01 .2 1";
          >
    <mpath xlink:href="#motionPath" />
  </animateMotion>
  
  <animate xlink:href="#leftside" attributeName="opacity" from="1" to="0" dur="0.01s" begin="10s;movement.begin+10s;" repeatCount="indefinitive" fill="freeze" />
  <animate xlink:href="#leftside" attributeName="opacity" from="0" to="1" dur="0.01s" begin="movement.begin" repeatCount="indefinitive" fill="freeze" />

</svg>
       
      


Solution

  • This is hard to follow for me, but I got this solution:

    <svg class="svg-object" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1923 643" preserveAspectRatio="xMinYMin meet">
      <path id="motionPath" fill="none" stroke="#000000" stroke-miterlimit="10"
        d="M1438.8,348.8c6.2,189.4-75.3,34.5-157.8,28.3c-515.1,38.8-757.8,54.5-849.3,72.8
        c-17.9,10.9-13.4,91.9-14.9,155.8"
      />
      <g id="vehicle">
        <path id="rightside" d="M13,2c-0.6,0-1-0.4-1-1s0.4-1,1-1s8,0.4,8,1S13.6,2,13,2z"/>
        <path id="leftside" d="M8,2C7.4,2,0,1.6,0,1s7.4-1,8-1s1,0.4,1,1S8.6,2,8,2z"/>
      </g>
      
      <animateMotion id="movement"
              xlink:href="#vehicle"
              dur="20s"
              begin="0;movement.end+4s"
              fill="freeze"
              keyPoints="0;1;0"
              keyTimes="0;0.5;1"
              calcMode="spline"
              keySplines= ".6 .01 .2 1; 0.6 .01 .2 1";
              >
        <mpath xlink:href="#motionPath" />
      </animateMotion>
      
      <animate xlink:href="#leftside" attributeName="opacity" from="1" to="0" dur="0.01s" begin="movement.begin+10s; 20s"  fill="freeze" />
      <animate xlink:href="#leftside" attributeName="opacity" from="0" to="1" dur="0.01s" begin="movement.begin" fill="freeze" />
    </svg>
           
          

    A couple of points:

    • If you want to repeat the animation, the keyword is indefinite, not indefinitive.
    • You apparently wanted to set the leftside animation to indefinite. This would apply to the opacity animation itself, with a 0.01s duration. This means that, after being triggered, the animation would be repeating itself every 0.01s in a blinking pattern.
    • I believe the issue here is related to the interplay between both leftside animations, and which one has the preference at each time. However, it looks like a complex issue, and I do not understand it fully (explained here).