广丰卷烟厂数采质量分析系统
zhuguifei
2026-03-04 64c2870483568cdeb0206661249a19c5b06de8fe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { computed, onScopeDispose, ref } from 'vue';
import { useRafFn } from '@vueuse/core';
 
/**
 * A hook for implementing a countdown timer. It uses `requestAnimationFrame` for smooth and accurate timing,
 * independent of the screen refresh rate.
 *
 * @param initialSeconds - The total number of seconds for the countdown.
 */
export default function useCountDown(initialSeconds: number) {
  const remainingSeconds = ref(0);
 
  const count = computed(() => Math.ceil(remainingSeconds.value));
 
  const isCounting = computed(() => remainingSeconds.value > 0);
 
  const { pause, resume } = useRafFn(
    ({ delta }) => {
      // delta: milliseconds elapsed since the last frame.
 
      // If countdown already reached zero or below, ensure it's 0 and stop.
      if (remainingSeconds.value <= 0) {
        remainingSeconds.value = 0;
        pause();
        return;
      }
 
      // Calculate seconds passed since the last frame.
      const secondsPassed = delta / 1000;
      remainingSeconds.value -= secondsPassed;
 
      // If countdown has finished after decrementing.
      if (remainingSeconds.value <= 0) {
        remainingSeconds.value = 0;
        pause();
      }
    },
    { immediate: false } // The timer does not start automatically.
  );
 
  /**
   * Starts the countdown.
   *
   * @param [updatedSeconds=initialSeconds] - Optionally, start with a new duration. Default is `initialSeconds`
   */
  function start(updatedSeconds: number = initialSeconds) {
    remainingSeconds.value = updatedSeconds;
    resume();
  }
 
  /** Stops the countdown and resets the remaining time to 0. */
  function stop() {
    remainingSeconds.value = 0;
    pause();
  }
 
  // Ensure the rAF loop is cleaned up when the component is unmounted.
  onScopeDispose(() => {
    pause();
  });
 
  return {
    count,
    isCounting,
    start,
    stop
  };
}