Search code examples
animationsvgsvg-animate

How to animation to all path of SVG


I want to animate to a SVG and delay to any elements. Please see this link and lion SVG. The animation of this is simple but to delay to any path is very Time consuming.


Solution

  • It is pretty simple to recreate this effect.

    I didn't check to see how that site did it, but this is how I would do it.

    Firstly we need an SVG where all the paths are in a group (<g>);

    <svg>
      <g id="anim">
        <!-- path elements in here -->
      </g>
    </svg>
    

    On page load, we set a transform on the group that moves it (an all the paths) off the side of the SVG.

    group.setAttribute("transform", "translate(-100, 0)");
    

    Then, for the animation, we loop through all the <path> elements one by one (with a delay) adding a class that uses a transform to move the paths back on screen.

    .onto-screen-anim
    {
      transition: transform 1s ease-out;
      transform: translateX(100px);  /* 100 = width of viewBox */
    }
    

    The transition causes the path to slide in smoothly.


    Working demo

    var group = document.getElementById("anim");
    
    
    // Generate a lot of test paths in our SVG.
    // This is just for the demo as an alternative to having a big SVG in our snippet.
    for (var i=0; i<100; i++) {
      path = document.createElementNS("http://www.w3.org/2000/svg", "path");
      var r1 = 5 + Math.random() * 45;
      var r2 = 5 + Math.random() * 45;
      var a1 = Math.random() * 2 * Math.PI;
      var a2 = a1 + (Math.random() - 0.5);
      path.setAttribute("d", [
        'M', 50 + Math.cos(a1) * r1, 50 + Math.sin(a1) * r1,
        'L', 50 + Math.cos(a2) * r2, 50 + Math.sin(a2) * r2,
      ].join(' '));
      group.appendChild(path);
    }
    
    
    // Add a transform to the<svg> root element to move all the child
    // elements off the left edge of the SVG where we want them to start.
    // The value 100 represents the width of the viewBox.
    group.setAttribute("transform", "translate(-100, 0)");
    
    
    // For our animation, just loop through all paths, adding the 
    // "onto-screen-anim" class that moves them back into view.
    
    var INTER_PATH_DELAY = 16;   // 10 milliseconds
    
    var allPaths = group.querySelectorAll("path");
    var itemNum = 0;
    function startOnePathMoving() {
      // Add the class that moves the path onto screen
      allPaths[itemNum++].classList.add("onto-screen-anim");
      // if there are paths left, then call this function again
      // after a short delay to start the next one moving
      if (itemNum < allPaths.length)
        setTimeout(startOnePathMoving, INTER_PATH_DELAY);
    }
    
    // Start the first timeout to get the animation started
    setTimeout(startOnePathMoving, INTER_PATH_DELAY);
    /* Make sure the paths that are off the SVG can't be seen */
    svg {
      overflow: hidden;
    }
    
    /* The class that moves the paths back onto screen */
    .onto-screen-anim
    {
      transition: transform 1s ease-out;
      transform: translateX(100px);  /* 100 = width of viewBox */
    }
    
    /* Styling for our demo paths. You can ignore this for a real SVG */
    path {
      fill: none;
      stroke: grey;
      stroke-width: 0.5;
    }
    <svg width="400" height="400" viewBox="0 0 100 100">
      <g id="anim"></g>
    </svg>