示例效果图:
话不多说直接上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas实现圆点动画 </title>
<style>
body {
background-color: #383838;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
const cvs = document.querySelector('canvas')
const ctx = cvs.getContext('2d')
function init() {
// devicePixelRatio
cvs.width = 600
cvs.height = 600
}
init()
// 获取随机数,用于生成随机位置等
function getRandom(min, max) {
return Math.floor(Math.random() * (max + 1 - min) + min)
}
// 生成圆点
class Point {
constructor() {
// 圆的大小
this.r = 4
// 生成圆的随机位置
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
// 如果圆点位置到达边界,则回弹
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
}
// 绘制圆点
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 {
constructor(pointNumber = 30, maxDis = 300) {
// 生成圆点数组
this.points = new Array(pointNumber).fill(0).map(() => new Point())
// 圆点连接距离
this.maxDis = maxDis
}
draw() {
// 无限执行,将线与点连接
requestAnimationFrame(() => {
this.draw()
})
// 将上次绘制清楚
ctx.clearRect(0, 0, cvs.width, cvs.height)
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, ${Math.abs(((p2.x - p1.x) / this.maxDis).toFixed(1))})`
ctx.stroke()
}
}
}
}
// 初始化生成
const g = new Graph()
g.draw()
</script>
</body>
</html>
浏览器不兼容处理(重点)
ie9 以上才支持 canvas, 其他 chrome、ff、苹果浏览器等都支持
只要浏览器兼容 canvas,那么就会支持绝大部分 api(个别最新 api 除外)
移动端的兼容情况非常理想,基本上随便使用
2d 的支持的都非常好,3d(webgl)ie11 才支持,其他都支持
如果浏览器不兼容,最好进行友好提示
例如:
<canvas id="cavsElem">
你的浏览器不支持canvas,请升级浏览器.浏览器不支持,显示此行文本
</canvas>
浏览器不兼容,可以使用_flash_等手段进行优雅降