<!-- * 时钟 --> <script setup lang="ts"> import { ref, onMounted, onBeforeUnmount } from 'vue'; const hoursRef = ref<any>(null); const minutesRef = ref<any>(null); const secondsRef = ref<any>(null); const ampmRef = ref<any>(null); const hhRef = ref<any>(null); const mmRef = ref<any>(null); const ssRef = ref<any>(null); const hrDotRef = ref<any>(null); const minDotRef = ref<any>(null); const secDotRef = ref<any>(null); const hours = ref<any>(0); const minutes = ref<any>(0); const seconds = ref<any>(0); const ampm = ref(''); const timer = ref<any>(null); onMounted(() => { getTime(); }); onBeforeUnmount(() => { clearTimeout(timer.value); timer.value = null; }); function getTime() { let h = new Date().getHours() as any; let m = new Date().getMinutes() as any; let s = new Date().getSeconds() as any; let am = h >= 12 ? 'PM' : 'AM'; if (h > 12) { h = h - 12; } if (h < 10) { h = '0' + h; } if (m < 10) { m = '0' + m; } if (s < 10) { s = '0' + s; } hours.value = h; minutes.value = m; seconds.value = s; ampm.value = am; hhRef.value.style.strokeDashoffset = 440 - (440 * h) / 12; mmRef.value.style.strokeDashoffset = 440 - (440 * m) / 60; ssRef.value.style.strokeDashoffset = 440 - (440 * s) / 60; // 360/12 = 30 hrDotRef.value.style.transform = `rotate(${h * 30}deg)`; // 360/60 = 6 minDotRef.value.style.transform = `rotate(${m * 6}deg)`; // 360/60 = 6 secDotRef.value.style.transform = `rotate(${s * 6}deg)`; timer.value = setTimeout(() => { getTime(); }, 1000); } </script> <template> <div class="fit box"> <div ref="timeRef" id="time"> <div class="circle" style="--clr: #ff2971"> <div class="dots" ref="hrDotRef"></div> <svg> <circle cx="70" cy="70" r="70"></circle> <circle cx="70" cy="70" r="70" id="hh" ref="hhRef"></circle> </svg> <div id="hours" ref="hoursRef"> {{ hours }} <br /><span>Hours</span> </div> </div> <div class="circle" style="--clr: #fee800"> <div class="dots" ref="minDotRef"></div> <svg> <circle cx="70" cy="70" r="70"></circle> <circle cx="70" cy="70" r="70" id="mm" ref="mmRef"></circle> </svg> <div id="minutes" ref="minutesRef"> {{ minutes }} <br /><span>Minutes</span> </div> </div> <div class="circle" style="--clr: #04fc43"> <div class="dots" ref="secDotRef"></div> <svg> <circle cx="70" cy="70" r="70"></circle> <circle cx="70" cy="70" r="70" id="ss" ref="ssRef"></circle> </svg> <div id="seconds" ref="secondsRef"> {{ seconds }} <br /><span>Seconds</span> </div> </div> <div class="ap"> <div id="ampm" ref="ampmRef">{{ ampm }}</div> </div> </div> </div> </template> <style lang="scss" scoped> * { margin: 0; padding: 0; box-sizing: border-box; } .box { display: flex; justify-content: center; align-items: center; background-color: #2f363e; } #time { display: flex; gap: 40px; color: #fff; .circle { position: relative; width: 150px; height: 150px; display: flex; justify-content: center; align-items: center; svg { position: relative; width: 150px; height: 150px; transform: rotate(270deg); circle { width: 100%; height: 100%; fill: transparent; stroke: #191919; stroke-width: 4; transform: translate(5px, 5px); &:nth-child(2) { stroke: var(--clr); stroke-dasharray: 440; } } } .dots { position: absolute; width: 100%; height: 100%; z-index: 10; display: flex; justify-content: center; &::before { position: absolute; content: ''; top: -3px; width: 15px; height: 15px; background-color: var(--clr); border-radius: 50%; box-shadow: 0 0 20px var(--clr), 0 0 60px var(--clr); } } } div { position: absolute; text-align: center; font-weight: 500; font-size: 1.5em; span { position: absolute; font-size: 0.35em; font-weight: 300; letter-spacing: 0.1em; transform: translateX(-50%); text-transform: uppercase; } } .ap { position: relative; font-size: 1em; transform: translateX(-20px); } } </style>