<canvas>
是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。例如,它可以用于绘制图表、制作图片构图或者制作简单的动画。本文将实现一个经常在博客主页出现的背景动画,在此过程中巩固复习一下Canvas
的相关知识
绘制静态图像
我们首先根据window
的尺寸和devicePixelRatio确定画布尺寸
js
const cvs = document.querySelector('canvas');
const ctx = cvs.getContext('2d');
function init() {
cvs.width = window.innerWidth * devicePixelRatio;
cvs.height = window.innerHeight * devicePixelRatio;
}
init();
因为我们最后的目的是要实现一个动画,我们会先编写一个通用的随机函数getRandom
,借用这个随机函数编写一个绘制点的构造函数Point
和一个绘制画的构造函数Graph
js
// 生成随机数
function getRandom(min, max) {
return Math.floor(Math.random() * (max + 1 - min) + min);
}
// 绘制点
class Point {
constructor() {
this.r = 6;
this.x = getRandom(0, cvs.width - this.r / 2);
this.y = getRandom(0, cvs.height - this.r / 2);
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = 'rgb(200, 200, 200)';
ctx.fill();
}
}
class Graph {
constructor(pointNumber = 30, maxDis = 500) {
this.points = new Array(pointNumber).fill(0).map(() => new Point());
this.maxDis = maxDis;
}
draw() {
for (let i = 0; i < this.points.length; i++) {
const p1 = this.points[i];
p1.draw();
for (let j = i + 1; j < this.points.length; j++) {
const p2 = this.points[j];
const d = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
if (d > this.maxDis) {
continue;
}
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.closePath();
ctx.strokeStyle = `rgba(200, 200, 200, ${0.8 - d / this.maxDis})`;
ctx.stroke();
}
}
}
}
以上我们完成了点线的绘制
绘制动态图像
动画实际上就是图像的不断刷新一点点的刷新,我们在不断的清空原来的图像,然后绘制的新的图像。我们首先在每次绘制图像的时候都使用requestAnimationFrame
注册下一次的动画,这样实现了页面图像的不断刷新。然后我们需要确定点
的运动方向,由此设置X和Y两个方向的速度,根据初中物理知识,我们要想知道点在移动距离,必须还要有一个相对时间,最后的的移动距离的值是速度
* 时间
js
class Point {
constructor() {
this.r = 6;
this.x = getRandom(0, cvs.width - this.r / 2);
this.y = getRandom(0, cvs.height - this.r / 2);
this.xSpeed = getRandom(-50, 50);
this.ySpeed = getRandom(-50, 50);
this.lastDrawTime = null;
}
draw() {
if(this.lastDrawTime){
//根据运动时间,计算当前位置
const now = Date.now()
const t = (now - this.lastDrawTime) / 1000;
let x = this.x + this.xSpeed * t
let y = this.y + this.ySpeed * t
this.x = x
this.y = y
}
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = 'rgb(200, 200, 200)';
ctx.fill();
this.lastDrawTime = Date.now()
}
}
class Graph {
draw() {
// 注册下一次画图
requestAnimationFrame(() => {
this.draw();
});
// 清空画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
优化
以上已经实现了基本的动画效果,但是有一个问题是点在运动时会越跑越远,超出我们的屏幕,下面我们要设置点的运动边界
js
if(this.lastDrawTime){
//根据运动时间,计算当前位置
const now = Date.now()
const t = (now - this.lastDrawTime) / 1000;
let x = this.x + this.xSpeed * t
let y = this.y + this.ySpeed * t
if(x <= this.r || x>= cvs.width - this.r){
this.xSpeed *= -1
}
if(y <= this.r || y>= cvs.height - this.r){
this.ySpeed *= -1
}
this.x = x
this.y = y
}
🔥🔥如果对您有一点帮助,给个👍鼓励一下吧!谢谢~🙏