vue3电子时钟组件

 上预览图:

上科技:

<template>
  <div class="timeBox">
    <div class="clockBox">
      <canvas ref="canvas" height="100" width="100"></canvas>
    </div>
    <div class="timeItem">
      <div class="time">{{ time.time }}</div>
      <div class="second">{{ time.second }}</div>
    </div>
    <div class="dateItem">
      <div class="week">{{ time.week }}</div>
      <div class="date">{{ time.date }}</div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, onBeforeUnmount } from 'vue';
  import dayjs from 'dayjs';
  const timer: any = ref(null);
  const time: any = ref({});
  const getDate = () => {
    time.value = parseTime(new Date());
    console.log(21, time.value);
  };
  // 根据传入的时间,处理成需要的对象函数
  const parseTime = (time) => {
    draw(time);
    let resObj: any = {};
    let week = ['日', '一', '二', '三', '四', '五', '六'];
    resObj.date = dayjs(time).format('YYYY年MM月DD日');
    resObj.week = `星期${week[dayjs(time).day()]}`;
    resObj.time = dayjs(time).format('HH:mm');
    resObj.second = dayjs(time).format('ss');
    return resObj;
  };
  const canvas = ref();
  //描绘时分秒小数和小数点
  // 绘制表盘
  const radius = 50;
  const cWidth = 100;
  const drawBackground = () => {
    ctx.value.save();
    // ctx.value.translate(radius, radius); //中心原点位置
    const width = cWidth;
    const height = cWidth;
    const R = width / 2; //圆半径
    const r = (R / 3) * 2;
    //设置坐标轴原点
    ctx.value.translate(width / 2, height / 2);
    // 圆心
    ctx.value.beginPath();
    // ctx.value.arc(0, 0, 10, 0, 2 * Math.PI, true);
    ctx.value.fill();
    ctx.value.closePath();
    // 表盘刻度(大格)
    ctx.value.beginPath();
    ctx.value.lineWidth = 2;
    for (var i = 0; i < 12; i++) {
      ctx.value.beginPath();
      ctx.value.strokeStyle = 'rgba(255,255,255,1)';
      ctx.value.rotate(Math.PI / 6);
      ctx.value.moveTo(R, 0);
      ctx.value.lineTo(r, 0);
      ctx.value.stroke();
    }
    ctx.value.closePath();
    // 表盘刻度(小格)
    ctx.value.beginPath();
    ctx.value.lineWidth = 1;
    for (var i = 0; i < 60; i++) {
      ctx.value.beginPath();
      ctx.value.strokeStyle = 'rgba(255,255,255,0.7)';
      ctx.value.rotate(Math.PI / 30);
      ctx.value.moveTo(R, 0);
      ctx.value.lineTo(R - 10, 0);
      ctx.value.stroke();
    }
    ctx.value.closePath();
  };

  //描绘时针
  const drawHour = (hour, minute) => {
    ctx.value.save();
    ctx.value.beginPath();
    ctx.value.strokeStyle = '#FFFFFF';
    let rad = ((2 * Math.PI) / 12) * hour;
    let mrad = ((2 * Math.PI) / 12 / 60) * minute;
    ctx.value.rotate(rad + mrad);
    ctx.value.lineWidth = 4;
    ctx.value.lineCap = 'round';
    ctx.value.moveTo(0, 10);
    ctx.value.lineTo(0, -radius + 30);
    ctx.value.stroke();
    ctx.value.restore();
  };
  //描绘分针
  const drawMinute = (minute) => {
    ctx.value.save();
    ctx.value.beginPath();
    let rad = ((2 * Math.PI) / 60) * minute;
    ctx.value.rotate(rad);
    ctx.value.strokeStyle = '#FFFFFF';
    ctx.value.lineWidth = 3;
    ctx.value.lineCap = 'round';
    ctx.value.moveTo(0, 10);
    ctx.value.lineTo(0, -radius + 20);
    ctx.value.stroke();
    ctx.value.restore();
  };
  //描绘秒针
  const drawSecond = (second) => {
    ctx.value.save();
    ctx.value.beginPath();
    ctx.value.fillStyle = '#C14543';
    ctx.value.lineWidth = 2;
    ctx.value.lineCap = 'round';
    let rad = ((2 * Math.PI) / 60) * second;
    ctx.value.rotate(rad);
    ctx.value.moveTo(-2, 20);
    ctx.value.lineTo(2, 20);
    ctx.value.lineTo(1, -radius + 10);
    ctx.value.lineTo(-1, -radius + 10);
    ctx.value.fill();
    ctx.value.restore();
  };
  //中间固定园点
  const drawDot = () => {
    ctx.value.beginPath();
    ctx.value.fillStyle = '#C14543';
    ctx.value.arc(0, 0, 4, 0, 2 * Math.PI, false);
    ctx.value.fill();
  };
  const draw = (now) => {
    ctx.value.clearRect(0, 0, cWidth, cWidth);
    let hour = now.getHours();
    let minute = now.getMinutes();
    let second = now.getSeconds();
    drawBackground();
    drawHour(hour, minute);
    drawMinute(minute);
    drawSecond(second);
    drawDot();
    ctx.value.restore();
  };

  const ctx = ref();
  onMounted(() => {
    ctx.value = canvas.value.getContext('2d');
    timer.value = setInterval(() => {
      getDate();
    }, 1000);
  });
  onBeforeUnmount(() => {
    clearInterval(timer.value);
    timer.value = null;
  });
</script>
<style lang="less" scoped>
  .timeBox {
    width: 60%;
    border-radius: 30px;
    margin: 0 auto;
    background: linear-gradient(to right bottom, #7cafe3, #046ac1);
    display: flex;
    padding: 20px 0;
    justify-content: center;
    cursor: default;
    .clockBox {
      width: 160px;
    }
    .timeItem {
      display: flex;
      color: white;
      width: 220px;
      .time {
        font: 60px/100px 'pf';
      }
      .second {
        font: 30px/30px 'pf';
        margin: 45px 0 0 20px;
      }
    }
    .dateItem {
      width: 200px;
      color: white;
      padding-top: 25px;
      padding-left: 40px;
      .week {
        font: 22px/22px 'pf';
      }
      .date {
        margin-top: 10px;
        font: 18px/18px 'pf';
      }
    }
  }
</style>

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tx10765

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值