| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- <template>
- <view class="clock-container">
- <view class="clock-face" :style="{width:`${size}rpx`,height:`${size}rpx`}">
- <!-- 时钟刻度 -->
- <view v-for="(item, index) in 12" :key="index" class="hour-marker"
- :style="{ transform: `rotate(${index * 30}deg) translateY(-${size * 0.44}rpx)` }"></view>
- <!-- 时针 -->
- <view class="hour-hand" :style="[hourHandStyle, { transform: `rotate(${hourDegree}deg)` }]"></view>
- <!-- 分针 -->
- <view class="minute-hand" :style="[minuteHandStyle, { transform: `rotate(${minuteDegree}deg)` }]"></view>
- <!-- 秒针 -->
- <view class="second-hand" :style="[secondHandStyle, { transform: `rotate(${secondDegree}deg)` }]"
- v-if="showSecond"></view>
- <!-- 中心点 -->
- <view class="center-point" :style="centerPointStyle"></view>
- </view>
- </view>
- </template>
- <script>
- export default {
- name: 'DynamicClock',
- props: {
- showSecond: {
- type: Boolean,
- default: true
- },
- size: {
- type: Number,
- default: 300 // 默认时钟大小,单位rpx
- }
- },
- data() {
- return {
- hourDegree: 0,
- minuteDegree: 0,
- secondDegree: 0,
- timer: null
- }
- },
- computed: {
- hourHandStyle() {
- return {
- width: `${this.size * 0.02}rpx`,
- height: `${this.size * 0.2}rpx`,
- marginLeft: `${-this.size * 0.01}rpx`
- }
- },
- minuteHandStyle() {
- return {
- width: `${this.size * 0.013}rpx`,
- height: `${this.size * 0.3}rpx`,
- marginLeft: `${-this.size * 0.0065}rpx`
- }
- },
- secondHandStyle() {
- return {
- width: `${this.size * 0.007}rpx`,
- height: `${this.size * 0.33}rpx`,
- marginLeft: `${-this.size * 0.0035}rpx`
- }
- },
- centerPointStyle() {
- return {
- width: `${this.size * 0.06}rpx`,
- height: `${this.size * 0.06}rpx`
- }
- }
- },
- mounted() {
- this.updateClock()
- this.startClock()
- },
- beforeDestroy() {
- this.stopClock()
- },
- methods: {
- updateClock() {
- const now = new Date()
- const hours = now.getHours() % 12
- const minutes = now.getMinutes()
- const seconds = now.getSeconds()
- // 计算指针角度
- // 时针:每小时旋转30度,每分钟额外旋转0.5度
- this.hourDegree = (hours * 30) + (minutes * 0.5)
- // 分针:每分钟旋转6度
- this.minuteDegree = minutes * 6
- // 秒针:每秒旋转6度
- this.secondDegree = seconds * 6
- },
- startClock() {
- // 每秒更新一次时钟
- this.timer = setInterval(() => {
- this.updateClock()
- }, 1000)
- },
- stopClock() {
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- }
- }
- }
- </script>
- <style scoped>
- .clock-container {
- display: flex;
- justify-content: center;
- align-items: center;
- /* width: 100%; */
- }
- .clock-face {
- position: relative;
- border-radius: 50%;
- background-color: #ffffff;
- display: flex;
- justify-content: center;
- align-items: center;
- border: 6rpx solid #f5f5f5;
- }
- .hour-marker {
- position: absolute;
- width: 6rpx;
- height: 6rpx;
- border-radius: 50%;
- background-color: #aaa;
- top: 50%;
- left: 50%;
- transform-origin: center;
- }
- .hour-hand {
- position: absolute;
- background-color: #333;
- bottom: 50%;
- left: 50%;
- transform-origin: bottom center;
- border-radius: 6rpx;
- }
- .minute-hand {
- position: absolute;
- background-color: #333;
- bottom: 50%;
- left: 50%;
- transform-origin: bottom center;
- border-radius: 4rpx;
- }
- .second-hand {
- position: absolute;
- background-color: #666;
- bottom: 50%;
- left: 50%;
- transform-origin: bottom center;
- border-radius: 2rpx;
- }
- .center-point {
- position: absolute;
- background-color: #333;
- border-radius: 50%;
- z-index: 10;
- }
- </style>
|