Skip to content

Instantly share code, notes, and snippets.

@eswak
Created February 19, 2015 21:17
Show Gist options
  • Select an option

  • Save eswak/35409a9f2ef30f35025d to your computer and use it in GitHub Desktop.

Select an option

Save eswak/35409a9f2ef30f35025d to your computer and use it in GitHub Desktop.

Revisions

  1. eswak created this gist Feb 19, 2015.
    63 changes: 63 additions & 0 deletions draw-svg.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    (function closure () {
    // progressively draw each <svg> without .no-draw class
    Array.prototype.forEach.call(document.querySelectorAll('svg:not(.no-draw)'), function(svg) {

    // animation duration & delay (default values overriden by data attributes)
    var animationTimeInSeconds = Number(svg.getAttribute('data-draw-time')) || 2;
    var animationStartDelay = Number(svg.getAttribute('data-draw-start-delay'))*1000 || 0;

    // init, hide all svgs
    var totalFrames = animationTimeInSeconds * 60;
    svg.style.display = 'none';

    // start to draw each <svg> after "data-draw-start-delay" (attribute) time (in seconds)
    setTimeout(function() {
    svg.style.display = 'inline-block';
    svg.id = svg.id || Math.random().toString(36).substring(2);

    // store paths in an array
    var paths = Array.prototype.slice.call(document.querySelectorAll('#' + svg.id + ' path'));

    // for each path
    paths.forEach(function(path, i) {
    var handle = 0;
    var l = path.getTotalLength();
    path.style.strokeDasharray = l + ' ' + l;
    path.style.strokeDashoffset = l;

    // start to draw them after a delay
    // ex: if <svg> is composed of 2 paths, and draws in 1s,
    // path 1 will start to draw immediatly and will be drawn in 500ms,
    // while path 2 will be drawn between 500ms and 1s
    setTimeout(function() {
    drawPath(path, l, 0, totalFrames/paths.length, handle, function() {
    // add .drawn class to every svg <path> that have been completely drawn
    path.classList.add('drawn');
    if (i === paths.length -1) {
    // add .all-paths-drawn class to <svg> dom element when all
    // its paths have been drawn
    svg.classList.add('all-paths-drawn');
    }
    });
    }, i*(animationTimeInSeconds/paths.length)*1000);

    });
    }, animationStartDelay);

    });

    function drawPath(path, pathLength, currentFrame, totalFrames, handle, drawn) {
    var progress = currentFrame/totalFrames;
    if (progress > 1) {
    window.clearTimeout(handle);
    path.style.strokeDashoffset = 0;
    drawn && drawn();
    } else {
    currentFrame++;
    path.style.strokeDashoffset = Math.floor(pathLength * (1 - progress));
    handle = window.setTimeout(function() {
    drawPath(path, pathLength, currentFrame, totalFrames, handle, drawn);
    }, 1000/60);
    }
    }
    })();