feat: 在播放控制器中添加动画帧定时器逻辑,优化播放时间更新和自动暂停功能
This commit is contained in:
parent
caadef3a92
commit
58e0726a7f
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue';
|
import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue';
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch, onUnmounted } from 'vue';
|
||||||
|
|
||||||
import { useTimelineTicks } from '../hooks/useTimelineTicks';
|
import { useTimelineTicks } from '../hooks/useTimelineTicks';
|
||||||
|
|
||||||
@ -35,14 +35,66 @@ const { ticks } = useTimelineTicks(viewStartTime, viewEndTime);
|
|||||||
watch(
|
watch(
|
||||||
() => props.currentTime,
|
() => props.currentTime,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
internalCurrentTime.value = newValue;
|
// Only update from prop if not playing
|
||||||
|
if (!props.isPlaying) {
|
||||||
|
internalCurrentTime.value = newValue;
|
||||||
|
}
|
||||||
const newHour = Math.floor(newValue / HOUR_IN_MS);
|
const newHour = Math.floor(newValue / HOUR_IN_MS);
|
||||||
if (newHour !== selectedHour.value) {
|
if (newHour !== selectedHour.value) {
|
||||||
selectedHour.value = newHour;
|
selectedHour.value = newHour;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// --- Animation Frame Timer for Playback ---
|
||||||
|
let animationFrameId: number | null = null;
|
||||||
|
let lastTimestamp: number | null = null;
|
||||||
|
|
||||||
|
const animationLoop = (timestamp: number) => {
|
||||||
|
if (!lastTimestamp) {
|
||||||
|
lastTimestamp = timestamp;
|
||||||
|
}
|
||||||
|
const deltaTime = timestamp - lastTimestamp;
|
||||||
|
lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
// Ensure we don't jump too far ahead if the tab was inactive
|
||||||
|
const clampedDelta = Math.min(deltaTime, 1000); // Max 1-second jump
|
||||||
|
|
||||||
|
const newTime = internalCurrentTime.value + clampedDelta;
|
||||||
|
|
||||||
|
if (newTime < props.totalDuration) {
|
||||||
|
internalCurrentTime.value = newTime;
|
||||||
|
// No need to emit timeupdate as per user decision
|
||||||
|
// emit('timeupdate', newTime);
|
||||||
|
animationFrameId = requestAnimationFrame(animationLoop);
|
||||||
|
} else {
|
||||||
|
internalCurrentTime.value = props.totalDuration;
|
||||||
|
emit('pause'); // Auto-pause at the end
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.isPlaying,
|
||||||
|
(isPlaying) => {
|
||||||
|
if (isPlaying) {
|
||||||
|
lastTimestamp = null; // Reset timestamp on play
|
||||||
|
animationFrameId = requestAnimationFrame(animationLoop);
|
||||||
|
} else {
|
||||||
|
if (animationFrameId) {
|
||||||
|
cancelAnimationFrame(animationFrameId);
|
||||||
|
animationFrameId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (animationFrameId) {
|
||||||
|
cancelAnimationFrame(animationFrameId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// --- Computed properties for display and binding ---
|
// --- Computed properties for display and binding ---
|
||||||
const formatTime = (ms: number): string => {
|
const formatTime = (ms: number): string => {
|
||||||
if (isNaN(ms) || ms < 0) return '00:00:00';
|
if (isNaN(ms) || ms < 0) return '00:00:00';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user