Search code examples
javascriptcsssvgsvg-animate

How to convert SVG CSS animation to pure JS code


I would like to convert an svg path animation, to a pure javascript one.

SVG code:

<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" width="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
    <path class="path" fill="#FFFFFF" stroke="#000000" stroke-width="4" stroke-miterlimit="10" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
C46.039,146.545,53.039,128.545,66.039,133.545z"/>
</svg>

CSS code:

.path {
    stroke-dasharray: 10 10;    /* 10px fill, 10px gap */
    -webkit-animation: dash 10s linear normal infinite;
}

@-webkit-keyframes dash {
  from {
      stroke-dashoffset: 1000;
  }
  to {
      stroke-dashoffset: 0;
  }
}

Here is the Fiddle


Solution

  • I'm not sure why you need pure javascript, also this answer may not fit your needs as it actually does create inline CSS. But here it is, mostly taken from : https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset

    function dashOffset() {
        var path = document.querySelector('.path');
        var length = "1000";
        // Clear any previous transition 
        path.style.transition = path.style.WebkitTransition = 'none';
        // Set up the starting positions 
        path.style.strokeDasharray = "10 10";
        path.style.strokeDashoffset = "1000";
        // Trigger a layout so styles are calculated & the browser 
        // picks up the starting position before animating 
        path.getBoundingClientRect();
        // Define our transition 
        path.style.transition = path.style.WebkitTransition = 'stroke-dashoffset 10s linear';
        //listener to restart our loop
        path.addEventListener('transitionend', dashOffset, false);
        // Go! 
        path.style.strokeDashoffset = '0';
    }
    dashOffset();
    <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" width="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
        <path class="path" fill="#FFFFFF" stroke="#000000" stroke-width="4" stroke-miterlimit="10" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
    	s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
    	C46.039,146.545,53.039,128.545,66.039,133.545z" />
    </svg>

    There is also the requestAnimationFrame way :

    function anim(){
        var path = document.querySelector('.path');
        path.style.strokeDasharray = "10 10";
        path.style.strokeDashoffset--;
        requestAnimationFrame(anim);
        }
    requestAnimationFrame(anim);
    

    function anim(){
            var path = document.querySelector('.path');
            path.style.strokeDasharray = "10 10";
            path.style.strokeDashoffset--;
            requestAnimationFrame(anim);
            }
     requestAnimationFrame(anim);
    <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" width="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
        <path class="path" fill="#FFFFFF" stroke="#000000" stroke-width="4" stroke-miterlimit="10" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
    	s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
    	C46.039,146.545,53.039,128.545,66.039,133.545z" />
    </svg>

    Note that you may be able to reproduce it with the pure SVG animateMotion element.