UNPKG

scroll-to-element

Version:

Smooth scrolling to an element via selector or node reference

101 lines (82 loc) 2 kB
var ease = require('./ease'); var Emitter = require('./emitter'); function extend(obj, src) { for (var key in src) { if (src.hasOwnProperty(key)) obj[key] = src[key]; } return obj; } function Tween(obj) { if (!(this instanceof Tween)) return new Tween(obj); this._from = obj; this.ease('linear'); this.duration(500); } Emitter(Tween.prototype); Tween.prototype.reset = function(){ this.isArray = Object.prototype.toString.call(this._from) === '[object Array]'; this._curr = extend({}, this._from); this._done = false; this._start = Date.now(); return this; }; Tween.prototype.to = function(obj){ this.reset(); this._to = obj; return this; }; Tween.prototype.duration = function(ms){ this._duration = ms; return this; }; Tween.prototype.ease = function(fn){ fn = 'function' == typeof fn ? fn : ease[fn]; if (!fn) throw new TypeError('invalid easing function'); this._ease = fn; return this; }; Tween.prototype.stop = function(){ this.stopped = true; this._done = true; this.emit('stop'); this.emit('end'); return this; }; Tween.prototype.step = function(){ if (this._done) return; var duration = this._duration; var now = Date.now(); var delta = now - this._start; var done = delta >= duration; if (done) { this._from = this._to; this._update(this._to); this._done = true; this.emit('end'); return this; } var from = this._from; var to = this._to; var curr = this._curr; var fn = this._ease; var p = (now - this._start) / duration; var n = fn(p); if (this.isArray) { for (var i = 0; i < from.length; ++i) { curr[i] = from[i] + (to[i] - from[i]) * n; } this._update(curr); return this; } for (var k in from) { curr[k] = from[k] + (to[k] - from[k]) * n; } this._update(curr); return this; }; Tween.prototype.update = function(fn){ if (0 == arguments.length) return this.step(); this._update = fn; return this; }; module.exports = Tween;