@visactor/vrender-animate 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/cjs/animate-extension.js +1 -4
  2. package/cjs/animate-extension.js.map +1 -1
  3. package/cjs/animate.js +4 -1
  4. package/cjs/animate.js.map +1 -1
  5. package/cjs/custom/custom-animate.js +1 -1
  6. package/cjs/custom/custom-animate.js.map +1 -1
  7. package/cjs/custom/fromTo.d.ts +1 -0
  8. package/cjs/custom/fromTo.js +3 -0
  9. package/cjs/custom/fromTo.js.map +1 -1
  10. package/cjs/custom/move.js +3 -3
  11. package/cjs/custom/move.js.map +1 -1
  12. package/cjs/executor/animate-executor.js +4 -3
  13. package/cjs/executor/animate-executor.js.map +1 -1
  14. package/cjs/state/index.js +1 -2
  15. package/cjs/ticker/default-ticker.d.ts +2 -2
  16. package/cjs/ticker/default-ticker.js +9 -7
  17. package/cjs/ticker/default-ticker.js.map +1 -1
  18. package/cjs/timeline.d.ts +1 -0
  19. package/cjs/timeline.js +4 -2
  20. package/cjs/timeline.js.map +1 -1
  21. package/dist/index.es.js +35 -22
  22. package/es/animate-extension.js +1 -4
  23. package/es/animate-extension.js.map +1 -1
  24. package/es/animate.js +4 -1
  25. package/es/animate.js.map +1 -1
  26. package/es/custom/custom-animate.js +1 -1
  27. package/es/custom/custom-animate.js.map +1 -1
  28. package/es/custom/fromTo.d.ts +1 -0
  29. package/es/custom/fromTo.js +3 -0
  30. package/es/custom/fromTo.js.map +1 -1
  31. package/es/custom/move.js +2 -2
  32. package/es/custom/move.js.map +1 -1
  33. package/es/executor/animate-executor.js +4 -3
  34. package/es/executor/animate-executor.js.map +1 -1
  35. package/es/state/index.js +1 -2
  36. package/es/ticker/default-ticker.d.ts +2 -2
  37. package/es/ticker/default-ticker.js +9 -7
  38. package/es/ticker/default-ticker.js.map +1 -1
  39. package/es/timeline.d.ts +1 -0
  40. package/es/timeline.js +3 -2
  41. package/es/timeline.js.map +1 -1
  42. package/package.json +2 -2
@@ -21,8 +21,8 @@ export declare class DefaultTicker extends EventEmitter implements ITicker {
21
21
  addTimeline(timeline: ITimeline): void;
22
22
  remTimeline(timeline: ITimeline): void;
23
23
  getTimelines(): ITimeline[];
24
- protected initHandler(): void;
25
- protected setupTickHandler(): boolean;
24
+ protected initHandler(force?: boolean): void;
25
+ protected setupTickHandler(force?: boolean): boolean;
26
26
  setInterval(interval: number): void;
27
27
  getInterval(): number;
28
28
  setFPS(fps: number): void;
@@ -49,8 +49,8 @@ class DefaultTicker extends vutils_1.EventEmitter {
49
49
  }
50
50
  init() {
51
51
  this.interval = 16, this.status = vrender_core_1.STATUS.INITIAL, vrender_core_1.application.global.hooks.onSetEnv.tap("graph-ticker", (() => {
52
- this.initHandler();
53
- })), vrender_core_1.application.global.env && this.initHandler();
52
+ this.initHandler(!1);
53
+ })), vrender_core_1.application.global.env && this.initHandler(!1);
54
54
  }
55
55
  addTimeline(timeline) {
56
56
  this.timelines.push(timeline);
@@ -61,10 +61,11 @@ class DefaultTicker extends vutils_1.EventEmitter {
61
61
  getTimelines() {
62
62
  return this.timelines;
63
63
  }
64
- initHandler() {
65
- this.setupTickHandler();
64
+ initHandler(force = !1) {
65
+ this.setupTickHandler(force);
66
66
  }
67
- setupTickHandler() {
67
+ setupTickHandler(force = !1) {
68
+ if (!force && this.tickerHandler) return !0;
68
69
  const handler = new RAFTickHandler;
69
70
  return this.tickerHandler && this.tickerHandler.release(), this.tickerHandler = handler,
70
71
  !0;
@@ -119,7 +120,7 @@ class DefaultTicker extends vutils_1.EventEmitter {
119
120
  !0;
120
121
  }
121
122
  stop() {
122
- this.status = vrender_core_1.STATUS.INITIAL, this.setupTickHandler(), this.lastFrameTime = -1;
123
+ this.status = vrender_core_1.STATUS.INITIAL, this.setupTickHandler(!0), this.lastFrameTime = -1;
123
124
  }
124
125
  trySyncTickStatus() {
125
126
  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();
@@ -135,4 +136,5 @@ class DefaultTicker extends vutils_1.EventEmitter {
135
136
  }
136
137
  }
137
138
 
138
- exports.DefaultTicker = DefaultTicker;
139
+ exports.DefaultTicker = DefaultTicker;
140
+ //# sourceMappingURL=default-ticker.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ticker/default-ticker.ts"],"names":[],"mappings":"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","file":"default-ticker.js","sourcesContent":["import { EventEmitter } from '@visactor/vutils';\nimport type { IStage, ITimeline } from '@visactor/vrender-core';\nimport { application, PerformanceRAF, type ITickHandler, type ITicker, STATUS } from '@visactor/vrender-core';\n\nconst performanceRAF = new PerformanceRAF();\n\nclass RAFTickHandler implements ITickHandler {\n protected released: boolean = false;\n\n tick(interval: number, cb: (handler: ITickHandler) => void | boolean): void {\n performanceRAF.addAnimationFrameCb(() => {\n if (this.released) {\n return;\n }\n return cb(this);\n });\n }\n\n release(): void {\n this.released = true;\n }\n\n getTime(): number {\n return Date.now();\n }\n}\n\n/**\n * Graph-based Ticker implementation\n * This ticker works directly with GraphManager instances without needing timeline adapters\n */\nexport class DefaultTicker extends EventEmitter implements ITicker {\n protected interval: number;\n protected tickerHandler: ITickHandler;\n protected status: STATUS;\n protected lastFrameTime: number;\n protected tickCounts: number;\n protected stage: IStage;\n timelines: ITimeline[] = [];\n autoStop: boolean;\n // 随机扰动(每次都对interval进行随机的扰动,避免所有tick都发生在同一帧)\n protected _jitter: number;\n protected timeOffset: number;\n declare _lastTickTime: number;\n protected frameTimeHistory: number[] = [];\n\n constructor(stage?: IStage) {\n super();\n this.init();\n this.lastFrameTime = -1;\n this.tickCounts = 0;\n this.stage = stage;\n this.autoStop = true;\n this.interval = 16;\n this.computeTimeOffsetAndJitter();\n }\n\n bindStage(stage: IStage): void {\n this.stage = stage;\n }\n\n /**\n * 计算时间偏移和随机扰动\n */\n computeTimeOffsetAndJitter(): void {\n this.timeOffset = Math.floor(Math.random() * this.interval);\n this._jitter = Math.min(Math.max(this.interval * 0.2, 6), this.interval * 0.7);\n }\n\n init(): void {\n this.interval = 16;\n this.status = STATUS.INITIAL;\n application.global.hooks.onSetEnv.tap('graph-ticker', () => {\n this.initHandler();\n });\n if (application.global.env) {\n this.initHandler();\n }\n }\n\n addTimeline(timeline: ITimeline): void {\n this.timelines.push(timeline);\n }\n\n remTimeline(timeline: ITimeline): void {\n this.timelines = this.timelines.filter(t => t !== timeline);\n }\n\n getTimelines(): ITimeline[] {\n return this.timelines;\n }\n\n protected initHandler() {\n this.setupTickHandler();\n }\n\n /**\n * Set up the tick handler\n * @returns true if setup was successful, false otherwise\n */\n protected setupTickHandler(): boolean {\n const handler: ITickHandler = new RAFTickHandler();\n\n // Destroy the previous tick handler\n if (this.tickerHandler) {\n this.tickerHandler.release();\n }\n\n this.tickerHandler = handler;\n return true;\n }\n\n setInterval(interval: number): void {\n this.interval = interval;\n this.computeTimeOffsetAndJitter();\n }\n\n getInterval(): number {\n return this.interval;\n }\n\n setFPS(fps: number): void {\n this.setInterval(Math.floor(1000 / fps));\n }\n\n getFPS(): number {\n return 1000 / this.interval;\n }\n\n tick(interval: number): void {\n this.tickerHandler.tick(interval, (handler: ITickHandler) => {\n return this.handleTick(handler, { once: true });\n });\n }\n\n tickTo(t: number): void {\n if (!this.tickerHandler.tickTo) {\n return;\n }\n this.tickerHandler.tickTo(t, (handler: ITickHandler) => {\n this.handleTick(handler, { once: true });\n });\n }\n\n pause(): boolean {\n if (this.status === STATUS.INITIAL) {\n return false;\n }\n this.status = STATUS.PAUSE;\n return true;\n }\n\n resume(): boolean {\n if (this.status === STATUS.INITIAL) {\n return false;\n }\n this.status = STATUS.RUNNING;\n return true;\n }\n\n ifCanStop(): boolean {\n if (this.autoStop) {\n if (!this.timelines.length) {\n return true;\n }\n if (this.timelines.every(timeline => !timeline.isRunning())) {\n return true;\n }\n }\n return false;\n }\n\n start(force: boolean = false): boolean {\n if (this.status === STATUS.RUNNING) {\n return false;\n }\n if (!this.tickerHandler) {\n return false;\n }\n\n // 暂停中、或者应该停止的时候,就不执行\n if (!force) {\n if (this.status === STATUS.PAUSE) {\n return false;\n }\n if (this.ifCanStop()) {\n return false;\n }\n }\n\n this.status = STATUS.RUNNING;\n this.tickerHandler.tick(0, this.handleTick);\n return true;\n }\n\n stop(): void {\n // Reset the tick handler\n this.status = STATUS.INITIAL;\n this.setupTickHandler();\n this.lastFrameTime = -1;\n }\n\n /**\n * 用于自动启动或停止\n * 基于当前的graph managers检查是否需要启动或停止\n */\n trySyncTickStatus(): void {\n if (this.status === STATUS.INITIAL && this.timelines.some(timeline => timeline.isRunning())) {\n this.start();\n } else if (this.status === STATUS.RUNNING && this.timelines.every(timeline => !timeline.isRunning())) {\n this.stop();\n }\n }\n\n release(): void {\n this.stop();\n this.timelines = [];\n this.tickerHandler?.release();\n this.tickerHandler = null;\n this.lastFrameTime = -1;\n }\n\n protected checkSkip(delta: number): boolean {\n if (this.stage.params.optimize.tickRenderMode === 'performance') {\n return false;\n }\n // 随机扰动(每次都对interval进行随机的扰动,避免所有tick都发生在同一帧)\n const skip = delta < this.interval + (Math.random() - 0.5) * 2 * this._jitter;\n return skip;\n }\n\n protected handleTick = (handler: ITickHandler, params?: { once?: boolean }): boolean => {\n const { once = false } = params ?? {};\n\n // 尝试停止\n if (this.ifCanStop()) {\n this.stop();\n return false;\n }\n\n const currentTime = handler.getTime();\n this._lastTickTime = currentTime;\n\n if (this.lastFrameTime < 0) {\n this.lastFrameTime = currentTime - this.interval + this.timeOffset;\n this.frameTimeHistory.push(this.lastFrameTime);\n }\n\n const delta = currentTime - this.lastFrameTime;\n\n const skip = this.checkSkip(delta);\n\n if (!skip) {\n this._handlerTick(delta);\n this.lastFrameTime = currentTime;\n this.frameTimeHistory.push(this.lastFrameTime);\n }\n\n if (!once) {\n handler.tick(this.interval, this.handleTick);\n }\n\n return !skip;\n };\n\n protected _handlerTick = (delta: number): void => {\n if (this.status !== STATUS.RUNNING) {\n return;\n }\n\n this.tickCounts++;\n\n // Update all graph managers\n this.timelines.forEach(timeline => {\n timeline.tick(delta);\n });\n\n this.emit('tick', delta);\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/ticker/default-ticker.ts"],"names":[],"mappings":"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","file":"default-ticker.js","sourcesContent":["import { EventEmitter } from '@visactor/vutils';\nimport type { IStage, ITimeline } from '@visactor/vrender-core';\nimport { application, PerformanceRAF, type ITickHandler, type ITicker, STATUS } from '@visactor/vrender-core';\n\nconst performanceRAF = new PerformanceRAF();\n\nclass RAFTickHandler implements ITickHandler {\n protected released: boolean = false;\n\n tick(interval: number, cb: (handler: ITickHandler) => void | boolean): void {\n performanceRAF.addAnimationFrameCb(() => {\n if (this.released) {\n return;\n }\n return cb(this);\n });\n }\n\n release(): void {\n this.released = true;\n }\n\n getTime(): number {\n return Date.now();\n }\n}\n\n/**\n * Graph-based Ticker implementation\n * This ticker works directly with GraphManager instances without needing timeline adapters\n */\nexport class DefaultTicker extends EventEmitter implements ITicker {\n protected interval: number;\n protected tickerHandler: ITickHandler;\n protected status: STATUS;\n protected lastFrameTime: number;\n protected tickCounts: number;\n protected stage: IStage;\n timelines: ITimeline[] = [];\n autoStop: boolean;\n // 随机扰动(每次都对interval进行随机的扰动,避免所有tick都发生在同一帧)\n protected _jitter: number;\n protected timeOffset: number;\n declare _lastTickTime: number;\n protected frameTimeHistory: number[] = [];\n\n constructor(stage?: IStage) {\n super();\n this.init();\n this.lastFrameTime = -1;\n this.tickCounts = 0;\n this.stage = stage;\n this.autoStop = true;\n this.interval = 16;\n this.computeTimeOffsetAndJitter();\n }\n\n bindStage(stage: IStage): void {\n this.stage = stage;\n }\n\n /**\n * 计算时间偏移和随机扰动\n */\n computeTimeOffsetAndJitter(): void {\n this.timeOffset = Math.floor(Math.random() * this.interval);\n this._jitter = Math.min(Math.max(this.interval * 0.2, 6), this.interval * 0.7);\n }\n\n init(): void {\n this.interval = 16;\n this.status = STATUS.INITIAL;\n application.global.hooks.onSetEnv.tap('graph-ticker', () => {\n this.initHandler(false);\n });\n if (application.global.env) {\n this.initHandler(false);\n }\n }\n\n addTimeline(timeline: ITimeline): void {\n this.timelines.push(timeline);\n }\n\n remTimeline(timeline: ITimeline): void {\n this.timelines = this.timelines.filter(t => t !== timeline);\n }\n\n getTimelines(): ITimeline[] {\n return this.timelines;\n }\n\n protected initHandler(force: boolean = false) {\n this.setupTickHandler(force);\n }\n\n /**\n * Set up the tick handler\n * @returns true if setup was successful, false otherwise\n */\n protected setupTickHandler(force: boolean = false): boolean {\n if (!force && this.tickerHandler) {\n return true;\n }\n const handler: ITickHandler = new RAFTickHandler();\n\n // Destroy the previous tick handler\n if (this.tickerHandler) {\n this.tickerHandler.release();\n }\n\n this.tickerHandler = handler;\n return true;\n }\n\n setInterval(interval: number): void {\n this.interval = interval;\n this.computeTimeOffsetAndJitter();\n }\n\n getInterval(): number {\n return this.interval;\n }\n\n setFPS(fps: number): void {\n this.setInterval(Math.floor(1000 / fps));\n }\n\n getFPS(): number {\n return 1000 / this.interval;\n }\n\n tick(interval: number): void {\n this.tickerHandler.tick(interval, (handler: ITickHandler) => {\n return this.handleTick(handler, { once: true });\n });\n }\n\n tickTo(t: number): void {\n if (!this.tickerHandler.tickTo) {\n return;\n }\n this.tickerHandler.tickTo(t, (handler: ITickHandler) => {\n this.handleTick(handler, { once: true });\n });\n }\n\n pause(): boolean {\n if (this.status === STATUS.INITIAL) {\n return false;\n }\n this.status = STATUS.PAUSE;\n return true;\n }\n\n resume(): boolean {\n if (this.status === STATUS.INITIAL) {\n return false;\n }\n this.status = STATUS.RUNNING;\n return true;\n }\n\n ifCanStop(): boolean {\n if (this.autoStop) {\n if (!this.timelines.length) {\n return true;\n }\n if (this.timelines.every(timeline => !timeline.isRunning())) {\n return true;\n }\n }\n return false;\n }\n\n start(force: boolean = false): boolean {\n if (this.status === STATUS.RUNNING) {\n return false;\n }\n if (!this.tickerHandler) {\n return false;\n }\n\n // 暂停中、或者应该停止的时候,就不执行\n if (!force) {\n if (this.status === STATUS.PAUSE) {\n return false;\n }\n if (this.ifCanStop()) {\n return false;\n }\n }\n\n this.status = STATUS.RUNNING;\n this.tickerHandler.tick(0, this.handleTick);\n return true;\n }\n\n stop(): void {\n // Reset the tick handler\n this.status = STATUS.INITIAL;\n this.setupTickHandler(true);\n this.lastFrameTime = -1;\n }\n\n /**\n * 用于自动启动或停止\n * 基于当前的graph managers检查是否需要启动或停止\n */\n trySyncTickStatus(): void {\n if (this.status === STATUS.INITIAL && this.timelines.some(timeline => timeline.isRunning())) {\n this.start();\n } else if (this.status === STATUS.RUNNING && this.timelines.every(timeline => !timeline.isRunning())) {\n this.stop();\n }\n }\n\n release(): void {\n this.stop();\n this.timelines = [];\n this.tickerHandler?.release();\n this.tickerHandler = null;\n this.lastFrameTime = -1;\n }\n\n protected checkSkip(delta: number): boolean {\n if (this.stage.params.optimize.tickRenderMode === 'performance') {\n return false;\n }\n // 随机扰动(每次都对interval进行随机的扰动,避免所有tick都发生在同一帧)\n const skip = delta < this.interval + (Math.random() - 0.5) * 2 * this._jitter;\n return skip;\n }\n\n protected handleTick = (handler: ITickHandler, params?: { once?: boolean }): boolean => {\n const { once = false } = params ?? {};\n\n // 尝试停止\n if (this.ifCanStop()) {\n this.stop();\n return false;\n }\n\n const currentTime = handler.getTime();\n this._lastTickTime = currentTime;\n\n if (this.lastFrameTime < 0) {\n this.lastFrameTime = currentTime - this.interval + this.timeOffset;\n this.frameTimeHistory.push(this.lastFrameTime);\n }\n\n const delta = currentTime - this.lastFrameTime;\n\n const skip = this.checkSkip(delta);\n\n if (!skip) {\n this._handlerTick(delta);\n this.lastFrameTime = currentTime;\n this.frameTimeHistory.push(this.lastFrameTime);\n }\n\n if (!once) {\n handler.tick(this.interval, this.handleTick);\n }\n\n return !skip;\n };\n\n protected _handlerTick = (delta: number): void => {\n if (this.status !== STATUS.RUNNING) {\n return;\n }\n\n this.tickCounts++;\n\n // Update all graph managers\n this.timelines.forEach(timeline => {\n timeline.tick(delta);\n });\n\n this.emit('tick', delta);\n };\n}\n"]}
package/cjs/timeline.d.ts CHANGED
@@ -16,6 +16,7 @@ export declare class DefaultTimeline extends EventEmitter implements ITimeline {
16
16
  protected _totalDuration: number;
17
17
  protected _startTime: number;
18
18
  protected _currentTime: number;
19
+ protected _animationEndFlag: boolean;
19
20
  isGlobal?: boolean;
20
21
  get animateCount(): number;
21
22
  constructor();
package/cjs/timeline.js CHANGED
@@ -13,7 +13,8 @@ class DefaultTimeline extends vutils_1.EventEmitter {
13
13
  constructor() {
14
14
  super(), this.head = null, this.tail = null, this.animateMap = new Map, this._animateCount = 0,
15
15
  this._playSpeed = 1, this._totalDuration = 0, this._startTime = 0, this._currentTime = 0,
16
- this.id = vrender_core_1.Generator.GenAutoIncrementId(), this.paused = !1;
16
+ this._animationEndFlag = !0, this.id = vrender_core_1.Generator.GenAutoIncrementId(),
17
+ this.paused = !1;
17
18
  }
18
19
  isRunning() {
19
20
  return !this.paused && this._animateCount > 0;
@@ -43,10 +44,11 @@ class DefaultTimeline extends vutils_1.EventEmitter {
43
44
  }
44
45
  tick(delta) {
45
46
  if (this.paused) return;
47
+ this._animationEndFlag && (this._animationEndFlag = !1, this.emit("animationStart"));
46
48
  const scaledDelta = delta * this._playSpeed;
47
49
  this._currentTime += scaledDelta, this.forEachAccessAnimate(((animate, i) => {
48
50
  animate.status === vrender_core_1.AnimateStatus.END ? this.removeAnimate(animate, !0) : animate.status !== vrender_core_1.AnimateStatus.RUNNING && animate.status !== vrender_core_1.AnimateStatus.INITIAL || animate.advance(scaledDelta);
49
- })), 0 === this._animateCount && this.emit("animationEnd");
51
+ })), 0 === this._animateCount && (this._animationEndFlag = !0, this.emit("animationEnd"));
50
52
  }
51
53
  clear() {
52
54
  this.forEachAccessAnimate((animate => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/timeline.ts"],"names":[],"mappings":"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","file":"timeline.js","sourcesContent":["import { Generator, type IAnimate, type ITimeline, AnimateStatus } from '@visactor/vrender-core';\nimport { EventEmitter } from '@visactor/vutils';\n\n// 定义链表节点\ninterface AnimateNode {\n animate: IAnimate;\n next: AnimateNode | null;\n prev: AnimateNode | null;\n}\n\nexport class DefaultTimeline extends EventEmitter implements ITimeline {\n declare id: number;\n protected head: AnimateNode | null = null;\n protected tail: AnimateNode | null = null;\n protected animateMap: Map<IAnimate, AnimateNode> = new Map();\n protected _animateCount: number = 0;\n protected declare paused: boolean;\n\n // 添加必要的属性\n protected _playSpeed: number = 1;\n protected _totalDuration: number = 0;\n protected _startTime: number = 0;\n protected _currentTime: number = 0;\n\n declare isGlobal?: boolean;\n\n get animateCount() {\n return this._animateCount;\n }\n\n constructor() {\n super();\n this.id = Generator.GenAutoIncrementId();\n this.paused = false;\n }\n\n isRunning() {\n return !this.paused && this._animateCount > 0;\n }\n\n forEachAccessAnimate(cb: (animate: IAnimate, index: number) => void) {\n let current = this.head;\n let index = 0;\n\n while (current) {\n // 保存下一个节点的引用,以防在回调中移除当前节点\n const next = current.next;\n cb(current.animate, index);\n index++;\n current = next;\n }\n }\n\n addAnimate(animate: IAnimate) {\n const newNode: AnimateNode = {\n animate,\n next: null,\n prev: null\n };\n\n // 添加到链表尾部\n if (!this.head) {\n this.head = newNode;\n this.tail = newNode;\n } else {\n if (this.tail) {\n this.tail.next = newNode;\n newNode.prev = this.tail;\n this.tail = newNode;\n }\n }\n\n // 在映射中保存节点引用\n this.animateMap.set(animate, newNode);\n this._animateCount++;\n\n // 更新总时长\n this._totalDuration = Math.max(this._totalDuration, animate.getStartTime() + animate.getDuration());\n }\n\n pause() {\n this.paused = true;\n }\n\n resume() {\n this.paused = false;\n }\n\n tick(delta: number) {\n if (this.paused) {\n return;\n }\n\n // 应用播放速度\n const scaledDelta = delta * this._playSpeed;\n\n // 更新当前时间\n this._currentTime += scaledDelta;\n\n this.forEachAccessAnimate((animate, i) => {\n if (animate.status === AnimateStatus.END) {\n this.removeAnimate(animate, true);\n } else if (animate.status === AnimateStatus.RUNNING || animate.status === AnimateStatus.INITIAL) {\n animate.advance(scaledDelta);\n }\n });\n\n if (this._animateCount === 0) {\n this.emit('animationEnd');\n }\n }\n\n clear() {\n this.forEachAccessAnimate(animate => {\n animate.release();\n });\n\n this.head = null;\n this.tail = null;\n this.animateMap.clear();\n this._animateCount = 0;\n this._totalDuration = 0;\n }\n\n removeAnimate(animate: IAnimate, release: boolean = true) {\n const node = this.animateMap.get(animate);\n\n if (!node) {\n return;\n }\n\n if (release) {\n animate._onRemove && animate._onRemove.forEach(cb => cb());\n animate.release();\n }\n\n // 从链表中移除节点\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n // 节点是头节点\n this.head = node.next;\n }\n\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n // 节点是尾节点\n this.tail = node.prev;\n }\n\n // 从映射中移除\n this.animateMap.delete(animate);\n this._animateCount--;\n\n // 如果移除的是最长时间的动画,应该重新计算总时长\n if (animate.getStartTime() + animate.getDuration() >= this._totalDuration) {\n this.recalculateTotalDuration();\n }\n\n return;\n }\n\n // 重新计算总时长\n protected recalculateTotalDuration() {\n this._totalDuration = 0;\n this.forEachAccessAnimate(animate => {\n this._totalDuration = Math.max(this._totalDuration, animate.getStartTime() + animate.getDuration());\n });\n }\n\n getTotalDuration() {\n return this._totalDuration;\n }\n\n getPlaySpeed() {\n return this._playSpeed;\n }\n\n setPlaySpeed(speed: number) {\n this._playSpeed = speed;\n }\n\n // 实现ITimeline接口所需的其他方法\n getPlayState(): 'playing' | 'paused' | 'stopped' {\n if (this.paused) {\n return 'paused';\n }\n if (this.animateCount === 0) {\n return 'stopped';\n }\n return 'playing';\n }\n\n setStartTime(time: number) {\n this._startTime = time;\n }\n\n getStartTime() {\n return this._startTime;\n }\n\n getCurrentTime() {\n return this._currentTime;\n }\n\n setCurrentTime(time: number) {\n this._currentTime = time;\n }\n}\n\n// 不会使用,存粹做临时存储用,请一定要放置到stage中才行\nexport const defaultTimeline = new DefaultTimeline();\ndefaultTimeline.isGlobal = true;\n"]}
1
+ {"version":3,"sources":["../src/timeline.ts"],"names":[],"mappings":"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","file":"timeline.js","sourcesContent":["import { Generator, type IAnimate, type ITimeline, AnimateStatus } from '@visactor/vrender-core';\nimport { EventEmitter } from '@visactor/vutils';\n\n// 定义链表节点\ninterface AnimateNode {\n animate: IAnimate;\n next: AnimateNode | null;\n prev: AnimateNode | null;\n}\n\nexport class DefaultTimeline extends EventEmitter implements ITimeline {\n declare id: number;\n protected head: AnimateNode | null = null;\n protected tail: AnimateNode | null = null;\n protected animateMap: Map<IAnimate, AnimateNode> = new Map();\n protected _animateCount: number = 0;\n protected declare paused: boolean;\n\n // 添加必要的属性\n protected _playSpeed: number = 1;\n protected _totalDuration: number = 0;\n protected _startTime: number = 0;\n protected _currentTime: number = 0;\n protected _animationEndFlag: boolean = true;\n\n declare isGlobal?: boolean;\n\n get animateCount() {\n return this._animateCount;\n }\n\n constructor() {\n super();\n this.id = Generator.GenAutoIncrementId();\n this.paused = false;\n }\n\n isRunning() {\n return !this.paused && this._animateCount > 0;\n }\n\n forEachAccessAnimate(cb: (animate: IAnimate, index: number) => void) {\n let current = this.head;\n let index = 0;\n\n while (current) {\n // 保存下一个节点的引用,以防在回调中移除当前节点\n const next = current.next;\n cb(current.animate, index);\n index++;\n current = next;\n }\n }\n\n addAnimate(animate: IAnimate) {\n const newNode: AnimateNode = {\n animate,\n next: null,\n prev: null\n };\n\n // 添加到链表尾部\n if (!this.head) {\n this.head = newNode;\n this.tail = newNode;\n } else {\n if (this.tail) {\n this.tail.next = newNode;\n newNode.prev = this.tail;\n this.tail = newNode;\n }\n }\n\n // 在映射中保存节点引用\n this.animateMap.set(animate, newNode);\n this._animateCount++;\n\n // 更新总时长\n this._totalDuration = Math.max(this._totalDuration, animate.getStartTime() + animate.getDuration());\n }\n\n pause() {\n this.paused = true;\n }\n\n resume() {\n this.paused = false;\n }\n\n tick(delta: number) {\n if (this.paused) {\n return;\n }\n if (this._animationEndFlag) {\n this._animationEndFlag = false;\n this.emit('animationStart');\n }\n\n // 应用播放速度\n const scaledDelta = delta * this._playSpeed;\n\n // 更新当前时间\n this._currentTime += scaledDelta;\n\n this.forEachAccessAnimate((animate, i) => {\n if (animate.status === AnimateStatus.END) {\n this.removeAnimate(animate, true);\n } else if (animate.status === AnimateStatus.RUNNING || animate.status === AnimateStatus.INITIAL) {\n animate.advance(scaledDelta);\n }\n });\n\n if (this._animateCount === 0) {\n this._animationEndFlag = true;\n this.emit('animationEnd');\n }\n }\n\n clear() {\n this.forEachAccessAnimate(animate => {\n animate.release();\n });\n\n this.head = null;\n this.tail = null;\n this.animateMap.clear();\n this._animateCount = 0;\n this._totalDuration = 0;\n }\n\n removeAnimate(animate: IAnimate, release: boolean = true) {\n const node = this.animateMap.get(animate);\n\n if (!node) {\n return;\n }\n\n if (release) {\n animate._onRemove && animate._onRemove.forEach(cb => cb());\n animate.release();\n }\n\n // 从链表中移除节点\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n // 节点是头节点\n this.head = node.next;\n }\n\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n // 节点是尾节点\n this.tail = node.prev;\n }\n\n // 从映射中移除\n this.animateMap.delete(animate);\n this._animateCount--;\n\n // 如果移除的是最长时间的动画,应该重新计算总时长\n if (animate.getStartTime() + animate.getDuration() >= this._totalDuration) {\n this.recalculateTotalDuration();\n }\n\n return;\n }\n\n // 重新计算总时长\n protected recalculateTotalDuration() {\n this._totalDuration = 0;\n this.forEachAccessAnimate(animate => {\n this._totalDuration = Math.max(this._totalDuration, animate.getStartTime() + animate.getDuration());\n });\n }\n\n getTotalDuration() {\n return this._totalDuration;\n }\n\n getPlaySpeed() {\n return this._playSpeed;\n }\n\n setPlaySpeed(speed: number) {\n this._playSpeed = speed;\n }\n\n // 实现ITimeline接口所需的其他方法\n getPlayState(): 'playing' | 'paused' | 'stopped' {\n if (this.paused) {\n return 'paused';\n }\n if (this.animateCount === 0) {\n return 'stopped';\n }\n return 'playing';\n }\n\n setStartTime(time: number) {\n this._startTime = time;\n }\n\n getStartTime() {\n return this._startTime;\n }\n\n getCurrentTime() {\n return this._currentTime;\n }\n\n setCurrentTime(time: number) {\n this._currentTime = time;\n }\n}\n\n// 不会使用,存粹做临时存储用,请一定要放置到stage中才行\nexport const defaultTimeline = new DefaultTimeline();\ndefaultTimeline.isGlobal = true;\n"]}
package/dist/index.es.js CHANGED
@@ -590,6 +590,7 @@ class DefaultTimeline extends EventEmitter {
590
590
  this._totalDuration = 0;
591
591
  this._startTime = 0;
592
592
  this._currentTime = 0;
593
+ this._animationEndFlag = true;
593
594
  this.id = Generator.GenAutoIncrementId();
594
595
  this.paused = false;
595
596
  }
@@ -637,6 +638,10 @@ class DefaultTimeline extends EventEmitter {
637
638
  if (this.paused) {
638
639
  return;
639
640
  }
641
+ if (this._animationEndFlag) {
642
+ this._animationEndFlag = false;
643
+ this.emit('animationStart');
644
+ }
640
645
  const scaledDelta = delta * this._playSpeed;
641
646
  this._currentTime += scaledDelta;
642
647
  this.forEachAccessAnimate((animate, i) => {
@@ -648,6 +653,7 @@ class DefaultTimeline extends EventEmitter {
648
653
  }
649
654
  });
650
655
  if (this._animateCount === 0) {
656
+ this._animationEndFlag = true;
651
657
  this.emit('animationEnd');
652
658
  }
653
659
  }
@@ -768,6 +774,14 @@ class Animate {
768
774
  }
769
775
  bind(target) {
770
776
  this.target = target;
777
+ if (!this.target.animates) {
778
+ this.target.animates = new Map();
779
+ }
780
+ this.target.animates.set(this.id, this);
781
+ this.onRemove(() => {
782
+ this.stop();
783
+ this.target.animates.delete(this.id);
784
+ });
771
785
  if (this.target.onAnimateBind && !this.slience) {
772
786
  this.target.onAnimateBind(this);
773
787
  }
@@ -1185,10 +1199,10 @@ class DefaultTicker extends EventEmitter {
1185
1199
  this.interval = 16;
1186
1200
  this.status = STATUS.INITIAL;
1187
1201
  application.global.hooks.onSetEnv.tap('graph-ticker', () => {
1188
- this.initHandler();
1202
+ this.initHandler(false);
1189
1203
  });
1190
1204
  if (application.global.env) {
1191
- this.initHandler();
1205
+ this.initHandler(false);
1192
1206
  }
1193
1207
  }
1194
1208
  addTimeline(timeline) {
@@ -1200,10 +1214,13 @@ class DefaultTicker extends EventEmitter {
1200
1214
  getTimelines() {
1201
1215
  return this.timelines;
1202
1216
  }
1203
- initHandler() {
1204
- this.setupTickHandler();
1217
+ initHandler(force = false) {
1218
+ this.setupTickHandler(force);
1205
1219
  }
1206
- setupTickHandler() {
1220
+ setupTickHandler(force = false) {
1221
+ if (!force && this.tickerHandler) {
1222
+ return true;
1223
+ }
1207
1224
  const handler = new RAFTickHandler();
1208
1225
  if (this.tickerHandler) {
1209
1226
  this.tickerHandler.release();
@@ -1283,7 +1300,7 @@ class DefaultTicker extends EventEmitter {
1283
1300
  }
1284
1301
  stop() {
1285
1302
  this.status = STATUS.INITIAL;
1286
- this.setupTickHandler();
1303
+ this.setupTickHandler(true);
1287
1304
  this.lastFrameTime = -1;
1288
1305
  }
1289
1306
  trySyncTickStatus() {
@@ -1771,10 +1788,7 @@ class AnimateExecutor {
1771
1788
  _handleRunAnimate(animate, custom, customType, from, props, duration, easing, customParameters, controlOptions, options, type, graphic) {
1772
1789
  var _a, _b, _c, _d;
1773
1790
  if (custom && customType) {
1774
- const customParams = this.resolveValue(customParameters, graphic, {
1775
- width: graphic.stage.width,
1776
- height: graphic.stage.height
1777
- });
1791
+ const customParams = Object.assign({ width: graphic.stage.width, height: graphic.stage.height, group: this._target.parent }, this.resolveValue(customParameters, graphic));
1778
1792
  const objOptions = isFunction(options)
1779
1793
  ? options.call(null, (_b = (customParams && ((_a = customParams.data) === null || _a === void 0 ? void 0 : _a[0]))) !== null && _b !== void 0 ? _b : (_d = (_c = graphic.context) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d[0], graphic, customParams)
1780
1794
  : options;
@@ -2169,9 +2183,6 @@ class AnimateExtension {
2169
2183
  }
2170
2184
  animate(params) {
2171
2185
  var _a, _b, _c;
2172
- if (!this.animates) {
2173
- this.animates = new Map();
2174
- }
2175
2186
  const animate = new Animate(params === null || params === void 0 ? void 0 : params.id, (_b = (_a = params === null || params === void 0 ? void 0 : params.timeline) !== null && _a !== void 0 ? _a : (this.stage && this.stage.getTimeline())) !== null && _b !== void 0 ? _b : defaultTimeline, params === null || params === void 0 ? void 0 : params.slience);
2176
2187
  animate.bind(this);
2177
2188
  if (params) {
@@ -2180,11 +2191,6 @@ class AnimateExtension {
2180
2191
  onEnd != null && animate.onEnd(onEnd);
2181
2192
  onRemove != null && animate.onRemove(onRemove);
2182
2193
  }
2183
- this.animates.set(animate.id, animate);
2184
- animate.onRemove(() => {
2185
- animate.stop();
2186
- this.animates.delete(animate.id);
2187
- });
2188
2194
  (_c = this.stage) === null || _c === void 0 ? void 0 : _c.ticker.start();
2189
2195
  return animate;
2190
2196
  }
@@ -2242,6 +2248,8 @@ class ACustomAnimate extends Step {
2242
2248
  this.type = 'customAnimate';
2243
2249
  this.customFrom = customFrom;
2244
2250
  this.params = params;
2251
+ this.from = customFrom;
2252
+ this.to = customTo;
2245
2253
  }
2246
2254
  update(end, ratio, out) {
2247
2255
  this.onStart();
@@ -6515,14 +6523,15 @@ const moveIn = (graphic, options, animationParameters) => {
6515
6523
  }
6516
6524
  };
6517
6525
  const moveOut = (graphic, options, animationParameters) => {
6518
- var _a, _b, _c, _d, _e, _f;
6526
+ var _a, _b, _c, _d;
6519
6527
  const { offset = 0, orient, direction, point: pointOpt } = options !== null && options !== void 0 ? options : {};
6520
- const groupWidth = (_b = (_a = options.layoutRect) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : graphic.stage.viewWidth;
6521
- const groupHeight = (_d = (_c = options.layoutRect) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : graphic.stage.viewHeight;
6528
+ const groupBounds = animationParameters.group ? animationParameters.group.AABBBounds : null;
6529
+ const groupWidth = (_a = groupBounds.width()) !== null && _a !== void 0 ? _a : animationParameters.width;
6530
+ const groupHeight = (_b = groupBounds.height()) !== null && _b !== void 0 ? _b : animationParameters.height;
6522
6531
  const changedX = (orient === 'negative' ? groupWidth : 0) + offset;
6523
6532
  const changedY = (orient === 'negative' ? groupHeight : 0) + offset;
6524
6533
  const point = isFunction(pointOpt)
6525
- ? pointOpt.call(null, (_f = (_e = graphic.context) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f[0], graphic, animationParameters)
6534
+ ? pointOpt.call(null, (_d = (_c = graphic.context) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d[0], graphic, animationParameters)
6526
6535
  : pointOpt;
6527
6536
  const fromX = point && isValidNumber(point.x) ? point.x : changedX;
6528
6537
  const fromY = point && isValidNumber(point.y) ? point.y : changedY;
@@ -6742,6 +6751,10 @@ class FromTo extends ACustomAnimate {
6742
6751
  });
6743
6752
  this.target.setAttributes(this.from);
6744
6753
  }
6754
+ deleteSelfAttr(key) {
6755
+ super.deleteSelfAttr(key);
6756
+ delete this.from[key];
6757
+ }
6745
6758
  update(end, ratio, out) {
6746
6759
  this.onStart();
6747
6760
  if (!this.props || !this.propKeys) {
@@ -12,16 +12,13 @@ export class AnimateExtension {
12
12
  }
13
13
  animate(params) {
14
14
  var _a, _b, _c;
15
- this.animates || (this.animates = new Map);
16
15
  const animate = new Animate(null == params ? void 0 : params.id, null !== (_b = null !== (_a = null == params ? void 0 : params.timeline) && void 0 !== _a ? _a : this.stage && this.stage.getTimeline()) && void 0 !== _b ? _b : defaultTimeline, null == params ? void 0 : params.slience);
17
16
  if (animate.bind(this), params) {
18
17
  const {onStart: onStart, onEnd: onEnd, onRemove: onRemove} = params;
19
18
  null != onStart && animate.onStart(onStart), null != onEnd && animate.onEnd(onEnd),
20
19
  null != onRemove && animate.onRemove(onRemove);
21
20
  }
22
- return this.animates.set(animate.id, animate), animate.onRemove((() => {
23
- animate.stop(), this.animates.delete(animate.id);
24
- })), null === (_c = this.stage) || void 0 === _c || _c.ticker.start(), animate;
21
+ return null === (_c = this.stage) || void 0 === _c || _c.ticker.start(), animate;
25
22
  }
26
23
  createTimeline() {
27
24
  return new DefaultTimeline;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/animate-extension.ts"],"names":[],"mappings":"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","file":"animate-extension.js","sourcesContent":["// 1. 支持animate函数\n// 2. 支持animates map\n// 2. 支持animatedAttribute 为所有动画的最终结果(loop为INFINITY的动画不算)\n// 3. 支持finalAttribute 为所有动画的最终结果(animatedAttribute 合并了 graphic.attribute之后的最终结果)\n// 3. 重载Graphic的getAttributes方法,根据参数getAttributes(final = true)返回finalAttribute = {}; merge(finalAttribute, graphic.attribute, animatedAttribute),\n// animatedAttribute为所有动画的最终结果(loop为INFINITY的动画不算)\n\nimport type { IGraphicAnimateParams, IAnimate } from '@visactor/vrender-core';\nimport { Animate } from './animate';\nimport { DefaultTimeline, defaultTimeline } from './timeline';\nimport { DefaultTicker } from './ticker/default-ticker';\nimport type { IAnimationConfig } from './executor/executor';\nimport { AnimateExecutor } from './executor/animate-executor';\n\n// 基于性能考虑,每次调用animate函数,都会设置animatedAttribute为null,每次getAttributes(true)会根据animatedAttribute属性判断是否需要重新计算animatedAttribute。\nexport class AnimateExtension {\n declare finalAttribute: Record<string, any>;\n _animateExecutor: AnimateExecutor | null;\n\n declare animates: Map<string | number, IAnimate>;\n\n getAttributes(final: boolean = false) {\n if (final && this.finalAttribute) {\n return this.finalAttribute;\n }\n return (this as any).attribute;\n }\n\n animate(params?: IGraphicAnimateParams) {\n if (!this.animates) {\n this.animates = new Map();\n }\n const animate = new Animate(\n params?.id,\n params?.timeline ?? ((this as any).stage && (this as any).stage.getTimeline()) ?? defaultTimeline,\n params?.slience\n );\n\n animate.bind(this as any);\n if (params) {\n const { onStart, onEnd, onRemove } = params;\n onStart != null && animate.onStart(onStart);\n onEnd != null && animate.onEnd(onEnd);\n onRemove != null && animate.onRemove(onRemove);\n }\n this.animates.set(animate.id, animate);\n animate.onRemove(() => {\n animate.stop();\n this.animates.delete(animate.id);\n });\n\n // TODO 考虑性能问题\n (this as any).stage?.ticker.start();\n\n return animate;\n }\n\n createTimeline() {\n return new DefaultTimeline();\n }\n\n createTicker(stage: any) {\n return new DefaultTicker(stage);\n }\n\n setFinalAttributes(finalAttribute: Record<string, any>) {\n if (!this.finalAttribute) {\n this.finalAttribute = {};\n }\n Object.assign(this.finalAttribute, finalAttribute);\n }\n\n initFinalAttributes(finalAttribute: Record<string, any>) {\n this.finalAttribute = finalAttribute;\n }\n\n initAnimateExecutor(): void {\n if (!this._animateExecutor) {\n this._animateExecutor = new AnimateExecutor(this as any);\n }\n }\n\n /**\n * Apply animation configuration to the component\n * @param config Animation configuration\n * @returns This component instance\n */\n executeAnimation(config: IAnimationConfig): this {\n this.initAnimateExecutor();\n this._animateExecutor.execute(config);\n return this;\n }\n\n /**\n * Apply animations to multiple components\n * @param configs Animation configurations\n * @returns This component instance\n */\n executeAnimations(configs: IAnimationConfig[]): this {\n this.initAnimateExecutor();\n configs.forEach(config => {\n this._animateExecutor.execute(config);\n });\n return this;\n }\n\n protected getFinalAttribute() {\n return this.finalAttribute;\n }\n\n // TODO prev是兼容原本VGrammar函数的一个参数,用于动画中获取上一次属性,目前的逻辑中应该不需要,直接去当前帧的属性即可\n getGraphicAttribute(key: string, prev: boolean = false) {\n if (!prev && this.finalAttribute) {\n return this.finalAttribute[key];\n }\n return (this as any).attribute[key];\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/animate-extension.ts"],"names":[],"mappings":"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","file":"animate-extension.js","sourcesContent":["// 1. 支持animate函数\n// 2. 支持animates map\n// 2. 支持animatedAttribute 为所有动画的最终结果(loop为INFINITY的动画不算)\n// 3. 支持finalAttribute 为所有动画的最终结果(animatedAttribute 合并了 graphic.attribute之后的最终结果)\n// 3. 重载Graphic的getAttributes方法,根据参数getAttributes(final = true)返回finalAttribute = {}; merge(finalAttribute, graphic.attribute, animatedAttribute),\n// animatedAttribute为所有动画的最终结果(loop为INFINITY的动画不算)\n\nimport type { IGraphicAnimateParams, IAnimate } from '@visactor/vrender-core';\nimport { Animate } from './animate';\nimport { DefaultTimeline, defaultTimeline } from './timeline';\nimport { DefaultTicker } from './ticker/default-ticker';\nimport type { IAnimationConfig } from './executor/executor';\nimport { AnimateExecutor } from './executor/animate-executor';\n\n// 基于性能考虑,每次调用animate函数,都会设置animatedAttribute为null,每次getAttributes(true)会根据animatedAttribute属性判断是否需要重新计算animatedAttribute。\nexport class AnimateExtension {\n declare finalAttribute: Record<string, any>;\n _animateExecutor: AnimateExecutor | null;\n\n declare animates: Map<string | number, IAnimate>;\n\n getAttributes(final: boolean = false) {\n if (final && this.finalAttribute) {\n return this.finalAttribute;\n }\n return (this as any).attribute;\n }\n\n animate(params?: IGraphicAnimateParams) {\n const animate = new Animate(\n params?.id,\n params?.timeline ?? ((this as any).stage && (this as any).stage.getTimeline()) ?? defaultTimeline,\n params?.slience\n );\n\n animate.bind(this as any);\n if (params) {\n const { onStart, onEnd, onRemove } = params;\n onStart != null && animate.onStart(onStart);\n onEnd != null && animate.onEnd(onEnd);\n onRemove != null && animate.onRemove(onRemove);\n }\n\n // TODO 考虑性能问题\n (this as any).stage?.ticker.start();\n\n return animate;\n }\n\n createTimeline() {\n return new DefaultTimeline();\n }\n\n createTicker(stage: any) {\n return new DefaultTicker(stage);\n }\n\n setFinalAttributes(finalAttribute: Record<string, any>) {\n if (!this.finalAttribute) {\n this.finalAttribute = {};\n }\n Object.assign(this.finalAttribute, finalAttribute);\n }\n\n initFinalAttributes(finalAttribute: Record<string, any>) {\n this.finalAttribute = finalAttribute;\n }\n\n initAnimateExecutor(): void {\n if (!this._animateExecutor) {\n this._animateExecutor = new AnimateExecutor(this as any);\n }\n }\n\n /**\n * Apply animation configuration to the component\n * @param config Animation configuration\n * @returns This component instance\n */\n executeAnimation(config: IAnimationConfig): this {\n this.initAnimateExecutor();\n this._animateExecutor.execute(config);\n return this;\n }\n\n /**\n * Apply animations to multiple components\n * @param configs Animation configurations\n * @returns This component instance\n */\n executeAnimations(configs: IAnimationConfig[]): this {\n this.initAnimateExecutor();\n configs.forEach(config => {\n this._animateExecutor.execute(config);\n });\n return this;\n }\n\n protected getFinalAttribute() {\n return this.finalAttribute;\n }\n\n // TODO prev是兼容原本VGrammar函数的一个参数,用于动画中获取上一次属性,目前的逻辑中应该不需要,直接去当前帧的属性即可\n getGraphicAttribute(key: string, prev: boolean = false) {\n if (!prev && this.finalAttribute) {\n return this.finalAttribute[key];\n }\n return (this as any).attribute[key];\n }\n}\n"]}
package/es/animate.js CHANGED
@@ -28,7 +28,10 @@ export class Animate {
28
28
  return this._timeline;
29
29
  }
30
30
  bind(target) {
31
- return this.target = target, this.target.onAnimateBind && !this.slience && this.target.onAnimateBind(this),
31
+ return this.target = target, this.target.animates || (this.target.animates = new Map),
32
+ this.target.animates.set(this.id, this), this.onRemove((() => {
33
+ this.stop(), this.target.animates.delete(this.id);
34
+ })), this.target.onAnimateBind && !this.slience && this.target.onAnimateBind(this),
32
35
  this.target.animationAttribute || (this.target.animationAttribute = {}), this;
33
36
  }
34
37
  to(props, duration = 300, easing = "linear") {
package/es/animate.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/animate.ts"],"names":[],"mappings":"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","file":"animate.js","sourcesContent":["import { Step, WaitStep } from './step';\nimport {\n Generator,\n AnimateStatus,\n AnimateStepType,\n type IGraphic,\n type IAnimate,\n type IStep,\n type ICustomAnimate,\n type EasingType,\n type ITimeline\n} from '@visactor/vrender-core';\nimport { defaultTimeline } from './timeline';\n\nexport class Animate implements IAnimate {\n readonly id: string | number;\n status: AnimateStatus;\n target: IGraphic;\n\n // 回调函数列表\n _onStart?: (() => void)[];\n _onFrame?: ((step: IStep, ratio: number) => void)[];\n _onEnd?: (() => void)[];\n _onRemove?: (() => void)[];\n\n // 时间控制\n private _timeline: ITimeline;\n private _startTime: number;\n private _duration: number;\n private _totalDuration: number;\n\n // 动画控制\n // private _reversed: boolean;\n private _loopCount: number;\n private _currentLoop: number;\n private _bounce: boolean;\n\n // 链表头节点和尾节点\n private _firstStep: IStep | null;\n private _lastStep: IStep | null;\n\n // 初始属性和屏蔽的属性\n private _startProps: Record<string, any>;\n private _endProps: Record<string, any>;\n private _preventAttrs: Set<string>;\n // 优先级,用于判定是否能被后续的动画preventAttr\n declare priority: number;\n\n protected currentTime: number;\n slience?: boolean;\n\n // 临时变量\n lastRunStep?: IStep;\n\n interpolateUpdateFunction:\n | ((from: Record<string, any>, to: Record<string, any>, ratio: number, step: IStep, target: IGraphic) => void)\n | null;\n\n constructor(\n id: string | number = Generator.GenAutoIncrementId(),\n timeline: ITimeline = defaultTimeline,\n slience?: boolean\n ) {\n this.id = id;\n this.status = AnimateStatus.INITIAL;\n this._timeline = timeline;\n timeline.addAnimate(this);\n this.slience = slience;\n this._startTime = 0;\n this._duration = 0;\n this._totalDuration = 0;\n // this._reversed = false;\n this._loopCount = 0;\n this._currentLoop = 0;\n this._bounce = false;\n this._firstStep = null;\n this._lastStep = null;\n this._startProps = {};\n this._endProps = {};\n this._preventAttrs = new Set();\n this.currentTime = 0;\n this.interpolateUpdateFunction = null;\n this.priority = 0;\n }\n\n /**\n * 获取开始属性\n */\n getStartProps(): Record<string, any> {\n return this._startProps;\n }\n\n /**\n * 获取结束属性\n */\n getEndProps(): Record<string, any> {\n return this._endProps;\n }\n\n /**\n * 设置时间线\n */\n setTimeline(timeline: ITimeline): void {\n this._timeline = timeline;\n }\n\n /**\n * 获取时间线\n */\n getTimeline(): ITimeline {\n return this._timeline;\n }\n\n /**\n * 时间线属性访问器\n */\n get timeline(): ITimeline {\n return this._timeline;\n }\n\n /**\n * 绑定目标图形\n */\n bind(target: IGraphic): this {\n this.target = target;\n\n if (this.target.onAnimateBind && !this.slience) {\n this.target.onAnimateBind(this as any);\n }\n // 添加一个animationAttribute属性,用于存储动画过程中的属性\n if (!this.target.animationAttribute) {\n this.target.animationAttribute = {};\n }\n return this;\n }\n\n /**\n * 动画步骤:to\n * 添加一个to步骤,这会在当前状态到指定状态间进行插值\n */\n to(props: Record<string, any>, duration: number = 300, easing: EasingType = 'linear'): this {\n // 创建新的step\n const step = new Step(AnimateStepType.to, props, duration, easing);\n\n step.bind(this.target, this);\n\n this.updateStepAfterAppend(step);\n\n return this;\n }\n\n /**\n * 等待延迟\n */\n wait(delay: number): this {\n // 创建新的wait step\n const step = new WaitStep(AnimateStepType.wait, {}, delay, 'linear');\n\n step.bind(this.target, this);\n\n this.updateStepAfterAppend(step);\n\n return this;\n }\n\n protected updateStepAfterAppend(step: IStep): void {\n // 如果是第一个step\n if (!this._firstStep) {\n this._firstStep = step;\n this._lastStep = step;\n } else {\n // 添加到链表末尾\n this._lastStep.append(step);\n this._lastStep = step;\n }\n\n this.parseStepProps(step);\n\n this.updateDuration();\n }\n\n /**\n * 解析step的props\n * 1. 预先获取step的propKeys并保存\n * 2. 将截止目前的最新props设置到step.props中,这样该props上的属性就是最终的属性了,跳帧时直接设置即可\n * 3. 同步到_endProps中,保存这个Animate实例的最终props\n * 4. 给step的props的原型链上绑定Animate的_startProps,这样在下一个step查找fromProps的时候,一定能拿得到值\n */\n parseStepProps(step: IStep) {\n if (!this._lastStep) {\n return;\n }\n\n /* 预设置step的属性,基于性能考虑,实现比较复杂 */\n // step.propKeys为真实的props属性的key\n step.propKeys = step.propKeys || Object.keys(step.props);\n // step.props为包含前序step的props的最终props,用于跳帧等场景,可以直接设置\n Object.keys(this._endProps).forEach(key => {\n step.props[key] = step.props[key] ?? this._endProps[key];\n });\n // 将最终的props设置到step.props中\n step.propKeys.forEach(key => {\n this._endProps[key] = step.props[key];\n });\n // 给step的props的原型链上绑定Animate的_startProps\n // 下一个step在查找上一个step.props(也就是找到它的fromProps)的时候,就能拿到初始的props了\n // 比如:\n // rect.animate().to({ x: 100 }, 1000, 'linear').to({ y: 100 }, 1000, 'linear');\n // 在第二个step查找fromProps的时候,就能拿到第一个step的endProps中的y值(在原型链上)\n // TODO 由于会有其他animate的干扰,所以不能直接设置原型链\n // Object.setPrototypeOf(step.props, this._startProps);\n }\n\n /**\n * 重新同步和计算props,用于内部某些step发生了变更后,重新计算自身\n * 性能较差,不要频繁调用\n * @returns\n */\n reSyncProps() {\n if (!this._lastStep) {\n return;\n }\n this._endProps = {};\n let currentStep: IStep = this._firstStep;\n // 从前向后寻找当前时间所在的step\n while (currentStep) {\n // step.props为包含前序step的props的最终props,用于跳帧等场景,可以直接设置\n // eslint-disable-next-line no-loop-func\n Object.keys(this._endProps).forEach(key => {\n currentStep.props[key] = currentStep.props[key] ?? this._endProps[key];\n });\n // 将最终的props设置到step.props中\n // eslint-disable-next-line no-loop-func\n currentStep.propKeys.forEach(key => {\n this._endProps[key] = currentStep.props[key];\n });\n // 给step的props的原型链上绑定Animate的_startProps\n // 下一个step在查找上一个step.props(也就是找到它的fromProps)的时候,就能拿到初始的props了\n // 比如:\n // rect.animate().to({ x: 100 }, 1000, 'linear').to({ y: 100 }, 1000, 'linear');\n // 在第二个step查找fromProps的时候,就能拿到第一个step的endProps中的y值(在原型链上)\n // TODO 由于会有其他animate的干扰,所以不能直接设置原型链\n // Object.setPrototypeOf(currentStep.props, this._startProps);\n currentStep = currentStep.next;\n }\n }\n\n /**\n * 动画步骤:from\n * 添加一个from步骤,这会将目标属性先设置为指定值,然后过渡到当前状态\n * 【注意】这可能会导致动画跳变,请谨慎使用\n */\n from(props: Record<string, any>, duration: number = 300, easing: EasingType = 'linear'): this {\n // 创建新的step\n const step = new Step(AnimateStepType.from, props, duration, easing);\n\n // 如果是第一个step\n if (!this._firstStep) {\n this._firstStep = step;\n this._lastStep = step;\n } else {\n // 添加到链表末尾\n this._lastStep.append(step);\n this._lastStep = step;\n }\n\n this.updateDuration();\n\n return this;\n }\n\n /**\n * 自定义动画\n */\n play(customAnimate: ICustomAnimate): this {\n customAnimate.bind(this.target, this);\n this.updateStepAfterAppend(customAnimate);\n\n return this;\n }\n\n /**\n * 暂停动画\n */\n pause(): void {\n if (this.status === AnimateStatus.RUNNING) {\n this.status = AnimateStatus.PAUSED;\n }\n }\n\n /**\n * 恢复动画\n */\n resume(): void {\n if (this.status === AnimateStatus.PAUSED) {\n this.status = AnimateStatus.RUNNING;\n }\n }\n\n /**\n * 注册开始回调\n */\n onStart(cb?: () => void): void {\n if (cb) {\n if (!this._onStart) {\n this._onStart = [];\n }\n this._onStart.push(cb);\n } else {\n this._onStart?.forEach(cb => cb());\n // 设置开始属性,Animate不会重复执行start所以不需要判断firstStart\n Object.keys(this._endProps).forEach(key => {\n this._startProps[key] = this.target.getComputedAttribute(key);\n });\n }\n }\n\n /**\n * 注册结束回调\n */\n onEnd(cb?: () => void): void {\n if (cb) {\n if (!this._onEnd) {\n this._onEnd = [];\n }\n this._onEnd.push(cb);\n } else {\n this._onEnd?.forEach(cb => cb());\n }\n }\n\n /**\n * 注册帧回调\n */\n onFrame(cb?: (step: IStep, ratio: number) => void): void {\n if (cb) {\n if (!this._onFrame) {\n this._onFrame = [];\n }\n this._onFrame.push(cb);\n }\n }\n\n /**\n * 注册移除回调\n */\n onRemove(cb?: () => void): void {\n if (cb) {\n if (!this._onRemove) {\n this._onRemove = [];\n }\n this._onRemove.push(cb);\n } else {\n this._onRemove?.forEach(cb => cb());\n }\n }\n\n /**\n * 屏蔽单个属性\n */\n preventAttr(key: string): void {\n this._preventAttrs.add(key);\n // 从所有step中移除该属性,并从自身的_startProps和_endProps中移除该属性\n delete this._startProps[key];\n delete this._endProps[key];\n let step = this._firstStep;\n while (step) {\n step.deleteSelfAttr(key);\n step = step.next;\n }\n }\n\n /**\n * 屏蔽多个属性\n */\n preventAttrs(keys: string[]): void {\n keys.forEach(key => this._preventAttrs.add(key));\n }\n\n /**\n * 检查属性是否合法(未被屏蔽)\n */\n validAttr(key: string): boolean {\n return !this._preventAttrs.has(key);\n }\n\n /**\n * 运行自定义回调\n */\n runCb(cb: (a: IAnimate, step: IStep) => void): IAnimate {\n this._lastStep?.onEnd(cb);\n return this;\n }\n\n /**\n * 设置动画开始时间\n */\n startAt(t: number): this {\n this._startTime = t;\n\n return this;\n }\n\n /**\n * 自定义插值函数,返回false表示没有匹配上\n */\n customInterpolate(\n key: string,\n ratio: number,\n from: any,\n to: any,\n target: IGraphic,\n ret: Record<string, any>\n ): boolean {\n // 默认无自定义插值,可由子类重写\n return false;\n }\n\n /**\n * 获取起始值,该起始值为animate的起始值,并不一定为step的起始值\n */\n getFromValue(): Record<string, any> {\n return this._startProps;\n }\n\n /**\n * 获取结束值\n */\n getToValue(): Record<string, any> {\n return this._endProps;\n }\n\n /**\n * 停止动画\n */\n stop(type?: 'start' | 'end' | Record<string, any>): void {\n // TODO 有些动画可能一添加就被删除\n // if (this.status === AnimateStatus.END) {\n // return;\n // }\n // 遍历step,调用其stop\n let step = this._firstStep;\n while (step) {\n step.stop();\n step = step.next;\n }\n\n if (this.status !== AnimateStatus.END) {\n this.onEnd();\n }\n\n this.status = AnimateStatus.END;\n\n if (!this.target) {\n return;\n }\n\n if (type === 'start') {\n // 设置为开始状态\n this.target.setAttributes(this._startProps);\n } else if (type === 'end') {\n // 设置为结束状态\n this.target.setAttributes(this._endProps);\n } else if (type) {\n // 设置为自定义状态\n this.target.setAttributes(type);\n }\n }\n\n /**\n * 释放动画资源\n */\n release(): void {\n this.status = AnimateStatus.END;\n\n // 触发移除回调\n if (this._onRemove) {\n this._onRemove.forEach(cb => cb());\n }\n\n // 清空回调\n this._onStart = [];\n this._onFrame = [];\n this._onEnd = [];\n this._onRemove = [];\n }\n\n /**\n * 获取动画持续时间\n */\n getDuration(): number {\n return this._duration;\n }\n\n /**\n * 获取动画开始时间\n */\n getStartTime(): number {\n return this._startTime;\n }\n\n /**\n * 在所有动画完成后执行\n */\n afterAll(list: IAnimate[]): this {\n if (!list || list.length === 0) {\n return this;\n }\n\n // 计算所有动画结束的最大时间点\n let maxEndTime = 0;\n list.forEach(animate => {\n const endTime = animate.getStartTime() + animate.getTotalDuration();\n maxEndTime = Math.max(maxEndTime, endTime);\n });\n\n // 设置当前动画的开始时间为最大结束时间\n return this.startAt(maxEndTime);\n }\n\n /**\n * 在指定动画完成后执行\n */\n after(animate: IAnimate): this {\n if (!animate) {\n return this;\n }\n\n // 计算指定动画结束的时间点\n const endTime = animate.getStartTime() + animate.getTotalDuration();\n\n // 设置当前动画的开始时间为结束时间\n return this.startAt(endTime);\n }\n\n /**\n * 并行执行动画\n */\n parallel(animate: IAnimate): this {\n if (!animate) {\n return this;\n }\n\n // 设置指定动画的开始时间为当前动画的开始时间\n this.startAt(animate.getStartTime());\n\n return this;\n }\n\n // /**\n // * 设置动画是否反转\n // */\n // reversed(r: boolean): this {\n // this._reversed = r;\n // return this;\n // }\n\n /**\n * 设置动画循环次数,如果传入true,则无限循环,如果传入false,则不循环\n */\n loop(n: number | boolean): this {\n if (n === true) {\n n = Infinity;\n } else if (n === false) {\n n = 0;\n }\n this._loopCount = n;\n this.updateDuration();\n return this;\n }\n\n /**\n * 设置动画是否反弹\n */\n bounce(b: boolean): this {\n this._bounce = b;\n return this;\n }\n\n /**\n * 推进动画\n */\n advance(delta: number): void {\n if (this.status === AnimateStatus.END) {\n console.warn('aaa 动画已经结束,不能推进');\n return;\n }\n const nextTime = this.currentTime + delta;\n // 如果还没开始,直接return\n if (nextTime < this._startTime) {\n this.currentTime = nextTime;\n return;\n }\n // 如果已经结束,设置状态后return\n if (nextTime >= this._startTime + this._totalDuration) {\n this._lastStep?.onUpdate(true, 1, {});\n this._lastStep?.onEnd();\n this.onEnd();\n this.status = AnimateStatus.END;\n return;\n }\n\n this.status = AnimateStatus.RUNNING;\n\n // 如果是第一次运行,触发开始回调\n if (this.currentTime <= this._startTime) {\n this.onStart();\n }\n this.currentTime = nextTime;\n\n let cycleTime = nextTime - this._startTime;\n let newLoop = false;\n let bounceTime = false;\n if (this._loopCount > 0) {\n cycleTime = (nextTime - this._startTime) % this._duration;\n const currentLoop = Math.floor((nextTime - this._startTime) / this._duration);\n newLoop = currentLoop > this._currentLoop;\n this._currentLoop = currentLoop;\n\n bounceTime = this._bounce && currentLoop % 2 === 1;\n if (bounceTime) {\n cycleTime = this._duration - cycleTime;\n }\n }\n\n // 如果是新的循环,重置为初始状态\n if (newLoop && !bounceTime) {\n this.target.setAttributes(this._startProps);\n }\n\n // 选择起始步骤和遍历方向\n let targetStep: IStep | null = null;\n\n if (this._lastStep === this._firstStep) {\n targetStep = this._firstStep;\n } else {\n let currentStep: IStep = this._firstStep;\n // 从前向后寻找当前时间所在的step\n while (currentStep) {\n const stepStartTime = currentStep.getStartTime();\n const stepDuration = currentStep.getDuration();\n const stepEndTime = stepStartTime + stepDuration;\n\n // 找到当前周期时间所在的step\n if (cycleTime >= stepStartTime && cycleTime <= stepEndTime) {\n targetStep = currentStep;\n break;\n }\n\n currentStep = currentStep.next;\n }\n }\n\n // 如果没找到目标step(可能是所有step都执行完了,但整体动画还没结束,这正常是不存在的)\n if (!targetStep) {\n // this.currentTime = nextTime;\n // console.warn('动画出现问题');\n return;\n }\n\n // 如果当前step和上一次执行的step不一样,则调用上一次step的onEnd,确保所有完成的step都调用了结束\n // 如果上一次的step已经调用了onEnd,在下面的onEnd那里会将lastRunStep设置为null\n if (targetStep !== this.lastRunStep) {\n this.lastRunStep?.onEnd();\n }\n\n this.lastRunStep = targetStep;\n\n // 计算当前step的进度比例(基于当前step内的相对时间)\n const stepStartTime = targetStep.getStartTime();\n const stepDuration = targetStep.getDuration();\n\n const ratio = (cycleTime - stepStartTime) / stepDuration;\n // // 限制ratio在0-1之间\n // ratio = Math.max(0, Math.min(1, ratio));\n\n const isEnd = ratio >= 1;\n targetStep.update(isEnd, ratio, {});\n\n // 如果step执行完毕\n if (isEnd) {\n targetStep.onEnd();\n this.lastRunStep = null;\n // 不立即调用onFinish,让动画系统来决定何时结束\n }\n\n // 触发帧回调\n // if (this._onFrame) {\n // this._onFrame.forEach(cb => cb(targetStep, ratio));\n // }\n }\n\n updateDuration(): void {\n if (!this._lastStep) {\n this._duration = 0;\n return;\n }\n\n this._duration = this._lastStep.getStartTime() + this._lastStep.getDuration();\n this._totalDuration = this._duration * (this._loopCount + 1);\n }\n\n getTotalDuration(): number {\n return this._totalDuration;\n }\n\n getLoop(): number {\n return this._loopCount;\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/animate.ts"],"names":[],"mappings":"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","file":"animate.js","sourcesContent":["import { Step, WaitStep } from './step';\nimport {\n Generator,\n AnimateStatus,\n AnimateStepType,\n type IGraphic,\n type IAnimate,\n type IStep,\n type ICustomAnimate,\n type EasingType,\n type ITimeline\n} from '@visactor/vrender-core';\nimport { defaultTimeline } from './timeline';\n\nexport class Animate implements IAnimate {\n readonly id: string | number;\n status: AnimateStatus;\n target: IGraphic;\n\n // 回调函数列表\n _onStart?: (() => void)[];\n _onFrame?: ((step: IStep, ratio: number) => void)[];\n _onEnd?: (() => void)[];\n _onRemove?: (() => void)[];\n\n // 时间控制\n private _timeline: ITimeline;\n private _startTime: number;\n private _duration: number;\n private _totalDuration: number;\n\n // 动画控制\n // private _reversed: boolean;\n private _loopCount: number;\n private _currentLoop: number;\n private _bounce: boolean;\n\n // 链表头节点和尾节点\n private _firstStep: IStep | null;\n private _lastStep: IStep | null;\n\n // 初始属性和屏蔽的属性\n private _startProps: Record<string, any>;\n private _endProps: Record<string, any>;\n private _preventAttrs: Set<string>;\n // 优先级,用于判定是否能被后续的动画preventAttr\n declare priority: number;\n\n protected currentTime: number;\n slience?: boolean;\n\n // 临时变量\n lastRunStep?: IStep;\n\n interpolateUpdateFunction:\n | ((from: Record<string, any>, to: Record<string, any>, ratio: number, step: IStep, target: IGraphic) => void)\n | null;\n\n constructor(\n id: string | number = Generator.GenAutoIncrementId(),\n timeline: ITimeline = defaultTimeline,\n slience?: boolean\n ) {\n this.id = id;\n this.status = AnimateStatus.INITIAL;\n this._timeline = timeline;\n timeline.addAnimate(this);\n this.slience = slience;\n this._startTime = 0;\n this._duration = 0;\n this._totalDuration = 0;\n // this._reversed = false;\n this._loopCount = 0;\n this._currentLoop = 0;\n this._bounce = false;\n this._firstStep = null;\n this._lastStep = null;\n this._startProps = {};\n this._endProps = {};\n this._preventAttrs = new Set();\n this.currentTime = 0;\n this.interpolateUpdateFunction = null;\n this.priority = 0;\n }\n\n /**\n * 获取开始属性\n */\n getStartProps(): Record<string, any> {\n return this._startProps;\n }\n\n /**\n * 获取结束属性\n */\n getEndProps(): Record<string, any> {\n return this._endProps;\n }\n\n /**\n * 设置时间线\n */\n setTimeline(timeline: ITimeline): void {\n this._timeline = timeline;\n }\n\n /**\n * 获取时间线\n */\n getTimeline(): ITimeline {\n return this._timeline;\n }\n\n /**\n * 时间线属性访问器\n */\n get timeline(): ITimeline {\n return this._timeline;\n }\n\n /**\n * 绑定目标图形\n */\n bind(target: IGraphic): this {\n this.target = target;\n\n if (!this.target.animates) {\n this.target.animates = new Map();\n }\n this.target.animates.set(this.id, this);\n this.onRemove(() => {\n this.stop();\n this.target.animates.delete(this.id);\n });\n\n if (this.target.onAnimateBind && !this.slience) {\n this.target.onAnimateBind(this as any);\n }\n // 添加一个animationAttribute属性,用于存储动画过程中的属性\n if (!this.target.animationAttribute) {\n this.target.animationAttribute = {};\n }\n return this;\n }\n\n /**\n * 动画步骤:to\n * 添加一个to步骤,这会在当前状态到指定状态间进行插值\n */\n to(props: Record<string, any>, duration: number = 300, easing: EasingType = 'linear'): this {\n // 创建新的step\n const step = new Step(AnimateStepType.to, props, duration, easing);\n\n step.bind(this.target, this);\n\n this.updateStepAfterAppend(step);\n\n return this;\n }\n\n /**\n * 等待延迟\n */\n wait(delay: number): this {\n // 创建新的wait step\n const step = new WaitStep(AnimateStepType.wait, {}, delay, 'linear');\n\n step.bind(this.target, this);\n\n this.updateStepAfterAppend(step);\n\n return this;\n }\n\n protected updateStepAfterAppend(step: IStep): void {\n // 如果是第一个step\n if (!this._firstStep) {\n this._firstStep = step;\n this._lastStep = step;\n } else {\n // 添加到链表末尾\n this._lastStep.append(step);\n this._lastStep = step;\n }\n\n this.parseStepProps(step);\n\n this.updateDuration();\n }\n\n /**\n * 解析step的props\n * 1. 预先获取step的propKeys并保存\n * 2. 将截止目前的最新props设置到step.props中,这样该props上的属性就是最终的属性了,跳帧时直接设置即可\n * 3. 同步到_endProps中,保存这个Animate实例的最终props\n * 4. 给step的props的原型链上绑定Animate的_startProps,这样在下一个step查找fromProps的时候,一定能拿得到值\n */\n parseStepProps(step: IStep) {\n if (!this._lastStep) {\n return;\n }\n\n /* 预设置step的属性,基于性能考虑,实现比较复杂 */\n // step.propKeys为真实的props属性的key\n step.propKeys = step.propKeys || Object.keys(step.props);\n // step.props为包含前序step的props的最终props,用于跳帧等场景,可以直接设置\n Object.keys(this._endProps).forEach(key => {\n step.props[key] = step.props[key] ?? this._endProps[key];\n });\n // 将最终的props设置到step.props中\n step.propKeys.forEach(key => {\n this._endProps[key] = step.props[key];\n });\n // 给step的props的原型链上绑定Animate的_startProps\n // 下一个step在查找上一个step.props(也就是找到它的fromProps)的时候,就能拿到初始的props了\n // 比如:\n // rect.animate().to({ x: 100 }, 1000, 'linear').to({ y: 100 }, 1000, 'linear');\n // 在第二个step查找fromProps的时候,就能拿到第一个step的endProps中的y值(在原型链上)\n // TODO 由于会有其他animate的干扰,所以不能直接设置原型链\n // Object.setPrototypeOf(step.props, this._startProps);\n }\n\n /**\n * 重新同步和计算props,用于内部某些step发生了变更后,重新计算自身\n * 性能较差,不要频繁调用\n * @returns\n */\n reSyncProps() {\n if (!this._lastStep) {\n return;\n }\n this._endProps = {};\n let currentStep: IStep = this._firstStep;\n // 从前向后寻找当前时间所在的step\n while (currentStep) {\n // step.props为包含前序step的props的最终props,用于跳帧等场景,可以直接设置\n // eslint-disable-next-line no-loop-func\n Object.keys(this._endProps).forEach(key => {\n currentStep.props[key] = currentStep.props[key] ?? this._endProps[key];\n });\n // 将最终的props设置到step.props中\n // eslint-disable-next-line no-loop-func\n currentStep.propKeys.forEach(key => {\n this._endProps[key] = currentStep.props[key];\n });\n // 给step的props的原型链上绑定Animate的_startProps\n // 下一个step在查找上一个step.props(也就是找到它的fromProps)的时候,就能拿到初始的props了\n // 比如:\n // rect.animate().to({ x: 100 }, 1000, 'linear').to({ y: 100 }, 1000, 'linear');\n // 在第二个step查找fromProps的时候,就能拿到第一个step的endProps中的y值(在原型链上)\n // TODO 由于会有其他animate的干扰,所以不能直接设置原型链\n // Object.setPrototypeOf(currentStep.props, this._startProps);\n currentStep = currentStep.next;\n }\n }\n\n /**\n * 动画步骤:from\n * 添加一个from步骤,这会将目标属性先设置为指定值,然后过渡到当前状态\n * 【注意】这可能会导致动画跳变,请谨慎使用\n */\n from(props: Record<string, any>, duration: number = 300, easing: EasingType = 'linear'): this {\n // 创建新的step\n const step = new Step(AnimateStepType.from, props, duration, easing);\n\n // 如果是第一个step\n if (!this._firstStep) {\n this._firstStep = step;\n this._lastStep = step;\n } else {\n // 添加到链表末尾\n this._lastStep.append(step);\n this._lastStep = step;\n }\n\n this.updateDuration();\n\n return this;\n }\n\n /**\n * 自定义动画\n */\n play(customAnimate: ICustomAnimate): this {\n customAnimate.bind(this.target, this);\n this.updateStepAfterAppend(customAnimate);\n\n return this;\n }\n\n /**\n * 暂停动画\n */\n pause(): void {\n if (this.status === AnimateStatus.RUNNING) {\n this.status = AnimateStatus.PAUSED;\n }\n }\n\n /**\n * 恢复动画\n */\n resume(): void {\n if (this.status === AnimateStatus.PAUSED) {\n this.status = AnimateStatus.RUNNING;\n }\n }\n\n /**\n * 注册开始回调\n */\n onStart(cb?: () => void): void {\n if (cb) {\n if (!this._onStart) {\n this._onStart = [];\n }\n this._onStart.push(cb);\n } else {\n this._onStart?.forEach(cb => cb());\n // 设置开始属性,Animate不会重复执行start所以不需要判断firstStart\n Object.keys(this._endProps).forEach(key => {\n this._startProps[key] = this.target.getComputedAttribute(key);\n });\n }\n }\n\n /**\n * 注册结束回调\n */\n onEnd(cb?: () => void): void {\n if (cb) {\n if (!this._onEnd) {\n this._onEnd = [];\n }\n this._onEnd.push(cb);\n } else {\n this._onEnd?.forEach(cb => cb());\n }\n }\n\n /**\n * 注册帧回调\n */\n onFrame(cb?: (step: IStep, ratio: number) => void): void {\n if (cb) {\n if (!this._onFrame) {\n this._onFrame = [];\n }\n this._onFrame.push(cb);\n }\n }\n\n /**\n * 注册移除回调\n */\n onRemove(cb?: () => void): void {\n if (cb) {\n if (!this._onRemove) {\n this._onRemove = [];\n }\n this._onRemove.push(cb);\n } else {\n this._onRemove?.forEach(cb => cb());\n }\n }\n\n /**\n * 屏蔽单个属性\n */\n preventAttr(key: string): void {\n this._preventAttrs.add(key);\n // 从所有step中移除该属性,并从自身的_startProps和_endProps中移除该属性\n delete this._startProps[key];\n delete this._endProps[key];\n let step = this._firstStep;\n while (step) {\n step.deleteSelfAttr(key);\n step = step.next;\n }\n }\n\n /**\n * 屏蔽多个属性\n */\n preventAttrs(keys: string[]): void {\n keys.forEach(key => this._preventAttrs.add(key));\n }\n\n /**\n * 检查属性是否合法(未被屏蔽)\n */\n validAttr(key: string): boolean {\n return !this._preventAttrs.has(key);\n }\n\n /**\n * 运行自定义回调\n */\n runCb(cb: (a: IAnimate, step: IStep) => void): IAnimate {\n this._lastStep?.onEnd(cb);\n return this;\n }\n\n /**\n * 设置动画开始时间\n */\n startAt(t: number): this {\n this._startTime = t;\n\n return this;\n }\n\n /**\n * 自定义插值函数,返回false表示没有匹配上\n */\n customInterpolate(\n key: string,\n ratio: number,\n from: any,\n to: any,\n target: IGraphic,\n ret: Record<string, any>\n ): boolean {\n // 默认无自定义插值,可由子类重写\n return false;\n }\n\n /**\n * 获取起始值,该起始值为animate的起始值,并不一定为step的起始值\n */\n getFromValue(): Record<string, any> {\n return this._startProps;\n }\n\n /**\n * 获取结束值\n */\n getToValue(): Record<string, any> {\n return this._endProps;\n }\n\n /**\n * 停止动画\n */\n stop(type?: 'start' | 'end' | Record<string, any>): void {\n // TODO 有些动画可能一添加就被删除\n // if (this.status === AnimateStatus.END) {\n // return;\n // }\n // 遍历step,调用其stop\n let step = this._firstStep;\n while (step) {\n step.stop();\n step = step.next;\n }\n\n if (this.status !== AnimateStatus.END) {\n this.onEnd();\n }\n\n this.status = AnimateStatus.END;\n\n if (!this.target) {\n return;\n }\n\n if (type === 'start') {\n // 设置为开始状态\n this.target.setAttributes(this._startProps);\n } else if (type === 'end') {\n // 设置为结束状态\n this.target.setAttributes(this._endProps);\n } else if (type) {\n // 设置为自定义状态\n this.target.setAttributes(type);\n }\n }\n\n /**\n * 释放动画资源\n */\n release(): void {\n this.status = AnimateStatus.END;\n\n // 触发移除回调\n if (this._onRemove) {\n this._onRemove.forEach(cb => cb());\n }\n\n // 清空回调\n this._onStart = [];\n this._onFrame = [];\n this._onEnd = [];\n this._onRemove = [];\n }\n\n /**\n * 获取动画持续时间\n */\n getDuration(): number {\n return this._duration;\n }\n\n /**\n * 获取动画开始时间\n */\n getStartTime(): number {\n return this._startTime;\n }\n\n /**\n * 在所有动画完成后执行\n */\n afterAll(list: IAnimate[]): this {\n if (!list || list.length === 0) {\n return this;\n }\n\n // 计算所有动画结束的最大时间点\n let maxEndTime = 0;\n list.forEach(animate => {\n const endTime = animate.getStartTime() + animate.getTotalDuration();\n maxEndTime = Math.max(maxEndTime, endTime);\n });\n\n // 设置当前动画的开始时间为最大结束时间\n return this.startAt(maxEndTime);\n }\n\n /**\n * 在指定动画完成后执行\n */\n after(animate: IAnimate): this {\n if (!animate) {\n return this;\n }\n\n // 计算指定动画结束的时间点\n const endTime = animate.getStartTime() + animate.getTotalDuration();\n\n // 设置当前动画的开始时间为结束时间\n return this.startAt(endTime);\n }\n\n /**\n * 并行执行动画\n */\n parallel(animate: IAnimate): this {\n if (!animate) {\n return this;\n }\n\n // 设置指定动画的开始时间为当前动画的开始时间\n this.startAt(animate.getStartTime());\n\n return this;\n }\n\n // /**\n // * 设置动画是否反转\n // */\n // reversed(r: boolean): this {\n // this._reversed = r;\n // return this;\n // }\n\n /**\n * 设置动画循环次数,如果传入true,则无限循环,如果传入false,则不循环\n */\n loop(n: number | boolean): this {\n if (n === true) {\n n = Infinity;\n } else if (n === false) {\n n = 0;\n }\n this._loopCount = n;\n this.updateDuration();\n return this;\n }\n\n /**\n * 设置动画是否反弹\n */\n bounce(b: boolean): this {\n this._bounce = b;\n return this;\n }\n\n /**\n * 推进动画\n */\n advance(delta: number): void {\n if (this.status === AnimateStatus.END) {\n console.warn('aaa 动画已经结束,不能推进');\n return;\n }\n const nextTime = this.currentTime + delta;\n // 如果还没开始,直接return\n if (nextTime < this._startTime) {\n this.currentTime = nextTime;\n return;\n }\n // 如果已经结束,设置状态后return\n if (nextTime >= this._startTime + this._totalDuration) {\n this._lastStep?.onUpdate(true, 1, {});\n this._lastStep?.onEnd();\n this.onEnd();\n this.status = AnimateStatus.END;\n return;\n }\n\n this.status = AnimateStatus.RUNNING;\n\n // 如果是第一次运行,触发开始回调\n if (this.currentTime <= this._startTime) {\n this.onStart();\n }\n this.currentTime = nextTime;\n\n let cycleTime = nextTime - this._startTime;\n let newLoop = false;\n let bounceTime = false;\n if (this._loopCount > 0) {\n cycleTime = (nextTime - this._startTime) % this._duration;\n const currentLoop = Math.floor((nextTime - this._startTime) / this._duration);\n newLoop = currentLoop > this._currentLoop;\n this._currentLoop = currentLoop;\n\n bounceTime = this._bounce && currentLoop % 2 === 1;\n if (bounceTime) {\n cycleTime = this._duration - cycleTime;\n }\n }\n\n // 如果是新的循环,重置为初始状态\n if (newLoop && !bounceTime) {\n this.target.setAttributes(this._startProps);\n }\n\n // 选择起始步骤和遍历方向\n let targetStep: IStep | null = null;\n\n if (this._lastStep === this._firstStep) {\n targetStep = this._firstStep;\n } else {\n let currentStep: IStep = this._firstStep;\n // 从前向后寻找当前时间所在的step\n while (currentStep) {\n const stepStartTime = currentStep.getStartTime();\n const stepDuration = currentStep.getDuration();\n const stepEndTime = stepStartTime + stepDuration;\n\n // 找到当前周期时间所在的step\n if (cycleTime >= stepStartTime && cycleTime <= stepEndTime) {\n targetStep = currentStep;\n break;\n }\n\n currentStep = currentStep.next;\n }\n }\n\n // 如果没找到目标step(可能是所有step都执行完了,但整体动画还没结束,这正常是不存在的)\n if (!targetStep) {\n // this.currentTime = nextTime;\n // console.warn('动画出现问题');\n return;\n }\n\n // 如果当前step和上一次执行的step不一样,则调用上一次step的onEnd,确保所有完成的step都调用了结束\n // 如果上一次的step已经调用了onEnd,在下面的onEnd那里会将lastRunStep设置为null\n if (targetStep !== this.lastRunStep) {\n this.lastRunStep?.onEnd();\n }\n\n this.lastRunStep = targetStep;\n\n // 计算当前step的进度比例(基于当前step内的相对时间)\n const stepStartTime = targetStep.getStartTime();\n const stepDuration = targetStep.getDuration();\n\n const ratio = (cycleTime - stepStartTime) / stepDuration;\n // // 限制ratio在0-1之间\n // ratio = Math.max(0, Math.min(1, ratio));\n\n const isEnd = ratio >= 1;\n targetStep.update(isEnd, ratio, {});\n\n // 如果step执行完毕\n if (isEnd) {\n targetStep.onEnd();\n this.lastRunStep = null;\n // 不立即调用onFinish,让动画系统来决定何时结束\n }\n\n // 触发帧回调\n // if (this._onFrame) {\n // this._onFrame.forEach(cb => cb(targetStep, ratio));\n // }\n }\n\n updateDuration(): void {\n if (!this._lastStep) {\n this._duration = 0;\n return;\n }\n\n this._duration = this._lastStep.getStartTime() + this._lastStep.getDuration();\n this._totalDuration = this._duration * (this._loopCount + 1);\n }\n\n getTotalDuration(): number {\n return this._totalDuration;\n }\n\n getLoop(): number {\n return this._loopCount;\n }\n}\n"]}
@@ -3,7 +3,7 @@ import { Step } from "../step";
3
3
  export class ACustomAnimate extends Step {
4
4
  constructor(customFrom, customTo, duration, easing, params) {
5
5
  super("customAnimate", customTo, duration, easing), this.type = "customAnimate",
6
- this.customFrom = customFrom, this.params = params;
6
+ this.customFrom = customFrom, this.params = params, this.from = customFrom, this.to = customTo;
7
7
  }
8
8
  update(end, ratio, out) {
9
9
  if (this.onStart(), !this.props || !this.propKeys) return;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/custom/custom-animate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,OAAgB,cAAkB,SAAQ,IAAI;IAUlD,YAAY,UAAa,EAAE,QAAW,EAAE,QAAgB,EAAE,MAAkB,EAAE,MAAY;QACxF,KAAK,CAAC,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAVrD,SAAI,GAAqB,eAAe,CAAC;QAWvC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,GAAY,EAAE,KAAa,EAAE,GAAwB;QAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACjC,OAAO;SACR;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAES,QAAQ,CAAC,KAAQ;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAgB,iBAAqB,SAAQ,cAAiB;IAGlE,YAAY,CAAC,QAA2B;QACtC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;CACF","file":"custom-animate.js","sourcesContent":["import type { ComponentAnimator } from '../component';\nimport type { EasingType, IAnimateStepType, ICustomAnimate } from '@visactor/vrender-core';\nimport { Step } from '../step';\n\nexport abstract class ACustomAnimate<T> extends Step implements ICustomAnimate {\n type: IAnimateStepType = 'customAnimate';\n declare customFrom: T;\n declare params?: any;\n declare props?: T;\n declare from?: T;\n declare to?: T;\n\n // 为了兼容旧的api,from和to是可选的,且尽量不需要From,因为为了避免突变,From都应该从当前位置开始\n // 所以From并不会真正设置到fromProps中,而是作为customFrom参数\n constructor(customFrom: T, customTo: T, duration: number, easing: EasingType, params?: any) {\n super('customAnimate', customTo, duration, easing);\n this.customFrom = customFrom;\n this.params = params;\n }\n\n update(end: boolean, ratio: number, out: Record<string, any>): void {\n // TODO 需要修复,只有在开始的时候才调用\n this.onStart();\n if (!this.props || !this.propKeys) {\n return;\n }\n // 应用缓动函数\n const easedRatio = this.easing(ratio);\n this.onUpdate(end, easedRatio, out);\n this.syncAttributeUpdate();\n }\n\n protected setProps(props: T) {\n this.props = props;\n this.propKeys = Object.keys(props);\n this.animate.reSyncProps();\n }\n}\n\nexport abstract class AComponentAnimate<T> extends ACustomAnimate<T> {\n protected _animator: ComponentAnimator;\n\n completeBind(animator: ComponentAnimator): void {\n this.setStartTime(0);\n this._animator && this._animator.start();\n this.setDuration(animator.getDuration());\n }\n\n stop(): void {\n this._animator && this._animator.stop();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/custom/custom-animate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,OAAgB,cAAkB,SAAQ,IAAI;IAUlD,YAAY,UAAa,EAAE,QAAW,EAAE,QAAgB,EAAE,MAAkB,EAAE,MAAY;QACxF,KAAK,CAAC,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAVrD,SAAI,GAAqB,eAAe,CAAC;QAWvC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,GAAY,EAAE,KAAa,EAAE,GAAwB;QAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACjC,OAAO;SACR;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAES,QAAQ,CAAC,KAAQ;QACzB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAgB,iBAAqB,SAAQ,cAAiB;IAGlE,YAAY,CAAC,QAA2B;QACtC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;CACF","file":"custom-animate.js","sourcesContent":["import type { ComponentAnimator } from '../component';\nimport type { EasingType, IAnimateStepType, ICustomAnimate } from '@visactor/vrender-core';\nimport { Step } from '../step';\n\nexport abstract class ACustomAnimate<T> extends Step implements ICustomAnimate {\n type: IAnimateStepType = 'customAnimate';\n declare customFrom: T;\n declare params?: any;\n declare props?: T;\n declare from?: T;\n declare to?: T;\n\n // 为了兼容旧的api,from和to是可选的,且尽量不需要From,因为为了避免突变,From都应该从当前位置开始\n // 所以From并不会真正设置到fromProps中,而是作为customFrom参数\n constructor(customFrom: T, customTo: T, duration: number, easing: EasingType, params?: any) {\n super('customAnimate', customTo, duration, easing);\n this.customFrom = customFrom;\n this.params = params;\n this.from = customFrom;\n this.to = customTo;\n }\n\n update(end: boolean, ratio: number, out: Record<string, any>): void {\n // TODO 需要修复,只有在开始的时候才调用\n this.onStart();\n if (!this.props || !this.propKeys) {\n return;\n }\n // 应用缓动函数\n const easedRatio = this.easing(ratio);\n this.onUpdate(end, easedRatio, out);\n this.syncAttributeUpdate();\n }\n\n protected setProps(props: T) {\n this.props = props;\n this.propKeys = Object.keys(props);\n this.animate.reSyncProps();\n }\n}\n\nexport abstract class AComponentAnimate<T> extends ACustomAnimate<T> {\n protected _animator: ComponentAnimator;\n\n completeBind(animator: ComponentAnimator): void {\n this.setStartTime(0);\n this._animator && this._animator.start();\n this.setDuration(animator.getDuration());\n }\n\n stop(): void {\n this._animator && this._animator.stop();\n }\n}\n"]}
@@ -6,5 +6,6 @@ export declare class FromTo extends ACustomAnimate<Record<string, number>> {
6
6
  constructor(from: null, to: null, duration: number, easing: EasingType, params?: any);
7
7
  onBind(): void;
8
8
  onFirstRun(): void;
9
+ deleteSelfAttr(key: string): void;
9
10
  update(end: boolean, ratio: number, out: Record<string, any>): void;
10
11
  }
@@ -21,6 +21,9 @@ export class FromTo extends ACustomAnimate {
21
21
  this.from[key] = null !== (_a = this.from[key]) && void 0 !== _a ? _a : startProps[key];
22
22
  })), this.target.setAttributes(this.from);
23
23
  }
24
+ deleteSelfAttr(key) {
25
+ super.deleteSelfAttr(key), delete this.from[key];
26
+ }
24
27
  update(end, ratio, out) {
25
28
  if (this.onStart(), !this.props || !this.propKeys) return;
26
29
  const easedRatio = this.easing(ratio);