canvas初体验--canvas实现写字板

1,445 阅读3分钟

Canvas 究竟是个啥

canvas的英文意思就是画布,在我们这儿canvas其实一个HTML5标签,用来定义图形,HTML5标签只是图形容器,我们需要使用脚本来绘制图形;如果我们不使用canvas,会操作大量的DOM,会消耗大量性能,而canvas不会;下面的例子可实现在PC端在移动端像画板一样写字

实际运用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas能实现划线的画板</title>
  <style>
    *{
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    canvas {
      border:1px solid red;
    }
  </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
  const canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    const cvs = canvas.getContext("2d");
    console.log(cvs);
  }
</script>
</body>
</html>

  • 从以上代码可以看到canvas并没有设置宽度和高度,但是cavas宽高却不是0,这是因为当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。另外需要特别注意的时候,如果我们要改变canvas的宽度与高度,要使用width和height属性来改变,而不是css方式改变,如果使用css方式改变宽高,图像会出现扭曲的现象;
  • canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。getContext方法是用来获得渲染上下文和它的绘画功能。我们可以通过打印,可以看到anvasRenderingContext2D对象具体内容
  • 把画布大小变为屏幕大小
<script>
  const canvas = document.getElementById("canvas");
  // 设置canvas宽高
  canvas.width = document.documentElement.clientWidth;
  canvas.height = document.documentElement.clientHeight;
  if (canvas.getContext) {
    const cvs = canvas.getContext("2d");
  }
</script>
  • 绘画圆点
 const canvas = document.getElementById("canvas");
  // 设置canvas宽高
  canvas.width = document.documentElement.clientWidth;
  canvas.height = document.documentElement.clientHeight;
  if (canvas.getContext) {
    const ctx = canvas.getContext("2d");
    // 新建一条路径
    ctx.beginPath();
    // 绘制
    ctx.arc(10,10,10,0,Math.PI*2,true);
    // 填充
    ctx.fill();
  }
  • 鼠标移动哪里就有绘画,我们可以使用onmousemove
const canvas = document.getElementById("canvas");
  // 设置canvas宽高
  canvas.width = document.documentElement.clientWidth;
  canvas.height = document.documentElement.clientHeight;
  if (canvas.getContext) {
    canvas.onmousemove = (e) => {
      const ctx = canvas.getContext("2d");
      // 新建一条路径
      ctx.beginPath();
      // 绘制
      ctx.arc(e.clientX,e.clientY,10,0,Math.PI*2,true);
      // 填充
      ctx.fill();
    }
  }
  • 但是以上代码有问题的点是,鼠标只要移动就会绘画,我们需要鼠标按下后拖动才绘画,我们可以设个开关controlPainting,当鼠标按下后controlPainting打开,鼠标起来后,开关关闭
  • 由于触屏设备没有鼠标事件,因此要做判断;
<script>
  let controlPainting = false;
  const canvas = document.getElementById("canvas");
  // 设置canvas宽高
  canvas.width = document.documentElement.clientWidth;
  canvas.height = document.documentElement.clientHeight;
  const ctx = canvas.getContext("2d");
  ctx.fillStyle = "black";
  // 判断是否触屏设备
  const isTouchDevice = 'ontouchstart' in document.documentElement;
  // 触屏设备
  if(isTouchDevice) {
    canvas.ontouchmove = (e) => {
      // 新建一条路径
      ctx.beginPath();
      // 绘制
      ctx.arc(e.targetTouches[0].clientX,e.targetTouches[0].clientY,10,0,Math.PI*2,true);
      // 填充
      ctx.fill();
    }
  }else {
    // pc设备
    canvas.onmousedown = (e) => {
      controlPainting = true;
    };
    canvas.onmousemove = (e) => {
      if (!controlPainting) {
        return false;
      }
      // 新建一条路径
      ctx.beginPath();
      // 绘制
      ctx.arc(e.clientX,e.clientY,10,0,Math.PI*2,true);
      // 填充
      ctx.fill();
    }
    canvas.onmouseup = (e) => {
      controlPainting = false;
    }
  }
</script>

  • 如上图会出现断点的现象,我们可以把画圆点换成画线
<script>
  let controlPainting = false;
  let posX = '';
  let posY = '';
  const canvas = document.getElementById("canvas");
  // 设置canvas宽高
  canvas.width = document.documentElement.clientWidth;
  canvas.height = document.documentElement.clientHeight;
  const ctx = canvas.getContext("2d");
  ctx.lineWidth = 6;
  ctx.lineCap = 'round';
  // 判断是否触屏设备
  const isTouchDevice = 'ontouchstart' in document.documentElement;
  // 触屏设备
  if(isTouchDevice) {
    canvas.ontouchstart = (e) => {
      posX = e.targetTouches[0].clientX;
      posY= e.targetTouches[0].clientY;
    };
    canvas.ontouchmove = (e) => {
      drawLine(posX, posY, e.targetTouches[0].clientX, e.targetTouches[0].clientY);
      posX = e.targetTouches[0].clientX;
      posY= e.targetTouches[0].clientY;
    }
  }else {
    // pc设备
    canvas.onmousedown = (e) => {
      controlPainting = true;
      posX = e.clientX;
      posY= e.clientY;
    };
    canvas.onmousemove = (e) => {
      if (!controlPainting) {
        return false;
      }
      drawLine(posX, posY, e.clientX, e.clientY);
      posX = e.clientX;
      posY= e.clientY;
    }
    canvas.onmouseup = (e) => {
      controlPainting = false;
    }
  }
  // 画线
  let drawLine = (originX, originY, finalX, finalY) => {
    console.log(originX, originY, finalX, finalY)
    // 新建一条路径
    ctx.beginPath();
    // 起点
    ctx.moveTo(originX, originY);
    // 终点
    ctx.lineTo(finalX, finalY);
    // 填充
    ctx.stroke();
  }
</script>


最后经过修改后,就非常流畅了;