canvas是更基础的绘图方式。我们在HTML中,只需要设置相关属性,就能调整边框、文字的样式。但如何画一条曲线呢?或者一个三角形?这就需要更贴近图形的API:Canvas。

有了上面的经验,我们知道,对于API,只需要关注它如何使用,能做什么就可以了。

让我们开始一张新的网页:canvas.html

画一个三角形

画一个三角形,来了解一下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <canvas id="mycanvas"></canvas>
  11. <script>
  12. var canvas = document.getElementById('mycanvas');
  13. var ctx = canvas.getContext('2d');
  14. ctx.beginPath();
  15. ctx.moveTo(50, 50); // a
  16. ctx.lineTo(100, 50); // b
  17. ctx.lineTo(50, 100); // c
  18. ctx.fill();
  19. </script>
  20. </body>
  21. </html>

说明:

  1. Dom API,我们已经用过了

  2. “渲染上下文”,进入canvas的世界~

  3. 开始用canvas的API画

    1. 开始一条路径”path”

    2. 移动到起始点 a (50, 50)

    3. 从上一点画到这一点 b (100, 50)

    4. 再画一点 c (50, 100)

    5. 填充!

最小的面——三角形,就画好啦

稍微总结一下:

  1. 坐标系,左上角是 (0, 0)

  2. 图形是由路径构成的

  3. 填充才实际绘制

编程是一项实践活动,不用了解很多就可以开始。在实际的尝试中逐步了解。

画一个矩形呢?
很简单吧就不写了

如何描边呢?

// ctx.fill() // 删掉
ctx.stroke();

有没有点奇怪?
因为对路径来说,它可以是闭合的,也可以是开放的。

怎样闭合?

  1. 回到原点

  2. beginPath() ,当然也有 closePath()

尝试一下~

蓝色的矩形

var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(100, 50);
ctx.lineTo(100, 100);
ctx.lineTo(50, 100);
ctx.fillStyle = 'blue';
ctx.fill();

只要在画之前,设置下颜色就可以啦~

再画一个蓝色的矩形?

// ...
ctx.beginPath();
ctx.moveTo(150, 50);
ctx.lineTo(200, 50);
ctx.lineTo(200, 100);
ctx.lineTo(150, 100);
ctx.fillStyle = 'blue';
ctx.fill();

画5个矩形?
……

循环

for (var i = 0; i < 5; ++i) {
  ctx.beginPath();
  ctx.moveTo(50, 50);
  ctx.lineTo(100, 50);
  ctx.lineTo(100, 100);
  ctx.lineTo(50, 100);
  ctx.fillStyle = 'blue';
  ctx.fill();
}

什么都没发生,因为重叠了

来看看我们的问题,我们要画5个(同样大小的)矩形
唯一的不同只是它的位置
即,我们需要改变位置

编程就像给自己出题: 不是有了一道题,把答案解出来;而是已经有了一些答案,我们怎样描述这个问题。

为了简便,我们这里只移动 x

var x = 0;
for (var i = 0; i < 5; ++i) {
  x = x + 30;
  console.log(x);
  ctx.beginPath();
  ctx.moveTo(x, 10);
  ctx.lineTo(x + 20, 10);
  ctx.lineTo(x + 20, 10 + 20);
  ctx.lineTo(x, 10 + 20);
  ctx.fillStyle = 'blue';
  ctx.fill();
}

这样,它就画出了5个不同位置的矩形

再一排矩形,要绿色的

这里有一堆复制的代码,把blue改成了green

你好,我要赤橙黄绿蓝靛紫……

函数 function

函数是可以复用的代码块
同时,就像数学中
Canvas 基本绘制 - 图1%20%3D%20x%20%2B%201#card=math&code=f%28x%29%20%3D%20x%20%2B%201&id=4721fea2)
函数也可以有参数(在函数内部看来就是变量)

也就是说,我们可以把重复的部分塞到函数里面;而需要改变的部分作为参数,在调用函数的时候再告诉它。
这样,我们就不需要关注内部的复杂性,而只需要知道它有什么结果,要什么参数。

“API”也可以被看作是浏览器给我们预定义好的函数。我们只要知道它能干什么,要什么参数去调用,就可以了。

函数是抽象思维的体现。让我们能够进行高层次的、简单的思考,而不是时时刻刻带着一堆细节。

在上面的循环中,我们已经把一部分需要改变的值,换成了变量。
现在我们再整理一下,看看可以把什么作为参数?

位置,大小,颜色

function rect (x, y, width, height, color) {
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + width, y);
  ctx.lineTo(x + width, y + height);
  ctx.lineTo(x, y + height);
  ctx.fillStyle = color;
  ctx.fill();
}

var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
rect(10, 10, 50, 50, 'blue');
rect(70, 10, 50, 50, 'green');

实际上,绘制矩形的方法,Canvas API已经提供了,它们是:fillRect , strokeRect , clearRect

ctx.strokeStyle = 'red';
ctx.strokeRect(10, 70, 50, 50);
ctx.fillStyle = 'red';
ctx.fillRect(70, 70, 50, 50);
// ctx.clearRect(0, 0, 300, 150);

其他图形都需要用路径绘制。

各种各样的图形

教程:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes API列表:https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D

TODO, list common API.

现在我们写的js越来越多了,可以把js写在另一个文件里:

  1. 新建 canvas.js

  2. 在刚才写的tag script 的上面,添加<script src="./canvas.js"></script>

  3. 把script里面的的内容复制到 canvas.js

  4. 保存2个文件

嗯看到的结果是一样的

另外,按需要大小,可以在js中改变canvas的大小:

var canvas = document.getElementById('mycanvas');
canvas.width = 400; // 宽
canvas.height = 600; // 高
var ctx = canvas.getContext('2d');