<!DOCTYPE html>
<html lang="en">
<style>
body {
overflow: hidden;
margin: 0px;
}
.container{
position: relative;
height: 900px;
width: 900px;
margin: auto;
margin-top: 100px;
background-color: aliceblue;
z-index: 1000;
}
#canvas{
z-index: 0;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<body>
<canvas id="canvas"></canvas>
<!-- <div class="container"> -->
</div>
<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')
var grd=context.createLinearGradient(0,0,window.innerHeight ,window.innerWidth);
//渐变效果函数,前两个参数是起点坐标,最后两个参数是终点坐标
grd.addColorStop(0.2,"#FF0000");
grd.addColorStop(0.5,"#00FF00");
grd.addColorStop(0.8,"#0000FF");
window.addEventListener('resize', resizeCanvas)
function resizeCanvas() { //实时调整canvas大小
canvas.height = window.innerHeight
canvas.width = window.innerWidth
}
// 创建粒子
var dots = []
for (var i = 0; i < 200; 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 = grd
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>
这个和上一篇文章的区别就是这个渐变,这个渐变非常有意思,前两个参数是起点坐标,后两个参数是终点坐标,我是从左上角到右下角的渐变,虽然我本来是想试一下随机颜色的但是随机颜色的效果很差(我写的有问题。也许下一篇会讲),刚好搜渐变搜到了这个,还蛮好玩的,有点那种小时候玩的刮的那个东西。
上图: