UNPKG

@clementroche/raf

Version:

This package implements a ticker using only one requestAnimationFrame

158 lines (136 loc) 3.85 kB
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } // https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js var Clock = /*#__PURE__*/function () { function Clock(autoStart) { _classCallCheck(this, Clock); this.autoStart = autoStart !== undefined ? autoStart : true; this.startTime = 0; this.oldTime = 0; this.elapsedTime = 0; this.running = false; } _createClass(Clock, [{ key: "start", value: function start() { this.startTime = (typeof performance === 'undefined' ? Date : performance).now(); // see #10732 this.oldTime = this.startTime; this.elapsedTime = 0; this.running = true; } }, { key: "stop", value: function stop() { this.getElapsedTime(); this.running = false; this.autoStart = false; } }, { key: "getElapsedTime", value: function getElapsedTime() { this.getDelta(); return this.elapsedTime; } }, { key: "getDelta", value: function getDelta() { var diff = 0; if (this.autoStart && !this.running) { this.start(); return 0; } if (this.running) { var newTime = (typeof performance === 'undefined' ? Date : performance).now(); diff = (newTime - this.oldTime) / 1000; this.oldTime = newTime; this.elapsedTime += diff; } return diff; } }]); return Clock; }(); var Raf = /*#__PURE__*/function () { function Raf() { var fps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 60; _classCallCheck(this, Raf); this.rafs = {}; this.clock = new Clock(); this.fps = fps; this.latest = 0; this.delta = 0; this.optimumDeltaTime = this.frameDuration / 1000; this.loop(); } _createClass(Raf, [{ key: "dispatch", value: function dispatch() { // clock var deltaTime = this.clock.getDelta(); var time = this.clock.getElapsedTime(); var lagSmoothing = deltaTime / (1000 / 60 / 1000); // callbacks Object.values(this.rafs).sort(function (a, b) { return a.priority - b.priority; }).forEach(function (raf) { raf.callback({ time: time, deltaTime: deltaTime, lagSmoothing: lagSmoothing }); }); } }, { key: "loop", value: function loop() { var now = performance.now(); this.delta = now - this.latest; if (this.delta > this.frameDuration) { this.dispatch(); } this.latest = now - this.delta % this.frameDuration; requestAnimationFrame(this.loop.bind(this)); } }, { key: "add", value: function add(id, callback) { var priority = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; if (this.rafs[id]) { return; } this.rafs[id] = { id: id, callback: callback, priority: priority }; } }, { key: "remove", value: function remove(id) { delete this.rafs[id]; } }, { key: "frameDuration", get: function get() { return 1000 / this.fps; } }]); return Raf; }(); export default Raf;