美文网首页让前端飞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