Skip to content
This repository was archived by the owner on Jun 21, 2025. It is now read-only.

Commit c7836ac

Browse files
author
=
committed
fix|feat: seeking failed and timeline for new API
1 parent 8cdde30 commit c7836ac

File tree

6 files changed

+205
-114
lines changed

6 files changed

+205
-114
lines changed

packages/core/src/animation.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import type { WatchSource } from "vue";
2-
import { getCurrentInstance, watch } from "vue";
1+
import type { Ref, WatchSource } from "vue";
2+
import { getCurrentInstance, ref, watch } from "vue";
33
import { usePlayer } from "./player";
4+
import { Widget } from "./widget";
45

56
export type TimingFunction = (x: number) => number;
67
export const linear: TimingFunction = (x) => x;
@@ -136,7 +137,7 @@ export class AnimationManager<T> {
136137

137138
exec(fn: () => void) {
138139
this.animate(
139-
defineAnimation((_, __) => (progress) => {
140+
defineAnimation(() => (progress) => {
140141
if (progress === 0) fn();
141142
}),
142143
{ duration: 0 },
@@ -161,18 +162,27 @@ export function defineAnimation<T, A = object>(setup: AnimationSetup<T, A>) {
161162
export function registerAnimation<T>(
162163
name: string,
163164
setup: (...args: any[]) => (animate: AnimationManager<T>) => void,
164-
relativeElapsed?: WatchSource<number>,
165+
widgetInstance?: Widget,
165166
): void {
166167
const current = getCurrentInstance();
167168
const { widget } = current?.props as {
168169
widget: T & { manager?: AnimationManager<T> };
169170
};
170171
if (widget) {
171172
if (typeof widget.manager === "undefined") {
172-
widget.manager = new AnimationManager<T>(
173-
widget,
174-
relativeElapsed ?? usePlayer().elapsed,
175-
);
173+
const elapsed: Ref<number> = ref(0);
174+
if (widgetInstance && widgetInstance.elapsed) {
175+
elapsed.value = widgetInstance.elapsed!;
176+
watch(widgetInstance, (v) => {
177+
elapsed.value = v.elapsed!;
178+
});
179+
} else {
180+
watch(usePlayer().elapsed, (v) => {
181+
elapsed.value = v;
182+
console.log(v);
183+
});
184+
}
185+
widget.manager = new AnimationManager<T>(widget, elapsed);
176186
}
177187
(widget as Record<string, any>)[name] = (
178188
...args: Parameters<typeof setup>

packages/core/src/player.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { App, Ref } from "vue";
22
import { inject, ref, watch } from "vue";
33
import { AnimationManager } from "./animation";
4+
// import { GLOBAL_PLAYER } from "./symbols";
45

56
const studioListenerAdded = { value: false };
67

@@ -20,11 +21,11 @@ export function createPlayer(options: {
2021
}
2122

2223
export function usePlayer() {
23-
const startAt = performance.now() / 1000;
2424
const elapsed = inject("elapsed") as Ref<number>;
2525
const studio = inject("studio") as boolean;
2626
const fps = inject("fps") as number;
2727
const playing = ref(false);
28+
const renderEvents: ((elapsed: number) => void)[] = [];
2829

2930
if (studio && !studioListenerAdded.value) {
3031
studioListenerAdded.value = true;
@@ -35,26 +36,31 @@ export function usePlayer() {
3536
});
3637
}
3738

38-
function play() {
39+
function play(to?: number) {
40+
if (to) elapsed.value = to;
3941
if (studio)
4042
return console.log(
4143
"You are in the studio mode, you are not supposed to call this function!",
4244
);
45+
renderEvents.forEach((fn) => fn(elapsed.value));
4346
playing.value = true;
44-
elapsed.value = performance.now() / 1000 - startAt;
45-
if (playing.value) requestAnimationFrame(play);
47+
// console.log(1 / fps)
48+
elapsed.value += 1 / fps;
49+
// console.log(elapsed.value)
50+
if (playing.value) requestAnimationFrame(() => play());
4651
}
4752

4853
function useAnimation<T extends object>(widget: T) {
4954
return new AnimationManager(widget, elapsed);
5055
}
5156

52-
function setElapsed(value: number) {
57+
function seek(value: number) {
5358
elapsed.value = value;
5459
}
5560

56-
function pause() {
61+
function pause(to?: number) {
5762
playing.value = false;
63+
if (to) elapsed.value = to;
5864
}
5965

6066
function renderOnce(ela: number) {
@@ -63,17 +69,21 @@ export function usePlayer() {
6369
}, 1000);
6470
}
6571

72+
function whenRender(fn: (elapsed: number) => void) {
73+
renderEvents.push(fn);
74+
}
75+
6676
function useTimeline(start: number = 0) {
6777
const relativeElapsed = ref<number>(0);
6878
const isPlaying = ref(false);
6979
const localStart = ref(start);
7080

71-
// 监听全局时间
7281
watch(
7382
elapsed,
7483
() => {
7584
if (isPlaying.value) {
7685
relativeElapsed.value = Math.max(0, elapsed.value - localStart.value);
86+
// console.log(relativeElapsed.value)
7787
}
7888
},
7989
{ immediate: true },
@@ -116,10 +126,12 @@ export function usePlayer() {
116126
elapsed,
117127
useAnimation,
118128
useTimeline,
119-
setElapsed,
129+
seek,
120130
pause,
121131
renderOnce,
132+
whenRender,
122133
};
123134
}
124135

125136
export type Player = ReturnType<typeof usePlayer>;
137+
export type Timeline = ReturnType<Player["useTimeline"]>;

packages/core/src/symbols.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const GLOBAL_PLAYER = Symbol("GLOBAL_PLAYER");

packages/core/src/widget.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import {
66
reactive,
77
ref,
88
useSlots,
9+
watch,
910
} from "vue";
1011
import type { AnimationManager } from "./animation";
12+
import { Timeline } from "./player";
1113

1214
const childWidgets: InjectionKey<Ref<Widget[]>> = Symbol("child-widgets");
1315

@@ -18,11 +20,16 @@ export interface Widget<T = any> {
1820
slots?: Slots;
1921
children?: Widget<T>[];
2022
manager?: AnimationManager<T>;
21-
wid?: string;
23+
elapsed?: number;
2224
}
2325

24-
export function useWidget<T extends Widget>(): Reactive<T> {
26+
export function useWidget<T extends Widget>(timeline?: Timeline): Reactive<T> {
2527
const widget = reactive({});
28+
if (timeline) {
29+
watch(timeline.elapsed, (v) => {
30+
(widget as T).elapsed = v;
31+
});
32+
}
2633
return widget as Reactive<T>;
2734
}
2835

0 commit comments

Comments
 (0)