UNPKG

@visactor/vrender-animate

Version:

This module provides a graph-based animation system for VRender.

140 lines (135 loc) 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.DefaultTicker = void 0; const vutils_1 = require("@visactor/vutils"), vrender_core_1 = require("@visactor/vrender-core"), performanceRAF = new vrender_core_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 === vrender_core_1.STATUS.RUNNING && (this.tickCounts++, this.timelines.forEach((timeline => { timeline.tick(delta); })), this.emit("tick", delta)); }, 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 = vrender_core_1.STATUS.INITIAL, vrender_core_1.application.global.hooks.onSetEnv.tap("graph-ticker", (() => { this.initHandler(!1); })), vrender_core_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 !== vrender_core_1.STATUS.INITIAL && (this.status = vrender_core_1.STATUS.PAUSE, !0); } resume() { return this.status !== vrender_core_1.STATUS.INITIAL && (this.status = vrender_core_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 === vrender_core_1.STATUS.RUNNING) return !1; if (!this.tickerHandler) return !1; if (!force) { if (this.status === vrender_core_1.STATUS.PAUSE) return !1; if (this.ifCanStop()) return !1; } return this.status = vrender_core_1.STATUS.RUNNING, this.tickerHandler.tick(0, this.handleTick), !0; } stop() { this.status = vrender_core_1.STATUS.INITIAL, this.setupTickHandler(!0), this.lastFrameTime = -1; } trySyncTickStatus() { this.status === vrender_core_1.STATUS.INITIAL && this.timelines.some((timeline => timeline.isRunning())) ? this.start() : this.status === vrender_core_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; } 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;