| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <template>
- <view class="clock-box">
- <view class="clock" :style="{ '--ds': ds, '--dm': dm, '--dh': dh }">
- <view class="clock-pane">
- <text class="clock-num" :style="{ '--i': n }" v-for="n in 12" :key="n">{{ n }}</text>
- </view>
- <view class="clock-hour"></view>
- <view class="clock-min"></view>
- <view class="clock-sec"></view>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- const d = new Date()
- const h = d.getHours()
- const m = d.getMinutes()
- const s = d.getSeconds()
- const ds = ref(s)
- const dm = ref(m + s / 60)
- const dh = ref(h + m / 60 + s / 3600)
- </script>
- <style lang="scss">
- .clock {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 380px;
- height: 380px;
- font-size: 24px;
- border-radius: 20px;
- box-shadow: 2px 2px 20px #0000001a;
- --step: 60s;
- }
- .clock::before {
- position: absolute;
- width: 300px;
- height: 300px;
- content: '';
- background: repeating-conic-gradient(from -0.5deg, #333 0 1deg, transparent 0deg 30deg),
- repeating-conic-gradient(from -0.5deg, #ccc 0 1deg, transparent 0deg 6deg);
- border-radius: 50%;
- mask: radial-gradient(transparent 145px, red 0);
- }
- .clock-pane {
- position: absolute;
- width: 250px;
- height: 250px;
- }
- .clock-num {
- position: absolute;
- offset-path: path(
- 'M250 125c0 69.036-55.964 125-125 125S0 194.036 0 125 55.964 0 125 0s125 55.964 125 125z'
- );
- offset-distance: calc(var(--i) * 10% / 1.2 - 25%);
- offset-rotate: 0deg;
- }
- .clock-hour {
- position: absolute;
- width: 4px;
- height: 60px;
- background: #333;
- transform: translateY(-50%) rotate(0);
- transform-origin: center bottom;
- animation: clock calc(var(--step) * 60 * 12) infinite linear;
- animation-delay: calc(-1 * var(--step) * var(--dh) * 60);
- }
- .clock-min {
- position: absolute;
- width: 4px;
- height: 90px;
- background: #333;
- transform: translateY(-50%) rotate(0);
- transform-origin: center bottom;
- animation: clock calc(var(--step) * 60) infinite linear;
- animation-delay: calc(-1 * var(--step) * var(--dm));
- }
- .clock-sec {
- position: absolute;
- width: 2px;
- height: 120px;
- background: red;
- transform: translateY(-50%) rotate(0);
- transform-origin: center bottom;
- animation: clock var(--step) infinite steps(60);
- animation-delay: calc(-1 * var(--step) * var(--ds) / 60);
- }
- .clock-sec::after {
- position: absolute;
- bottom: 0;
- left: 50%;
- width: 10px;
- height: 10px;
- content: '';
- background: #fff;
- border: 4px solid #333;
- border-radius: 50%;
- transform: translate(-50%, 50%);
- }
- @keyframes clock {
- to {
- transform: translateY(-50%) rotate(360deg);
- }
- }
- a {
- width: 8px;
- height: 9px;
- }
- </style>
|