数据可视化Canvas

邂逅Canvas

Canvas优缺点

初体验Canvas



Canvas Grid 和 坐标空间

绘制矩形(Rectangle


认识路径

路径-绘制直线

路径-绘制三角形(Triangle )

路径-绘制圆弧(Arc)、圆(Circle)

路径-矩形(Rectangle)

色彩Colors

透明度Transparent

线型Line styles


绘制文本

绘制图片

Canvas绘画状态-保存和恢复

变形Transform

移动-translate

旋转-rotate

缩放-scale

Canvas动画

绘制秒针-setInterval方法


绘制秒针-requestAnimationFrame


太阳系旋转


时钟案例

  <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
     body{
      margin: 0;
      padding: 0;
      background-image: url(./images/grid.png);
    }
    .click{
      width: 300px;
      height: 300px;
      background-color: black;
      margin: 20px;
      border-radius: 50px;
    }
  </style>
</head>
<body>
  <div class="click">
    <canvas id="main" width="300px" height="300px">
      您的浏览器不兼容Canvas,请升级或更换浏览器!
    </canvas>
  </div>
  <script>
    window.onload=function(){
      const canvasEl = document.getElementById("main")
      if(!canvasEl.getContext){
        return
      }
    const ctx = canvasEl.getContext("2d")
    requestAnimationFrame(draw)

    function draw(){
      ctx.clearRect(0,0,300,300)
      ctx.save()

      // 绘制一个白色的园
      ctx.save()
      ctx.translate(150,150)
      ctx.fillStyle="white"
      ctx.beginPath()
      ctx.arc(0,0,130,0,Math.PI*2)
      ctx.closePath()
      ctx.fill()
      ctx.restore()

      //绘制数字
      ctx.save()
      ctx.translate(150,150)
      // 开始画数字3
      ctx.font = "30px fangsong"
      ctx.textBaseline = "middle"
      ctx.textAlign = "center"
      const numbers = [3,4,5,6,7,8,9,10,11,12,1,2]
      for(let i= 0;i<numbers.length;i++){
        ctx.fillText(numbers[i],Math.cos(  Math.PI * 2 / 12  * i  )  * 100,  Math.sin(  Math.PI * 2 / 12  * i  )  * 100)
      }
      ctx.restore()
      let hour = new Date().getHours()
      let minute = new Date().getMinutes()
      let second = new Date().getSeconds()
      // 绘制时针
      ctx.save()
      ctx.translate(150,150)//原点在圆的中心
      ctx.rotate(Math.PI*2/12 * hour + Math.PI*2/12/60 * minute + Math.PI*2/12/60/60*second)
      ctx.lineWidth = 5
      ctx.lineCap="round"
      ctx.beginPath()
      ctx.moveTo(0,0)
      ctx.lineTo(0,-50)
      ctx.stroke()
      ctx.restore()

      // 绘制分针
      ctx.save()
      ctx.translate(150,150)
      ctx.rotate(Math.PI*2/60 *minute + Math.PI*2/60/60*second)
      ctx.lineWidth = 3
      ctx.lineCap="round"
      ctx.beginPath()
      ctx.moveTo(0,0)
      ctx.lineTo(0,-70)
      ctx.stroke()
      ctx.restore()

      // 绘制秒针
      ctx.save()
      ctx.translate(150,150)
      ctx.rotate( Math.PI*2/60*second)
      ctx.strokeStyle ="red"
      ctx.lineCap="round"
      ctx.beginPath()
      ctx.moveTo(0,0)
      ctx.lineTo(0,-100)
      ctx.stroke()
      ctx.restore()

      // 绘制圆心
      ctx.save()
      ctx.translate(150,150)
      ctx.beginPath()
      ctx.arc(0,0,8,0,Math.PI*2)
      ctx.fill()
      // 圆心的小圆
      ctx.fillStyle="gray"
      ctx.beginPath()
      ctx.arc(0,0,5,0,Math.PI*2)
      ctx.fill()
      ctx.restore()

      // 圆心刻度时针刻度
      ctx.save()
      ctx.translate(150,150)
      ctx.lineWidth = 5
      for(let i= 0 ;i<12;i++){
        ctx.rotate(Math.PI*2 /12)
        ctx.beginPath()
        ctx.moveTo(0,-130)
        ctx.lineTo(0,-120)
        ctx.stroke()
      }
      ctx.restore()

      // 圆心刻度时针刻度分针刻度
      ctx.save()
      ctx.translate(150,150)
      ctx.lineWidth = 2
      for(let i= 0 ;i<60;i++){
        ctx.rotate(Math.PI*2/60)
        ctx.beginPath()
        ctx.moveTo(0,-130)
        ctx.lineTo(0,-126)
        ctx.stroke()
      }
      ctx.restore()

      ctx.restore()
      requestAnimationFrame(draw)
    }
  }
  </script>
</body>
</html>
posted @ 2024-11-14 15:56  韩德才  阅读(4)  评论(0编辑  收藏  举报