参考文档:canvas中文网 和 mdn中的canvas
Canvas API 主要聚焦于 2D 图形。而同样使用<canvas>元素的 WebGL API 则用于绘制硬件加速的 2D 和 3D 图形。
基本用法
...
// html部分
<canvas class="myCanvas" height="500px" width="500px"></canvas>
...
...
// css部分
* {
padding: 0;
margin: 0;
}
body {
display: grid;
place-content: center;
height: 100vh;
}
.myCanvas {
background-color: aquamarine;
border: 1px solid black;
margin: auto;
display: block;
/* height: 600px;
width: 600px; */
/* canvas中的宽度和高度只能写成行内样式,不能这样写,且默认大小是300*150大小的形状 */
box-sizing: border-box;
}
...
...
// js部分
// 这行注释可以开启canvas的代码提示,不写没有关于canvas的代码提示
/**
* @type {HTMLCanvasElement}
*/
let myCanvas = document.querySelector('.myCanvas')
// 获取上下文对象
let ctx = myCanvas.getContext('2d')
// 开启一条路径
ctx.beginPath()
// 起始点
ctx.moveTo(0,0)
// ctx.moveTo(300,600)
// 结束点
ctx.lineTo(500,500)
// 进行上色
ctx.stroke()
// 关闭路径
ctx.closePath()
...
例子:用canvas制作一个简单的canvas小球运动
// html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<canvas class="myCanvas" height="500px" width="500px"></canvas>
<script src="./5.js"></script>
<style>
* {
padding: 0;
margin: 0;
}
body {
display: grid;
place-content: center;
height: 100vh;
}
.myCanvas {
background-color: pink;
border: 1px solid black;
margin: auto;
display: block;
box-sizing: border-box;
}
</style>
</html>
// js文件
/**
* @type {HTMLCanvasElement}
*/
let myCanvas = document.querySelector(".myCanvas");
let ctx = myCanvas.getContext("2d");
/**
*
*/
let x = 100,
y = 100,
radius = 40,
startAngle = 0,
endAngle = Math.PI * 2,
couterclockwise = false,
yInitSpeed = 6, // y轴方向初始速度
xInitSpeed = 7; // x轴方向初始速度
// ctx.stroke(); // Stroke(笔触)是一个形状的轮廓,类似画边框
/**
* 画运动的球
* @param {圆心x轴坐标} x
* @param {圆心y轴坐标} y
* @param {半径} radius
* @param {开始角度} startAngle
* @param {结束角度} endAngle
* @param {是否逆时针} couterclockwise
*/
function drawCircle(x, y, radius, startAngle, endAngle, couterclockwise) {
ctx.beginPath(); // 新建一条绘画路径
ctx.arc(x, y, radius, startAngle, endAngle, couterclockwise);
ctx.fillStyle = "white"; // 先选好颜色再画图,先fillStyle再fill才生效
ctx.fill(); // Fill(填充)是在形状内部的内容
}
setInterval(() => {
ctx.clearRect(0, 0, 500, 500); // 清除指定矩形区域,让清除部分完全透明。
if (x - radius <= 0 || x + radius >= 500) {
xInitSpeed = -xInitSpeed;
}
x = x + xInitSpeed;
if (y - radius <= 0 || y + radius >= 500) {
yInitSpeed = -yInitSpeed;
}
y = y + yInitSpeed;
drawCircle(x, y, radius, startAngle, endAngle, couterclockwise);
}, 50);
setInterval(() => {
console.log("小球的速度为:", x);
}, 4000);
例子改写:用canvas制作多个不规则的canvas小球运动
// js文件
/**
* @type {HTMLCanvasElement}
*/
let myCanvas = document.querySelector(".myCanvas");
let ctx = myCanvas.getContext("2d");
let w = 500,
h = 500;
// 多个小球运动,采用面向对象的思想
function Ball() {
// Math.random():[0,1)
this.x = (Math.random() * w) / 100 + 70;
this.y = (Math.random() * h) / 100 + 70;
this.radius = Math.random() * 60 + 10;
this.color = "#" + parseInt(Math.random() * 0xffffff).toString(16);
this.xInitSpeed = Math.random() * 5 + 11;
this.yInitSpeed = Math.random() * 10 + 10;
this.startAngle = 0;
this.endAngle = Math.PI * 2;
this.couterclockwise = false;
this;
}
// 定义小球显示的方法
Ball.prototype.show = function() {
ctx.beginPath(); // 新建一条绘画路径
ctx.arc(
this.x,
this.y,
this.radius,
this.startAngle,
this.endAngle,
this.couterclockwise
);
ctx.fillStyle = this.color; // 先选好颜色再画图,先fillStyle再fill才生效
ctx.fill(); // Fill(填充)是在形状内部的内容
};
// 创建出现多个小球
let ballArr = []; // 记录生成的小球,方便后续操作创建的小球
for (let i = 0; i < Math.random() * 10 + 5; i++) {
// new Ball().show()
let ball = new Ball();
ballArr.push(ball);
ball.show();
}
console.log(ballArr);
// 小球的运动
Ball.prototype.run = function() {
if (this.x - this.radius <= 0 || this.x + this.radius >= w) {
this.xInitSpeed = -this.xInitSpeed;
}
this.x = this.x + this.xInitSpeed;
if (this.y - this.radius <= 0 || this.y + this.radius >= h) {
this.yInitSpeed = -this.yInitSpeed;
}
this.y = this.y + this.yInitSpeed;
};
// 给创建的小球加运动
setInterval(() => {
ctx.clearRect(0, 0, w, h);
for (const item of ballArr) {
item.run();
item.show();
}
}, 50);
这让我想起了一个自己线下碰到的一个面试题:如果前端页面中需要根据后端返回的数据,绘制对应的不同形状的图片,怎么实现?我当时居然连canvas都不想上去!想必面试官应该很无语吧,作为前端居然不知道canvas,简直是离离原谱!!!**