<!DOCTYPE html>
<html lang="en">
<style>
body {
overflow: hidden;
margin: 0px;
}
</style>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
// 动画兼容函数
window.requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60) //延迟一帧执行一次绘制,每秒60帧
}
)
})()
const canvas = document.getElementById('canvas')
canvas.height = window.innerHeight //根据屏幕显示canvas大小
canvas.width = window.innerWidth
const context = canvas.getContext('2d')
window.addEventListener('resize', resizeCanvas)
function resizeCanvas() { //实时调整canvas大小
canvas.height = window.innerHeight
canvas.width = window.innerWidth
}
// 创建粒子
var dots = []
for (var i = 0; i < 100; i++) {
dots.push({
x: Math.random() * canvas.width, // x , y 为 粒子坐标
y: Math.random() * canvas.height,
xa: Math.random() * 3 - 1, // xa , ya 为 粒子 xy 轴加速度
ya: Math.random() * 3 - 1,
max: 100 // 连线的最大距离 px
})
}
// 鼠标粒子
let warea = {
x: null,
y: null,
max: 200 // 鼠标位置 和点的连线
}
//获取鼠标活动时的鼠标坐标
canvas.onmousemove = (e) => {
warea.x = e.clientX
warea.y = e.clientY
}
//鼠标移出界面时清空
canvas.onmouseout = (e) => {
warea.x = null
warea.y = null
}
// 绘制粒子
function drawDots() {
// 先清空
context.clearRect(0, 0, canvas.width, canvas.height)
context.fillStyle = 'rgba(0,43,54,1)'
context.fillRect(0, 0, canvas.width, canvas.height)
// 循环加载粒子
dots.forEach((dot) => {
// 粒子位移
dot.x += dot.xa //与其说是加速度不如说是速度
dot.y += dot.ya
// 遇到边界将 加速度 反向
dot.xa *= dot.x > canvas.width || dot.x < 0 ? -1 : 1
dot.ya *= dot.y > canvas.height || dot.y < 0 ? -1 : 1
// 绘制点
context.fillRect(dot.x - 1, dot.y - 1, 2, 2)
context.fillStyle = 'rgba(255,218,27,1)'
drawLine(dot, dots)
})
}
/**
* 计算距离 并连线
* @param dot 当前点
* @param dots 所有点
*/
function drawLine(dot, dots) {
var ndots = [warea].concat(dots)
for (var i = 0; i < ndots.length; i++) {
var item = ndots[i]
// 过滤错误信息
if (dot === item || item.x === null || item.y === null) continue
// 创建变量
let xc = dot.x - item.x,
yc = dot.y - item.y,
dis = '',
ratio = ''
// 两个粒子之间的距离
dis = Math.sqrt(xc * xc + yc * yc)
// 判断 粒子 之间的距离
if (dis < item.max) {
// 如果是鼠标,则让其他粒子向鼠标的位置移动
if (item === warea && dis > item.max / 10) {
dot.x -= xc * 0.03
dot.y -= yc * 0.03
}
// 计算距离比 -- 用于线 厚度
ratio = (item.max - dis) / item.max
// 画线
context.beginPath()
context.lineWidth = ratio / 2
context.strokeStyle = 'rgba(255,218,27,1)'
context.moveTo(dot.x, dot.y)
context.lineTo(item.x, item.y)
context.stroke()
}
}
}
// drawDots()
function animate() { // 使用递归实现动画
requestAnimFrame(animate) //用递归实现定时器的功效
drawDots()
}
console.log(canvas.getBoundingClientRect())
animate()
//
</script>
</body>
</html>
没什么好说的,直接上代码,这算是canvas的小练习,这是修改的网上的代码,这个可以实现屏幕自适应,而且我原本找的那个代码鼠标事件是绑定在window上的,实测并不好,可能会把点全拉走
效果图: