feat: 在播放控制器中添加动画帧定时器逻辑,优化播放时间更新和自动暂停功能
This commit is contained in:
parent
caadef3a92
commit
58e0726a7f
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
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';
|
||||
|
||||
@ -35,14 +35,66 @@ const { ticks } = useTimelineTicks(viewStartTime, viewEndTime);
|
||||
watch(
|
||||
() => props.currentTime,
|
||||
(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);
|
||||
if (newHour !== selectedHour.value) {
|
||||
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 ---
|
||||
const formatTime = (ms: number): string => {
|
||||
if (isNaN(ms) || ms < 0) return '00:00:00';
|
||||
|
Loading…
x
Reference in New Issue
Block a user