UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

172 lines 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Animation = void 0; const common_1 = require("../../common"); const animationEvent_1 = require("./animationEvent"); const utils_1 = require("./utils"); /** * Web Animation API 的 Animation 实现,功能完善实现中 * 参考: https://developer.mozilla.org/en-US/docs/Web/API/Animation */ class Animation { constructor(effect, timeline) { this._effect = null; this._currentTime = null; this._playbackRate = 1; this._playState = 'idle'; this._rafId = null; this._startTime = null; this._pausedTime = null; this._timeline = null; this.id = ''; this.onfinish = null; this.oncancel = null; this._effect = effect; this._timeline = timeline !== null && timeline !== void 0 ? timeline : document.timeline; } get effect() { return this._effect; } get currentTime() { return this._currentTime; } set currentTime(value) { const now = this._timeline.currentTime; if (!common_1.NumberExt.isNumber(now)) return; this._startTime = now - value; this._currentTime = value; } get playbackRate() { return this._playbackRate; } set playbackRate(value) { const oldRate = this._playbackRate; this._playbackRate = value; const now = this._timeline.currentTime; // 如果正在运行,调整开始时间以保持视觉连续性 if (this._playState === 'running' && this._startTime != null && common_1.NumberExt.isNumber(now)) { const currentTime = (now - this._startTime) * oldRate; this._startTime = now - currentTime / value; } } get playState() { return this._playState; } get timeline() { return this._timeline; } play() { if (this._playState === 'running' || !this._effect) return; const now = this._timeline.currentTime; if (!common_1.NumberExt.isNumber(now)) return; if (this._playState === 'paused') { // 从暂停状态恢复 this._startTime = now - this._pausedTime / this._playbackRate; this._pausedTime = null; } else { // 新开始播放 this._currentTime = 0; this._startTime = now; } this._playState = 'running'; this._tick(); } pause() { if (this._playState !== 'running') return; if (this._rafId) { cancelAnimationFrame(this._rafId); this._rafId = null; } this._pausedTime = this._currentTime; this._playState = 'paused'; } finish() { var _a; if (!this._effect) return; const timing = this._effect.getComputedTiming(); const reversePlaybackRate = this._playbackRate < 0; const { duration, endTime, direction, fill, iterations } = timing; // 根据 fill 模式设置最终状态 if (fill === 'forwards' || fill === 'both') { const lastIteration = reversePlaybackRate ? 0 : iterations - 1; const reverseDirection = (0, utils_1.isReverseDirection)(direction, lastIteration); this._effect.apply(reverseDirection || reversePlaybackRate ? 0 : duration); } // 清除所有动画效果 else if (fill === 'none' || fill === 'backwards') { this._effect.apply(null); } this._currentTime = reversePlaybackRate ? 0 : endTime; this._playState = 'finished'; if (this._rafId) { cancelAnimationFrame(this._rafId); this._rafId = null; } const event = new animationEvent_1.AnimationPlaybackEvent(this, 'finish', this._currentTime, this._timeline.currentTime); (_a = this.onfinish) === null || _a === void 0 ? void 0 : _a.call(this, event); this._effect.target.notify('animation:finish', event); } cancel() { var _a; if (!this._effect) return; if (this._rafId) { cancelAnimationFrame(this._rafId); this._rafId = null; } this._playState = 'idle'; this._currentTime = null; this._startTime = null; this._pausedTime = null; this._effect.apply(null); const event = new animationEvent_1.AnimationPlaybackEvent(this, 'cancel', this._currentTime, this._timeline.currentTime); (_a = this.oncancel) === null || _a === void 0 ? void 0 : _a.call(this, event); this._effect.target.notify('animation:cancel', event); } updatePlaybackRate(playbackRate) { this.playbackRate = playbackRate; } reverse() { this.playbackRate = this.playbackRate * -1; } _tick() { const now = this._timeline.currentTime; if (this._playState !== 'running' || !this._effect || !common_1.NumberExt.isNumber(now)) { return; } const timing = this._effect.getComputedTiming(); const { duration, delay, iterations, direction, endTime } = timing; const currentTime = (now - this._startTime) * this._playbackRate; const elapsed = currentTime - delay; let currentIteration = Math.floor(elapsed / duration); if (currentTime >= endTime || currentTime < 0 || duration <= 0) { this.finish(); return; } if (currentTime >= delay) { // 计算当前迭代的进度 let iterationTime = elapsed % duration; currentIteration = Math.min(currentIteration, iterations - 1); // 处理播放方向 if ((0, utils_1.isReverseDirection)(direction, currentIteration)) { iterationTime = duration - iterationTime; } // 应用动画效果 this._effect.apply(iterationTime); } this._currentTime = currentTime; this._rafId = requestAnimationFrame(() => this._tick()); } } exports.Animation = Animation; //# sourceMappingURL=animation.js.map