美文网首页让前端飞Web前端之路
用JS Canvas画一个腕表⌚️送给自己

用JS Canvas画一个腕表⌚️送给自己

作者: IM唐钰小宝 | 来源:发表于2020-11-04 17:52 被阅读0次

    没钱买表 某前端程序员竟然 用代码画了个表😄

    clock.jpeg

    在线Demo https://codepen.io/DiscoverForever/pen/dyXKaqb

    HTML代码

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>test</title>
      <style>
        html,
        body {
          height: 100%;
          width: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
    
        #canvas {
          width: 200px;
          height: 200px;
        }
      </style>
      <script src="./index.js"></script>
    </head>
    
    <body>
      <canvas id="canvas" width="200" height="200"></canvas>
    </body>
    
    </html>
    

    Javascript代码

    function init() {
      const canvas = document.getElementById('canvas')
      const width = canvas.width
      const height = canvas.height
      canvas.style.width = width + 'px'
      canvas.style.height = height + 'px'
      canvas.height = height * devicePixelRatio
      canvas.width = width * devicePixelRatio
      let ctx = null
      if (canvas.getContext) {
        ctx = canvas.getContext('2d')
      } else {
        alert('该浏览器暂不支持Canvas')
        return
      }
      setInterval(() => {
        // 清空画布
        canvas.height = height * devicePixelRatio
        canvas.width = width * devicePixelRatio
        run(ctx)
      }, 1000)
    }
    
    function run(ctx) {
    
      const date = new Date()
      renderCircle(ctx, 100, 100, 99, 'grey')
      renderCircle(ctx, 100, 100, 94, 'black')
      renderHourHand(ctx, getHourHandAngle(date.getHours()))
      renderMinuteHand(ctx, getMinuteHandAngle(date.getMinutes()))
      renderSecondHand(ctx, getSecondHandAngle(date.getSeconds()))
      artCenterCircle(ctx)
      renderScaleLabel(ctx)
      renderHourScale(ctx)
      renderMinuteScale(ctx)
    
    }
    
    /**
     * 获取时针偏转角度
     * @param {*} second
     * @returns
     */
    function getHourHandAngle(hour) {
      let currentHour = null
      if (hour <= 12) {
        currentHour = hour
      } else {
        currentHour = hour - 12
      }
      return currentHour * 30 * (Math.PI / 180)
    }
    
    /**
     * 获取分针偏转角度
     * @param {*} second
     * @returns
     */
    function getMinuteHandAngle(minute) {
      return minute * 6 * (Math.PI / 180)
    }
    
    /**
     * 获取秒针偏转角度
     * @param {*} second
     * @returns
     */
    function getSecondHandAngle(second) {
      return second * 6 * (Math.PI / 180)
    }
    
    /**
     * 画圆
     */
    function renderCircle(ctx, x, y, radius, color, lineWidth = 1) {
      ctx.beginPath()
      ctx.strokeStyle = color
      ctx.lineWidth = lineWidth
      ctx.arc(x * devicePixelRatio, y * devicePixelRatio, radius * devicePixelRatio, 0, 2 * Math.PI, false)
      ctx.stroke()
      ctx.closePath()
    }
    
    /**
     * 画时针
     * @param {*} ctx 
     * @param {*} angle 
     */
    function renderHourHand(ctx, angle) {
      ctx.beginPath()
      ctx.save()
      ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
      ctx.rotate(angle)
      ctx.strokeStyle = 'black'
      ctx.lineWidth = 10
      ctx.moveTo(0, 0)
      ctx.lineTo(0, -40 * devicePixelRatio)
      ctx.stroke()
      ctx.restore()
      ctx.closePath()
    }
    
    /**
     * 画分针
     * @param {*} ctx
     * @param {*} angle
     */
    function renderMinuteHand(ctx, angle) {
      ctx.beginPath()
      ctx.save()
      ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
      ctx.rotate(angle)
      ctx.strokeStyle = 'black'
      ctx.lineWidth = 6
      ctx.moveTo(0, 0)
      ctx.lineTo(0, -60 * devicePixelRatio)
      ctx.stroke()
      ctx.restore()
      ctx.closePath()
    }
    
    
    /**
     * 画秒针
     * @param {*} ctx
     * @param {*} angle
     */
    function renderSecondHand(ctx, angle) {
      ctx.beginPath()
      ctx.save()
      ctx.translate(100 * devicePixelRatio, 100 * devicePixelRatio)
      ctx.rotate(angle)
      ctx.strokeStyle = 'black'
      ctx.lineWidth = 2
      ctx.moveTo(0, 0)
      ctx.lineTo(0, -90 * devicePixelRatio)
      ctx.stroke()
      ctx.restore()
      ctx.closePath()
    
    }
    
    /**
     * 表心
     * @param {*} ctx 
     */
    function artCenterCircle(ctx) {
      ctx.beginPath()
      ctx.lineWidth = 1
      ctx.fillStyle = 'black'
      ctx.arc(100 * devicePixelRatio, 100 * devicePixelRatio, 4 * devicePixelRatio, 0, 2 * Math.PI, false)
      ctx.fill()
    }
    
    /**
     * 画表盘刻度
     * @param {*} ctx 
     */
    function renderScale(ctx) {
      const lables = genClockScale(100, 100, 94)
      ctx.beginPath()
      lables.forEach(label => {
        ctx.moveTo(label.x, label.y)
        ctx.lineTo(100 * devicePixelRatio, 100 * devicePixelRatio)
      })
      ctx.stroke()
    }
    
    /**
     * 画小时刻度
     */
    function renderHourScale(ctx) {
      for (var i = 0; i < 12; i++) {
        ctx.beginPath()
        ctx.save()
        ctx.translate(102 * devicePixelRatio, 98 * devicePixelRatio)
        ctx.lineWidth = 2
        ctx.strokeStyle = 'black'
        ctx.rotate(i * 30 * Math.PI / 180)
        ctx.moveTo(0, -94 * devicePixelRatio)
        ctx.lineTo(0, -89 * devicePixelRatio)
        ctx.stroke()
        ctx.restore()
        ctx.closePath()
      }
    }
    
    /**
     * 画分刻度
     */
    function renderMinuteScale(ctx) {
      for (var i = 0; i < 60; i++) {
        ctx.beginPath()
        ctx.save()
        ctx.translate(102 * devicePixelRatio, 98 * devicePixelRatio)
        ctx.lineWidth = 1
        ctx.strokeStyle = 'black'
        ctx.rotate(i * 6 * Math.PI / 180)
        ctx.moveTo(0, -94 * devicePixelRatio)
        ctx.lineTo(0, -92 * devicePixelRatio)
        ctx.stroke()
        ctx.restore()
        ctx.closePath()
      }
    }
    
    /**
     * 画表盘数字
     */
    function renderScaleLabel(ctx) {
      const lables = genClockScale(100, 100, 82)
      ctx.beginPath()
      ctx.font = `${10 * devicePixelRatio}px Pingfang`
      ctx.translate(-2 * devicePixelRatio, 2 * devicePixelRatio)
      lables.forEach(label => ctx.fillText(label.text, label.x, label.y))
      ctx.translate(0, 0)
      ctx.closePath()
    }
    /**
     * 获取刻度坐标
     * @param {*} x 圆心x
     * @param {*} y 圆心y
     * @param {*} radius 半径
     * @returns
     */
    function genClockScale(ccX, ccY, radius, offset = 0) {
      const lables = [9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8]
      return lables.map((label, index) => {
        const angle = Math.PI * 2 / 12 * index
        let x = ccX - radius * Math.cos(angle) + offset
        let y = ccY - radius * Math.sin(angle) + offset
        return {
          angle,
          text: label,
          x: x * devicePixelRatio,
          y: y * devicePixelRatio,
        }
      })
    }
    
    window.onload = init
    

    相关文章

      网友评论

        本文标题:用JS Canvas画一个腕表⌚️送给自己

        本文链接:https://www.haomeiwen.com/subject/ncngvktx.html