Search code examples
svgsvg-animate

Staggering animation of SVG markers


Is it possible to stagger the animation of SVG markers to sync up with a line animation, i.e. so the markers become visible at the same time the line becomes visible behind it?

I've tried targeting the markers individually like this (below) which was unsuccessful:

.marker-circle:nth-child(1) {
  animation-delay: 200ms;
}

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 800 800">
  
 <defs>
   <marker class="marker" id="marker" markerWidth="4" markerHeight="4" refX="2" refY="2">
   <circle class="marker-circle" cx="2" cy="2" r="2" />
   </marker>
  </defs>
<style type="text/css">

.line {
  fill:none;
  fill-opacity:0.46;
  stroke:#3BB0FF;
  stroke-width:8;
  stroke-miterlimit:10;
  stroke-dasharray: 2000;
  stroke-dashoffset: 2000;
  animation: draw 5s infinite;
}

@keyframes draw {
  from {
    stroke-dashoffset: 2000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
   
   
.marker-circle {
  fill:#FF4F4F;
  fill-opacity:0.0;
  background-color: red;
  animation-name: example;
  animation: example 5s infinite;
}

@keyframes example {
  from {fill-opacity:0.0;}
  to {fill-opacity:1.0;}
}


.marker-circle:nth-child(1) {
  animation-delay: 200ms;
}

.marker-circle:nth-child(2) {
  animation-delay: 400ms;
}

.marker-circle:nth-child(3) {
  animation-delay: 600ms;
}

.marker-circle:nth-child(4) {
  animation-delay: 800ms;
}

.marker-circle:nth-child(5) {
  animation-delay: 1000ms;
}

.marker-circle:nth-child(6) {
  animation-delay: 1200ms;
}

.marker-circle:nth-child(7) {
  animation-delay: 1400ms;
}

.marker-circle:nth-child(8) {
  animation-delay: 1600ms;
}
    

</style>
<polygon class="line" points="266.14,191.92 471.86,127.15 530.52,302.39 666.14,388.49 550.33,633.06 225.76,580.49 359.86,363.34 
    153.38,388.49" marker-start="url(#marker)" marker-mid="url(#marker)"/>
</svg>


Solution

  • You could create a mask that "reveals" the polygone.

    .line {
      fill:none;
      fill-opacity:0.46;
      stroke:#3BB0FF;
      stroke-width:8;
      stroke-miterlimit:10;
    }
    .linem {
      fill:none;
      fill-opacity:0.46;
      stroke:white;
      stroke-width:32;
      stroke-linejoin: round;
      stroke-linecap: round;
      stroke-dasharray: 2000;
      stroke-dashoffset: 2000;
      animation: draw 5s infinite linear;
    }
    
    @keyframes draw {
      from {
        stroke-dashoffset: 2000;
      }
      to {
        stroke-dashoffset: 0;
      }
    }
       
       
    .marker-circle {
      fill:#FF4F4F;
      fill-opacity:1;
      background-color: red;
    }
    <svg xmlns="http://www.w3.org/2000/svg" width="300" viewBox="0 0 800 800">
      <defs>
        <marker class="marker" id="marker" markerWidth="4"
          markerHeight="4" refX="2" refY="2">
          <circle class="marker-circle" cx="2" cy="2" r="2" />
        </marker>
        <mask id="m1">
          <polygon class="linem" points="266.14,191.92 471.86,127.15 530.52,302.39 666.14,388.49 550.33,633.06 225.76,580.49 359.86,363.34 153.38,388.49"
            pathLength="2000" stroke="white"/>
        </mask>
      </defs>
      <polygon class="line" mask="url(#m1)"
        points="266.14,191.92 471.86,127.15 530.52,302.39 666.14,388.49 550.33,633.06 225.76,580.49 359.86,363.34 153.38,388.49"
        marker-start="url(#marker)" marker-mid="url(#marker)" pathLength="2000" />
    </svg>