62 lines
1.2 KiB
JavaScript
62 lines
1.2 KiB
JavaScript
import { computed, onMounted, onUnmounted, ref, unref, watch } from 'vue'
|
|
|
|
export default function useTimer(expirationTime) {
|
|
const now = ref(Date.now())
|
|
const remainingTime = ref(calcRemainingTime())
|
|
const requestId = ref()
|
|
|
|
const isPaused = computed(() => !requestId.value)
|
|
const isPassed = computed(() => remainingTime.value === 0)
|
|
|
|
function calcRemainingTime() {
|
|
return Math.max(Math.ceil((unref(expirationTime) - now.value) / 1000), 0)
|
|
}
|
|
|
|
function update() {
|
|
now.value = Date.now()
|
|
|
|
const newRemainingTime = calcRemainingTime()
|
|
|
|
if (newRemainingTime !== remainingTime.value)
|
|
remainingTime.value = newRemainingTime
|
|
|
|
if (remainingTime.value > 0)
|
|
requestId.value = window.requestAnimationFrame(update)
|
|
}
|
|
|
|
function start() {
|
|
requestId.value = requestAnimationFrame(update)
|
|
}
|
|
|
|
function stop() {
|
|
cancelAnimationFrame(requestId.value)
|
|
|
|
requestId.value = null
|
|
}
|
|
|
|
watch(expirationTime, () => {
|
|
if (!isPaused.value) {
|
|
remainingTime.value = calcRemainingTime()
|
|
|
|
stop()
|
|
start()
|
|
}
|
|
})
|
|
|
|
onMounted(() => {
|
|
start()
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
stop()
|
|
})
|
|
|
|
return {
|
|
remainingTime,
|
|
isPaused,
|
|
isPassed,
|
|
start,
|
|
stop,
|
|
}
|
|
}
|