UNPKG

algoframe

Version:

A TypeScript comprehensive and modulated libary for doing algebraic animation with requestAnimatioFrame natively, even with Bezier and Sequences

148 lines (147 loc) 6.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Animate = exports.Sequence = exports.sensibility = void 0; const timeline_1 = require("./timeline"); Object.defineProperty(exports, "Sequence", { enumerable: true, get: function () { return timeline_1.Sequence; } }); const utils_1 = require("./utils"); exports.sensibility = 0.9; class Animate { constructor(options) { // Frame properties this.frame = new utils_1.Framer(); this.control = new utils_1.Controller(); this.progress = 0; // Engine this.engine = new utils_1.Animator(this); const { sequence, easing, controls, timing } = options; this.engine.easing = (0, utils_1.passPreset)(easing ? easing : 'linear'); this.frame.sequence = sequence; if (controls === null || controls === void 0 ? void 0 : controls.FPS) this.frame.FPS = controls.FPS; // also implicitily declares Framer._precision if (controls === null || controls === void 0 ? void 0 : controls.loop) this.control.loop = controls.loop; this.frame.start.time = (timing === null || timing === void 0 ? void 0 : timing.delay) || 0; this.frame.duration = (timing === null || timing === void 0 ? void 0 : timing.duration) || sequence.duration; } finally(callback) { this.control.finally = callback; return this; } break() { this.control.stop = false; return this; } precision(value) { this.frame.precision = value; return this; } run(callback) { if (this.frame.sequence.duration !== this.frame.duration) this.frame.duration = this.frame.sequence.duration; let condition, seg; if (callback) { this.control.callback = callback; } // if (!this.control.callback) // throw new Error('Main callback is required for the animation'); this.frame.last.time = new utils_1.Refresher(); this.frame.last.frameRate = this.frame.last.frameRate ? this.frame.last.frameRate : new utils_1.Refresher(this.frame.precision); function refresh(timestamp) { if (this.control.completed) { this.frame.frame = -1; this.frame.start.animationTime = timestamp; this.control.completed = false; } if (this.frame._FPS) { seg = Math.floor((timestamp - this.frame.start.time) / this.frame.delay); condition = Boolean(seg > this.frame.count); } else { condition = true; } this.frame.last.time.refresh(timestamp); } function animate(timestamp) { var _a, _b, _c, _d, _e, _f; refresh.call(this, timestamp); let runtime = null, relativeProgress = null, easedProgress = null; this.control.sent = false; const send = () => { var _a, _b, _c, _d; this.control.sent = true; this.frame.value = this.frame.sequence.test(Math.min(easedProgress, 1)); if (this.frame.value > 100) { debugger; } // TODO: Add a recursvie callback inside Sequence (_b = (_a = this.frame.sequence).callback) === null || _b === void 0 ? void 0 : _b.call(_a, this.frame.stats()); // console.log(this.frame.sequence) // END (_d = (_c = this.control).callback) === null || _d === void 0 ? void 0 : _d.call(_c, this.frame.stats()); }; // console.log(this.frame.start.time); if (!this.frame.start.animationTime && this.frame.start.time === 0) { this.frame.start.animationTime = timestamp; } else if (this.frame.start.time > 0) { this.frame.start.animationTime = timestamp; let last = 0; if (typeof this.frame.last.time.last === 'number') { last = this.frame.last.time.last; } this.frame.start.time = this.frame.start.time - last < last * exports.sensibility ? 0 : this.frame.start.time - last; requestAnimationFrame(animate.bind(this)); return; } if (this.frame.start.animationTime) { // console.log(this.frame.start.animationTime - timestamp); runtime = timestamp - this.frame.start.animationTime; relativeProgress = runtime / this.frame.duration; easedProgress = this.engine.easing(relativeProgress); this.progress = Math.min(easedProgress, 1); this.frame.progress = Math.min(easedProgress, 1); } if (condition) { this.frame.count = seg; this.frame.frame++; this.frame.last.frameRate.refresh(timestamp); send(); } if (!this.control.stop) { if (typeof runtime === 'number' && runtime < this.frame.duration) { requestAnimationFrame(animate.bind(this)); } else if (runtime && runtime + (typeof this.frame.last.time.last === 'number' ? this.frame.last.time.last : 0) > this.frame.duration) { this.frame.frame++; send(); this.control.completed = true; if (this.control.loop) requestAnimationFrame(animate.bind(this)); (_b = (_a = this.control).finally) === null || _b === void 0 ? void 0 : _b.call(_a); // this.frame.sequence.ofinallyCallback?.(); } else if (!this.control.completed) { this.control.completed = true; if (this.control.loop) requestAnimationFrame(animate.bind(this)); (_d = (_c = this.control).finally) === null || _d === void 0 ? void 0 : _d.call(_c); (_f = (_e = this.frame.sequence).ofinallyCallback) === null || _f === void 0 ? void 0 : _f.call(_e); } } if (this.frame.frame === 0) this.control._start(); } requestAnimationFrame(animate.bind(this)); return this; } } exports.Animate = Animate;