(function () { var _ = this._ || require('underscore'); var TWEEN = this.TWEEN || require('tween'); var async = this.async || require('async'); // see: http://jakearchibald.com/2013/animated-line-drawing-svg/ function Path(el, options) { options || (options = {}); _.defaults(options, { duration: 1000 }); this.options = options; this.el = el; var length = el.getTotalLength(); this.length = length; // Set up the starting positions el.style.strokeDasharray = length + ' ' + length; el.style.strokeDashoffset = length; this.update(1); } Path.prototype.update = function (val) { this.val = val; }; Path.prototype.paint = function () { this.el.style.strokeDashoffset = this.length * (1 - this.val); }; Path.prototype.start = function (cb) { this.tween && this.tween.stop(); var o = {t: 0}; this.tween = new TWEEN.Tween(o).to({t: 1}, this.options.duration) .onUpdate(function () { this.update(o.t); this.paint(); }.bind(this)) .onComplete(function () { //console.log('complete'); cb(null); }) .start() ; }; Path.prototype.stop = function () { this.tween && this.tween.stop(); }; Path.prototype.erase = function () { this.stop(); this.tween = undefined; this.update(0); this.paint(); }; function Scribble(pathsEls, options) { options || (options = {}); _.defaults(options, { duration: 2000, durationPerPath: false }); this.options = options; var paths = []; this.paths = paths; var arr = []; this.arr = arr; var i = pathsEls.length; var totalLength = 0; while(i--) { var path = new Path(pathsEls[i], {duration: this.options.duration}); paths.push(path); arr.push(path.start.bind(path)); totalLength += path.length; } // normalize duration if (this.options.durationPerPath !== true) { var totalDuration = this.options.duration; var i = pathsEls.length; while (i--) { var path = paths[i]; var percent = paths[i].length / totalLength; //if (percent > 2*1/pathsEls.length) continue; paths[i].options.duration = percent * totalDuration; } } var drawing = false; } Scribble.prototype.draw = function (cb) { if (this.drawing) return; this.drawing = true; async.series(this.arr, cb); // https://github.com/caolan/async#seriestasks-callback }; Scribble.prototype.erase = function () { this.paths.forEach(function (path) { path.erase(); }); this.drawing = false; }; // Exports this.Scribble = Scribble; if (typeof module !== "undefined" && module !== null) { module.exports = this.Scribble; } }).call(this);