Canvas入门学习——小试牛刀

48 阅读4分钟

本篇文章分享来自小伙伴「guanghuan」的一次学习总结分享。

定义

顾名思义,Canvas即为绘画的地方,允许JavaScript动态的绘制图形,标签定义了网页上的绘图区域。有了,开发者就可以使用JavaScript绘制任何想画的东西。提供了一些简单的绘图函数,用来绘制点、线、矩形、圆等等。

基本操作

  • 创建canvas容器
// 必须设置width和height,否则会按照默认100, 100的属性来渲染
<canvas id="canvas1" width="600" height="600"></canvas>
  • 获取canvas画笔
const myCanvas = document.querySelector('#canvas1');
const ctx = myCanvas.getContext('2d'); // 现在ctx就是开发者想要的画笔了
  • 画直线 ,效果如图
  ctx.strokeStyle = '#5ac05a'; // 指定画笔的颜色
  ctx.moveTo(0, 75); // 指定画笔的起点,传入的参数依次是x轴方向和y轴方向相对canvas容器左上角的单                         位距离
  ctx.lineTo(75, 75);// 指定画笔的终点
  ctx.stroke(); // 给线段填充颜色

画直线.png

  • 画圆 ,效果如图
  ctx.strokeStyle='5ac05a';
  ctx.lineWidth=2;
  // 入参分别是x轴、y轴方向相对canvas容器左上角的距离,圆的半径,开始绘制的角度,结束绘制的角度。画布      的0度从正左边开始
  ctx.arc(100, 100, 50, 0, 2*Math.PI);
  ctx.stroke();

画圆.png

  • 画实心矩形 ,效果如图
   // 实心部分的填充色
   ctx.fillStyle = '#ff0000';
   // 入参分别是x轴,y轴方向相对于canvas容器左上角的距离,矩形的长度,宽度
   ctx.fillRect(100, 100 , 75, 75);

画矩形.png

小结

  • 在掌握了直线,矩形,圆的绘制方法后,也算是一脚迈进了canvas学习的大门,下面再学习一下canvas更有趣的API

进阶操作

  • 刮刮卡
    • 我们应该怎么实现刮刮卡呢?
      1. 设置奖品内容,这个很轻松,随便造个dom元素放到界面上即可
      2. 要有能遮住奖品内容的刮奖层,随便放个canvas容器,画上一层纯色图形
      3. 实战发现【奖品内容】怼到canvas容器表层了,只好给【奖品内容】设置z-index属性了
      4. 然后用canvas的fillText()加上文字
      5. 给canvas添加mouseDown, mouseUp, mouseMove事件
      6. 刮奖过程怎么让对应位置的内容显示,发现canvas有个globalCompositeOperation非常的妙,可以让图像产生透明的效果。详情可以看这里
      7. 至此,刮刮卡需要的东西都有了,接下来开始代码编写
  • 代码
    • html部分
<div class="father" style="position: relative;">
    <div class="" style="
    position: absolute;
    width: 150px;
    height: 20px;
    left: 130px;
    top: 30px;
    z-index: -1;"
    >
      你真棒,奖励你再做一个画画板吧
    </div>
    
    <canvas id="canvas1"
            width="400"
            height="400"
            style="
                   border: 1px solid #000;
                   width: 400;
                   height: 400px;"
    >
    </canvas>
</div>
  • js部分
const myCanvas = document.querySelector('#canvas1');
const ctx = myCanvas.getContext('2d');
// 设置刮奖层的填充颜色
ctx.fillStyle = '#c01219';
// 设置刮奖层位置、形状
ctx.fillRect(100, 0, 200, 100);
// 绘制刚刚设置的图案
ctx.fill();
// 设置字体颜色
ctx.fillStyle = '#f7d432';
// 设置字体样式
ctx.font = '30px Arial';
// 插入具体的内容,后面的两个为位置参数
ctx.fillText('轻轻的刮我', 120, 60);

// 声明全局变量,控制鼠标按下时才启动刮奖模式
let isDraw = false;

myCanvas.addEventListener('mousedown', ()=>{
  isDraw = true;
});

myCanvas.addEventListener('mousemove', (e)=>{
  if (!isDraw) return;
  // 这里是因为我在当前canvas容器上方还有其他demo,所以位置都根据可视区范围计算
  const x = e.clientX - myCanvas.getBoundingClientRect().left;
  const y = e.clientY - myCanvas.getBoundingClientRect().top;
  // 这里自己看上方超链接的文档
  ctx.globalCompositeOperation = 'destination-out';
  
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, 2 * Math.PI);
  // 解决非连续轨迹产生的连线
  ctx.closePath();
  // 绘制之前设置的图形 
  ctx.fill();
});

myCanvas.addEventListener('mouseup', ()=>{
  isDraw = false;
})

刮奖前的样子 画刮刮卡1.png

开始刮奖 画刮刮卡2.png 刮完了,奖励一个新挑战 画刮刮卡3.png

小结

  • 通过上面的小试牛刀,电脑前的你肯定已经把另外一只脚也伸canvas的大门里了,下面再进一步,我们完全可以结合vue框架制作一款自己的画画板。

中阶操作

记得引入vue的在线地址:cdn.jsdelivr.net/npm/vue@2.6…

  • html
<h2>画板</h2>
  <div id="board-box">
    <div>
      <button @click="clearCanvas">清空画布</button>
      <button @click="setEraser">橡皮</button>
      <button @click="setPencil">画笔</button>
    </div>
    <canvas
            id="board"
            width="600"
            height="400"
            @mousedown="drawDown"
            @mousemove="drawMove"
            @mouseUp="drawUp"
            style="border: 1px solid #2d2d2d;margin-top: 5px"
    ></canvas>
  </div>
  • js代码
const myCanvas = document.querySelector('#board');
const ctx = myCanvas.getContext('2d');

new Vue({
  el: '#board-box',
  data: {
    draw: false,
    beginX: 0,
    beginY: 0,
    endX: 0,
    endY: 0,
    board: null,
    boardCanvas: null,
    lineWidth: 2,
    // false: 橡皮, true: 画笔
    state: true
  },

  watch: {
    endX () {
      if (this.endX > 595 || this.endX < 2) {
        this.draw =false
      }
    },
    endY () {
      if (this.endY > 395 || this.endY < 2) {
        this.draw =false
      }
    }
  },

  methods: {
    drawDown (e) {
      this.draw = true;
      this.beginX = e.pageX - this.boardCanvas.offsetLeft;
      this.beginY = e.pageY - this.boardCanvas.offsetTop;
      this.board.fillStyle = '#ff0000';
      this.board.lineWidth = 2;
      this.board.beginPath();
      this.board.moveTo(this.beginX, this.beginY);
    },

    drawMove (e) {
      if (!this.draw) {
        return
      }
      this.endX = e.pageX - this.boardCanvas.offsetLeft;
      this.endY = e.pageY - this.boardCanvas.offsetTop;
      if(this.state) {
        this.usePencil();
      } else {
        this.useEraser(this.endX, this.endY);
      }
    },

    drawUp () {
      this.draw =false;
    },

    clearCanvas () {
      this.board.clearRect(0, 0, 600, 400);
    },

    usePencil () {
      this.board.lineTo(this.endX, this.endY);
      this.board.stroke();
    },

    useEraser (x, y) {
      this.board.clearRect(x, y, 10, 10);
    },

    setEraser () {
      this.state = false;
    },
    setPencil () {
      this.state =true;
    }
  },
  mounted () {
    this.boardCanvas = document.querySelector('#board');
    this.board = this.boardCanvas.getContext('2d');
  }
})

真不错,下面我来演示一下效果 画画板1.png 感觉还不错,哈哈 画画板2.png

  • 这里我已经实现了画图和橡皮擦除的功能了,以上代码是可以正常运行的,感兴趣的同学可以拿去跑一下,都没有问题。另外,大家可以思考一下,给画画板增加【颜色选择器】,【保存下载】等功能,其实也很简单,哈哈。