JavaScript 画布教程展示了如何在 JavaScript 中使用画布元素。
画布
canvas 元素提供了一个与分辨率相关的位图区域,可用于动态渲染图形、游戏图形、艺术或其他视觉图像。简单来说,canvas 是一个 HTML 元素,它允许我们使用 JavaScript 绘制图形。
画布上下文
画布上下文是一个公开画布 API 以执行绘图的对象。它提供对象、方法和属性以在画布绘图表面上绘制和操作图形。使用getContext
函数检索上下文。
<!DOCTYPE html> <html> <head> <title>Canvas</title> <script type="module" src="main.mjs"></script> <style> canvas { border: 1px solid #bbb; } </style> </head> <body> <canvas id="myCanvas" width="450" height="450"> </canvas> </body> </html>
在本文中,我们使用这个 HTML 文件。 canvas 元素放置在 body 元素内。 JS 代码位于 main.mjs
模块中。
let canvas = document.getElementById('myCanvas');
使用getElementById
方法,我们获取对canvaselement 的引用。 2d
选项提供二维渲染上下文。
let ctx = canvas.getContext('2d');
使用getContext
方法检索渲染上下文。
JS画布线条
在第一个例子中,我们画线。
(function drawLines() { let canvas = document.getElementById('myCanvas'); let ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(20, 20); ctx.lineTo(250, 150); ctx.stroke(); ctx.beginPath(); ctx.moveTo(20, 20); ctx.lineTo(250, 250); ctx.lineWidth = 5; ctx.stroke(); })();
画了两条线。第二条线较粗。
ctx.beginPath();
beginPath
方法创建一个新路径。创建后,后续绘图命令将定向到路径中并用于构建路径。
ctx.moveTo(20, 20);
moveTo
方法将笔移动到 x 和 y 指定的坐标。
ctx.lineTo(250, 150);
lineTo
方法从当前绘图位置到x和y指定的位置绘制一条线。
ctx.stroke();
stroke
方法通过描边来绘制线条。
ctx.lineWidth = 5;
lineWidth
设置第二行的宽度;线条更粗。
JS 画布矩形
在下一个示例中,我们绘制矩形。
(function drawRectangles() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillStyle = 'brown'; ctx.fillRect(10, 10, 90, 60); ctx.fillStyle = 'rgb(217, 146, 54)'; ctx.fillRect(130, 10, 90, 60); ctx.fillStyle = '#3F79BA'; ctx.fillRect(250, 10, 90, 60); })();
在示例中,我们绘制了三个彩色矩形。颜色以三种不同的格式指定。
ctx.fillStyle = 'brown';
在这一行中,一个字符串值用于设置颜色值。
ctx.fillStyle = 'rgb(217, 146, 54)';
这里我们使用RGB系统。
ctx.fillStyle = '#3F79BA';
第三个矩形的颜色用RGB系统的十六进制表示法设置。
JS 画布形状
在下面的程序中,我们绘制了一些基本的形状。
(function draw() { let canvas = document.getElementById('myCanvas'); let ctx = canvas.getContext('2d'); ctx.fillStyle = 'gray'; ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 90, 60); ctx.beginPath(); ctx.arc(250, 40, 32, 0, 2 * Math.PI); ctx.fill(); ctx.beginPath(); ctx.moveTo(10, 160); ctx.lineTo(90, 160); ctx.lineTo(50, 110); ctx.closePath(); ctx.fill(); ctx.save(); ctx.scale(2, 1); ctx.beginPath(); ctx.arc(72, 130, 25, 0, 2 * Math.PI); ctx.fill(); ctx.restore(); ctx.beginPath(); ctx.arc(250, 120, 40, 0, Math.PI); ctx.fill(); })();
在示例中,我们在画布上绘制了六个不同的形状。
ctx.fillStyle = 'gray';
形状将被涂成灰色。
ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 90, 60);
矩形是用fillRect
方法绘制的。矩形是唯一不是由 beginPath
方法启动的形状。
ctx.beginPath(); ctx.arc(250, 40, 32, 0, 2*Math.PI); ctx.fill();
用arc
方法绘制圆。该方法将弧添加到创建的路径。前两个参数定义圆弧中心点的 x 和 y 坐标。接下来的两个参数指定圆弧的开始和结束角度。角度以弧度定义。最后一个参数是可选的;它指定绘制圆弧的方向。默认方向为顺时针。
ctx.beginPath(); ctx.moveTo(10, 160); ctx.lineTo(90, 160); ctx.lineTo(50, 110); ctx.closePath(); ctx.fill();
使用moveTo
和lineTo
方法,我们绘制了一个三角形。 closePath
方法使笔移回当前子路径的开头。在我们的例子中,它完成了三角形。
ctx.save(); ctx.scale(2, 1); ctx.beginPath(); ctx.arc(72, 130, 25, 0, 2*Math.PI); ctx.fill(); ctx.restore();
通过缩放圆来绘制椭圆形。操作放在save
和restore
方法之间,这样缩放操作不影响后面的绘图。
ctx.beginPath(); ctx.arc(250, 120, 40, 0, Math.PI); ctx.fill();
最后一个形状,一个半圆,是用arc
方法绘制的。
JS画布动画
在下一个例子中,我们创建一个动画。
canvas { border: 1px solid #bbb; background: #000; }
为了更好的视觉体验,将背景设置为黑色。
let cols = ["blue", "cadetblue", "green", "orange", "red", "yellow", "gray", "white"]; const NUMBER_OF_CIRCLES = 35; const DELAY = 30; let maxSize; let canvas; let ctx; let circles; function Circle(x, y, r, c) { this.x = x; this.y = y; this.r = r; this.c = c; } function init() { canvas = document.getElementById('myCanvas'); ctx = canvas.getContext('2d'); circles = new Array(NUMBER_OF_CIRCLES); initCircles(); doStep(); } function initCircles() { let w = canvas.width; let h = canvas.height; maxSize = w / 10; for (let i = 0; i < circles.length; i++) { let rc = getRandomCoordinates(); let r = Math.floor(maxSize * Math.random()); let c = cols[Math.floor(Math.random() * cols.length)] circles[i] = new Circle(rc[0], rc[1], r, c); } } function doStep() { for (let i = 0; i < circles.length; i++) { let c = circles[i]; c.r += 1; if (c.r > maxSize) { let rc = getRandomCoordinates(); c.x = rc[0]; c.y = rc[1]; c.r = 1; } } drawCircles(); setTimeout(doStep, DELAY); } function getRandomCoordinates() { let w = canvas.width; let h = canvas.height; let x = Math.floor(Math.random() * (w - (maxSize / 2))); let y = Math.floor(Math.random() * (h - (maxSize / 2))); return [x, y]; } function drawCircles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < circles.length; i++) { ctx.beginPath(); ctx.lineWidth = 2.5; let c = circles[i]; ctx.strokeStyle = c.c; ctx.arc(c.x, c.y, c.r, 0, 2 * Math.PI); ctx.stroke(); } } init();
在示例中,不断增长的彩色泡泡在屏幕上随机出现和消失。
let cols = ["blue", "cadetblue", "green", "orange", "red", "yellow", "gray", "white"];
这些颜色用于绘制气泡。
function Circle(x, y, r, c) { this.x = x; this.y = y; this.r = r; this.c = c; }
这是Circle
对象的构造函数。除了 x 和 y 坐标和半径外,它还包含颜色值的 c 属性。
circles = new Array(NUMBER_OF_CIRCLES);
circles
数组用于保存圆形对象。
for (var i = 0; i < circles.length; i++) { var rc = getRandomCoordinates(); var r = Math.floor(maxSize * Math.random()); var c = cols[Math.floor(Math.random()*cols.length)] circles[i] = new Circle(rc[0], rc[1], r, c); }
circles
数组由圆圈填充。我们计算随机坐标、随机初始半径和随机颜色值。
function doStep() {
doStep
代表程序的一个动画循环。
for (var i = 0; i < circles.length; i++) { var c = circles[i]; c.r += 1; if (c.r > maxSize) { var rc = getRandomCoordinates(); c.x = rc[0]; c.y = rc[1]; c.r = 1; } }
我们遍历 circles
数组并增加每个圆的半径。当圆达到最大大小时,它会随机重新定位并最小化。
setTimeout(doStep, DELAY);
setTimeout
方法用于创建动画。您可能需要调整 DELAY
值以适合您的硬件。
function drawCircles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < circles.length; i++) { ctx.beginPath(); ctx.lineWidth = 2.5; var c = circles[i]; ctx.strokeStyle = c.c; ctx.arc(c.x, c.y, c.r, 0, 2*Math.PI); ctx.stroke(); } }
drawCircles
函数清除画布并绘制数组中的所有圆圈。
在本文中,我们使用了 JavaScript 中的画布元素。
列出所有 JavaScript 教程。