tweezer.js
Version:
A small, dependency-free, ES6 tweening library for smooth animations
132 lines (112 loc) • 4.67 kB
JavaScript
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var SingleTweener = function () {
function SingleTweener() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, SingleTweener);
this.start = opts.start;
this.end = opts.end;
this.decimal = opts.decimal;
}
_createClass(SingleTweener, [{
key: "getIntermediateValue",
value: function getIntermediateValue(tick) {
if (this.decimal) {
return tick;
} else {
return Math.round(tick);
}
}
}, {
key: "getFinalValue",
value: function getFinalValue() {
return this.end;
}
}]);
return SingleTweener;
}();
var _createClass$1 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Tweezer = function () {
function Tweezer() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck$1(this, Tweezer);
this.duration = opts.duration || 1000;
this.ease = opts.easing || this._defaultEase;
this.tweener = opts.tweener || new SingleTweener(opts);
this.start = this.tweener.start;
this.end = this.tweener.end;
this.frame = null;
this.next = null;
this.isRunning = false;
this.events = {};
this.direction = this.start < this.end ? 'up' : 'down';
}
_createClass$1(Tweezer, [{
key: 'begin',
value: function begin() {
if (!this.isRunning && this.next !== this.end) {
this.frame = window.requestAnimationFrame(this._tick.bind(this));
}
return this;
}
}, {
key: 'stop',
value: function stop() {
window.cancelAnimationFrame(this.frame);
this.isRunning = false;
this.frame = null;
this.timeStart = null;
this.next = null;
return this;
}
}, {
key: 'on',
value: function on(name, handler) {
this.events[name] = this.events[name] || [];
this.events[name].push(handler);
return this;
}
}, {
key: '_emit',
value: function _emit(name, val) {
var _this = this;
var e = this.events[name];
e && e.forEach(function (handler) {
return handler.call(_this, val);
});
}
}, {
key: '_tick',
value: function _tick(currentTime) {
this.isRunning = true;
var lastTick = this.next || this.start;
if (!this.timeStart) this.timeStart = currentTime;
this.timeElapsed = currentTime - this.timeStart;
this.next = this.ease(this.timeElapsed, this.start, this.end - this.start, this.duration);
if (this._shouldTick(lastTick)) {
this._emit('tick', this.tweener.getIntermediateValue(this.next));
this.frame = window.requestAnimationFrame(this._tick.bind(this));
} else {
this._emit('tick', this.tweener.getFinalValue());
this._emit('done', null);
}
}
}, {
key: '_shouldTick',
value: function _shouldTick(lastTick) {
return {
up: this.next < this.end && lastTick <= this.next,
down: this.next > this.end && lastTick >= this.next
}[this.direction];
}
}, {
key: '_defaultEase',
value: function _defaultEase(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * (--t * (t - 2) - 1) + b;
}
}]);
return Tweezer;
}();
export default Tweezer;