first commit
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<script setup>
|
||||
import { computed, watch } from 'vue'
|
||||
import { useInterval } from '@vueuse/core'
|
||||
|
||||
const props = defineProps({
|
||||
active: { type: Boolean, default: false },
|
||||
seconds: { type: Number, default: 3 },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['finished'])
|
||||
|
||||
const { counter, pause, resume, reset } = useInterval(1000, {
|
||||
controls: true,
|
||||
immediate: false,
|
||||
})
|
||||
|
||||
const remaining = computed(() => Math.max(props.seconds - counter.value, 0))
|
||||
|
||||
watch(
|
||||
() => props.active,
|
||||
(value) => {
|
||||
if (value) {
|
||||
reset()
|
||||
resume()
|
||||
return
|
||||
}
|
||||
|
||||
pause()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
watch(remaining, (value) => {
|
||||
if (!props.active) return
|
||||
|
||||
if (value === 0) {
|
||||
pause()
|
||||
emit('finished')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="active" class="countdown">
|
||||
<span
|
||||
v-motion
|
||||
:initial="{ scale: 0.6, opacity: 0 }"
|
||||
:enter="{ scale: 1, opacity: 1, transition: { type: 'spring', stiffness: 300, damping: 16 } }"
|
||||
:key="remaining"
|
||||
class="countdown-number"
|
||||
>
|
||||
{{ remaining }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.countdown {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 32px;
|
||||
background: rgba(255, 230, 239, 0.65);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.countdown-number {
|
||||
font-size: clamp(2.5rem, 6vw, 4.5rem);
|
||||
font-weight: 700;
|
||||
color: #8e2c4a;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user