001-CANVAS

1、CANVAS 概念

<canvas> 是 HTML5 新增的,一个可以使用 js 在其中绘制图像的 HTML 元素。它可以用来制作动画。Canvas是画布,通过Javascript来绘制2D图形,是逐像素进行渲染的。

2、基础案例

💡 Tips:实现 矩形、线段、三角形、圆弧、贝塞尔曲线、文本 等基础图形

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .canvas {
      border: 1px solid #ccc;
    }
  </style>
  <body>
    <!-- 矩形 -->
    <canvas id="demo1" width="300" height="300" class="canvas"></canvas>
    <!-- 线 -->
    <canvas id="demo2" width="300" height="300" class="canvas"></canvas>
    <!-- 三角形 -->
    <canvas id="demo3" width="300" height="300" class="canvas"></canvas>
    <!-- 圆弧 -->
    <canvas id="demo4" width="300" height="300" class="canvas"></canvas>
    <!-- 二次贝塞尔曲线 -->
    <canvas id="demo5" width="300" height="300" class="canvas"></canvas>
    <!-- 文本 -->
    <canvas id="demo6" width="300" height="300" class="canvas"></canvas>
    <!-- 裁剪 -->
    <canvas id="demo7" width="300" height="300" class="canvas"></canvas>
  </body>
  <script>
    const utils = {
      initDraw(id) {
        const ctx = document.getElementById(id).getContext('2d');
        ctx.fillStyle = 'rgb(200, 0, 0)'; // 填充颜色
        ctx.strokeStyle = 'rgb(200, 0, 0)'; // 描边颜色
        return ctx;
      },
    };

    const drawCanvas = {
      draw1() {
        const ctx = utils.initDraw('demo1');
        // 画矩形 x, y, widh, height
        ctx.fillRect(10, 10, 100, 50); // 填充
        ctx.strokeRect(10, 70, 100, 50); // 描边
        ctx.clearRect(15, 15, 50, 25); // 透明
      },
      draw2() {
        const ctx = utils.initDraw('demo2');
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(200, 50);
        ctx.lineWidth = 5;
        ctx.lineCap = 'round'; // butt方形-默认值、square方形-外延
        ctx.stroke();

        // 虚线
        ctx.moveTo(50, 100);
        ctx.lineTo(200, 100);
        ctx.lineWidth = 1;
        ctx.setLineDash([10, 10]); // [实线长度, 间隙长度]
        ctx.lineDashOffset = 0;
        ctx.stroke();

        ctx.closePath();
      },
      draw3() {
        const ctx = utils.initDraw('demo3');
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(200, 50);
        ctx.lineTo(200, 200);
        // ctx.closePath(); // 虽然我们只绘制了两条线段,但是closePath会closePath,仍然是一个3角形
        // ctx.stroke(); // 描边。stroke不会自动closePath()

        ctx.fill(); //填充闭合区域。如果path没有闭合,则fill()会自动闭合路径。
      },
      draw4() {
        const ctx = utils.initDraw('demo4');
        // arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。
        ctx.beginPath();
        ctx.arc(50, 50, 40, 0, (Math.PI / 180) * 270, false);
        // ctx.closePath();
        ctx.stroke();
      },
      draw5() {
        const ctx = utils.initDraw('demo5');
        const sx = 10,
          sy = 200; // 起始点
        const cp1x = 40,
          cp1y = 100; // 控制点
        const x = 200,
          y = 200; // 结束点

        ctx.beginPath();
        ctx.moveTo(sx, sy);
        // 绘制二次贝塞尔曲线 quadraticCurveTo(cp1x, cp1y, x, y) 参数 1 和 2:控制点坐标 参数 3 和 4:结束点坐标
        ctx.quadraticCurveTo(cp1x, cp1y, x, y);
        ctx.stroke();

        ctx.beginPath();
        ctx.rect(sx, sy, 10, 10);
        ctx.rect(cp1x, cp1y, 10, 10);
        ctx.rect(x, y, 10, 10);
        ctx.fill();
      },
      draw6() {
        const ctx = utils.initDraw('demo6');
        ctx.font = '40px sans-serif'; // 字符串使用和 CSS font 属性相同的语法
        ctx.fillText('天若有情', 10, 100);
        ctx.strokeText('天若有情', 10, 200);
      },
      draw7() {
        const ctx = utils.initDraw('demo7');
        ctx.beginPath();
        ctx.arc(20, 20, 100, 0, Math.PI * 2);
        ctx.clip();

        ctx.fillStyle = 'pink';
        ctx.fillRect(20, 20, 50, 100);
      },
    };

    for (let key in drawCanvas) {
      drawCanvas[key]();
    }
  </script>
</html>

效果图如下:
在这里插入图片描述

3、CANVAS 实现时钟

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .canvas {
      border: 1px solid #ccc;
    }
  </style>
  <body>
    <!-- 时钟 -->
    <canvas id="demo" width="300" height="300" class="canvas"></canvas>
  </body>
  <script>
    const ctx = document.getElementById('demo').getContext('2d');
    requestAnimationFrame(function step() {
      drawDial(ctx); //绘制表盘
      drawAllHands(ctx); //绘制时分秒针
      requestAnimationFrame(step);
    });

    /*绘制表盘*/
    function drawDial(ctx) {
      let pi = Math.PI;

      ctx.clearRect(0, 0, 300, 300); //清除所有内容
      ctx.save();

      ctx.translate(150, 150); //一定坐标原点到原来的中心
      ctx.beginPath();
      ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周
      ctx.stroke();
      ctx.closePath();

      for (let i = 0; i < 60; i++) {
        //绘制刻度。
        ctx.save();
        ctx.rotate(-pi / 2 + (i * pi) / 30); //旋转坐标轴。坐标轴x的正方形从 向上开始算起
        ctx.beginPath();
        ctx.moveTo(110, 0);
        ctx.lineTo(140, 0);
        ctx.lineWidth = i % 5 ? 2 : 4;
        ctx.strokeStyle = i % 5 ? 'blue' : 'red';
        ctx.stroke();
        ctx.closePath();
        ctx.restore();
      }
      ctx.restore();
    }
    /*绘制时分秒针*/
    function drawAllHands(ctx) {
      let time = new Date();

      let s = time.getSeconds();
      let m = time.getMinutes();
      let h = time.getHours();

      let pi = Math.PI;
      let secondAngle = (pi / 180) * 6 * s; //计算出来s针的弧度
      let minuteAngle = (pi / 180) * 6 * m + secondAngle / 60; //计算出来分针的弧度
      let hourAngle = (pi / 180) * 30 * h + minuteAngle / 12; //计算出来时针的弧度

      drawHand(hourAngle, 60, 6, 'red', ctx); //绘制时针
      drawHand(minuteAngle, 106, 4, 'green', ctx); //绘制分针
      drawHand(secondAngle, 129, 2, 'blue', ctx); //绘制秒针
    }
    /*绘制时针、或分针、或秒针
     * 参数1:要绘制的针的角度
     * 参数2:要绘制的针的长度
     * 参数3:要绘制的针的宽度
     * 参数4:要绘制的针的颜色
     * 参数4:ctx
     * */
    function drawHand(angle, len, width, color, ctx) {
      ctx.save();
      ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心
      ctx.rotate(-Math.PI / 2 + angle); //旋转坐标轴。 x轴就是针的角度
      ctx.beginPath();
      ctx.moveTo(-4, 0);
      ctx.lineTo(len, 0); // 沿着x轴绘制针
      ctx.lineWidth = width;
      ctx.strokeStyle = color;
      ctx.lineCap = 'round';
      ctx.stroke();
      ctx.closePath();
      ctx.restore();
    }
  </script>
</html>

效果图如下:
在这里插入图片描述

4、扩展

  1. canvas 可实现 折线图、柱状图等基础图表,也可实现各种定制性图形,可扩展性非常强。
  2. 现成的基于 canvas 的二次封装库也有很多,工作中常见的如下:
    echarts
    three.js
  3. canvas 学习链接如下:
    学习 HTML5 Canvas | 菜鸟教程
    canvas基础-CSDN博客
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值