JavaScript canvas
最后修改于 2023 年 10 月 18 日
在本文中,我们将展示如何在 JavaScript 中使用 canvas 元素。
Canvas
canvas 元素提供了一个依赖于分辨率的位图区域,可用于动态渲染图形、游戏图形、艺术或其他视觉图像。 简单来说,canvas 是一个 HTML 元素,允许我们使用 JavaScript 绘制图形。
Canvas 上下文
canvas 上下文是一个对象,它公开了 Canvas API 以执行绘图。 它提供了对象、方法和属性,用于在 canvas 绘图表面上绘制和操作图形。 上下文使用 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 方法,我们获取对 canvas 元素的引用。 2d 选项提供了一个二维渲染上下文。
let ctx = canvas.getContext('2d');
使用 getContext 方法检索渲染上下文。
JS canvas 线条
在第一个例子中,我们绘制线条。
(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 canvas 矩形
在下一个例子中,我们绘制矩形。
(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 canvas 形状
在下面的程序中,我们绘制一些基本形状。
(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();
})();
在示例中,我们在 canvas 上绘制了六种不同的形状。
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 动画
在下一个例子中,我们创建一个动画。
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 函数清除 canvas 并绘制数组中的所有圆。
来源
在本文中,我们使用了 JavaScript 中的 canvas 元素。