@visactor/vrender-animate
Version:
This module provides a graph-based animation system for VRender.
146 lines (139 loc) • 5.87 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.DefaultTicker = void 0;
const vutils_1 = require("@visactor/vutils"), application_1 = require("@visactor/vrender-core/application"), performance_raf_1 = require("@visactor/vrender-core/common/performance-raf"), constant_1 = require("@visactor/vrender-core/event/constant");
require("@visactor/vrender-core/global");
const performanceRAF = new performance_raf_1.PerformanceRAF;
class RAFTickHandler {
constructor() {
this.released = !1;
}
tick(interval, cb) {
performanceRAF.addAnimationFrameCb((() => {
if (!this.released) return cb(this);
}));
}
release() {
this.released = !0;
}
getTime() {
return Date.now();
}
}
class DefaultTicker extends vutils_1.EventEmitter {
constructor(stage) {
super(), this.timelines = [], this.frameTimeHistory = [], this.handleTick = (handler, params) => {
const {once: once = !1} = null != params ? params : {};
if (this.ifCanStop()) return this.stop(), !1;
const currentTime = handler.getTime();
this._lastTickTime = currentTime, this.lastFrameTime < 0 && (this.lastFrameTime = currentTime - this.interval + this.timeOffset,
this.frameTimeHistory.push(this.lastFrameTime));
const delta = currentTime - this.lastFrameTime, skip = this.checkSkip(delta);
return skip || (this._handlerTick(delta), this.lastFrameTime = currentTime, this.frameTimeHistory.push(this.lastFrameTime)),
once || handler.tick(this.interval, this.handleTick), !skip;
}, this._handlerTick = delta => {
this.status === constant_1.STATUS.RUNNING && (this.tickCounts++, this.timelines.forEach((timeline => {
timeline.tick(delta);
})), this.emit("tick", delta));
}, this._handleGraphTick = () => {
this.initHandler(!1);
}, this.init(), this.lastFrameTime = -1, this.tickCounts = 0, this.stage = stage,
this.autoStop = !0, this.interval = 16, this.computeTimeOffsetAndJitter();
}
bindStage(stage) {
this.stage = stage;
}
computeTimeOffsetAndJitter() {
this.timeOffset = Math.floor(Math.random() * this.interval), this._jitter = Math.min(Math.max(.2 * this.interval, 6), .7 * this.interval);
}
init() {
this.interval = 16, this.status = constant_1.STATUS.INITIAL, application_1.application.global.hooks.onSetEnv.tap("graph-ticker", this._handleGraphTick),
application_1.application.global.env && this.initHandler(!1);
}
addTimeline(timeline) {
this.timelines.push(timeline);
}
remTimeline(timeline) {
this.timelines = this.timelines.filter((t => t !== timeline));
}
getTimelines() {
return this.timelines;
}
initHandler(force = !1) {
this.setupTickHandler(force);
}
setupTickHandler(force = !1) {
if (!force && this.tickerHandler) return !0;
const handler = new RAFTickHandler;
return this.tickerHandler && this.tickerHandler.release(), this.tickerHandler = handler,
!0;
}
setInterval(interval) {
this.interval = interval, this.computeTimeOffsetAndJitter();
}
getInterval() {
return this.interval;
}
setFPS(fps) {
this.setInterval(Math.floor(1e3 / fps));
}
getFPS() {
return 1e3 / this.interval;
}
tick(interval) {
this.tickerHandler.tick(interval, (handler => this.handleTick(handler, {
once: !0
})));
}
tickTo(t) {
this.tickerHandler.tickTo && this.tickerHandler.tickTo(t, (handler => {
this.handleTick(handler, {
once: !0
});
}));
}
pause() {
return this.status !== constant_1.STATUS.INITIAL && (this.status = constant_1.STATUS.PAUSE,
!0);
}
resume() {
return this.status !== constant_1.STATUS.INITIAL && (this.status = constant_1.STATUS.RUNNING,
!0);
}
ifCanStop() {
if (this.autoStop) {
if (!this.timelines.length) return !0;
if (this.timelines.every((timeline => !timeline.isRunning()))) return !0;
}
return !1;
}
start(force = !1) {
if (this.status === constant_1.STATUS.RUNNING) return !1;
if (!this.tickerHandler) return !1;
if (!force) {
if (this.status === constant_1.STATUS.PAUSE) return !1;
if (this.ifCanStop()) return !1;
}
return this.status = constant_1.STATUS.RUNNING, this.tickerHandler.tick(0, this.handleTick),
!0;
}
stop() {
this.status = constant_1.STATUS.INITIAL, this.setupTickHandler(!0), this.lastFrameTime = -1;
}
trySyncTickStatus() {
this.status === constant_1.STATUS.INITIAL && this.timelines.some((timeline => timeline.isRunning())) ? this.start() : this.status === constant_1.STATUS.RUNNING && this.timelines.every((timeline => !timeline.isRunning())) && this.stop();
}
release() {
var _a;
this.stop(), this.timelines = [], null === (_a = this.tickerHandler) || void 0 === _a || _a.release(),
this.tickerHandler = null, this.lastFrameTime = -1, application_1.application.global.hooks.onSetEnv.unTap("graph-ticker", this._handleGraphTick);
}
checkSkip(delta) {
var _a, _b, _c;
if ("performance" === (null === (_c = null === (_b = null === (_a = this.stage) || void 0 === _a ? void 0 : _a.params) || void 0 === _b ? void 0 : _b.optimize) || void 0 === _c ? void 0 : _c.tickRenderMode)) return !1;
return delta < this.interval + 2 * (Math.random() - .5) * this._jitter;
}
}
exports.DefaultTicker = DefaultTicker;
//# sourceMappingURL=default-ticker.js.map