分享个Canvas粉尘态粒子引力效应
主要特点:
鼠标移动会被依附追随
鼠标点击会被弹开
鼠标拖动会以一定的范围弹开
HTML5 Canvas粉尘态粒子引力效应
* {
margin: 0;
padding: 0;
}
html {
overflow: hidden;
}
canvas {
cursor: none;
}
window.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var pi = Math.PI;
var centerX, centerY;
var part_num = 2000; //粒子数量
var mousedown = false;
var X, Y; //鼠标坐标
var P = [];
var part = function(x, y, vx, vy, r, red, green, blue, alpha, col) {
this.x = x;
this.y = y;
this.vx = vx; //初始向左移动
this.vy = vy; //初始向右移动
this.r = r; //大小
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
this.col = col;
};
window.onmousemove = function(e) {
X = e.clientX;
Y = e.clientY;
}
window.onmousedown = function() {
mousedown = true;
}
window.onmouseup = function() {
mousedown = false;
}
var mouseover = false;
window.onmouseover = function() {
mouseover = true;
}
window.onmouseout = function() {
mouseover = false;
}
function rand(min, max) {
return Math.random() * (max - min) + min;
}
function dist(dx, dy) {
return Math.sqrt(dx * dx + dy * dy);
}
function size() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
centerX = canvas.width / 2;
centerY = canvas.height / 2;
}
size();
X = centerX;
Y = centerY;
function init() {
var x, y, vx, vy, r, red, green, blue, alpha, col;
for (var i = 0; i < part_num; i++) {
x = rand(0, canvas.width);
y = rand(0, canvas.height);
vx = rand(-5, 5);
vy = rand(-5, 5);
r = rand(1, 10);
red = Math.round(rand(150, 200));
green = Math.round(rand(100, 255));
blue = Math.round(rand(180, 255));
alpha = 1;
col = "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";
P.push(new part(x, y, vx, vy, r, red, green, blue, alpha, col));
}
}
// 背景绘制
function bg() {
// 使用 fillStyle 属性来设置用于填充绘图的颜色
ctx.fillStyle = "raba(25,25,30,1)";
// 使用fillRect() 方法绘制“已填色”的矩形
ctx.fillRect(0, 0, canvas.width, canvas.height);
//clearRect() 方法清空给定矩形内的指定像素
// ctx.clearRect(0, 0, canvas.width, canvas.height);
}
//鼠标吸引
function attract(p) {
var dx = (p.x - X),
dy = (p.y - Y),
dist = Math.sqrt(dx * dx + dy * dy), //返回距离(平方根)
angle = Math.atan2(dy, dx); //返回坐标(dx,dy)与 X轴之间的角度的弧度
if(dist > 50 && dist < 500) {
if(!mousedown) {
p.vx -= (200 / (p.r * dist)) * Math.cos(angle);
p.vy -= (200 / (p.r * dist)) * Math.sin(angle);
} else if(mousedown) {
p.vx += (300 / (p.r * dist)) * Math.cos(angle);
p.vy += (300 / (p.r * dist)) * Math.sin(angle);
}
}
}
//粒子弹弹弹
function bounce(b) {
if(b.x < b.r) {
b.x = b.y;
b.vx *= -3;
}
if(b.x > canvas.width - b.r) {
b.x = canvas.width - b.r;
b.vx *= -3;
}
if(b.y - b.r < 0) {
b.y = b.r;
b.vy *= -3;
}
if(b.y > canvas.height - b.r) {
b.y = canvas.height - b.r;
b.vy *= -3;
}
}
// 鼠标拖动
function draw() {
var p;
for(var i = 0; i < P.length; i++) {
p = P[i];
if(mouseover) attract(p);
bounce(p);
p.x += p.vx;
p.y += p.vy;
p.vx *= .975;
p.vy *= .975;
ctx.fillStyle = p.col;
ctx.fillRect(p.x, p.y, p.r, p.r);
}
ctx.strokeStyle = (!mousedown) ? "rgba(0,0,0,,1)" : "rgba(255,0,0,1)";
ctx.beginPath();
ctx.moveTo(X, Y - 10);
ctx.lineTo(X, Y + 10);
ctx.moveTo(X - 10, Y);
ctx.lineTo(X + 10, Y);
ctx.stroke();
}
function loop() {
bg();
draw();
window.requestAnimationFrame(loop);
}
// 事件
window.onresize = size;
// 初始化
init();
loop();
}
“我自己是一名从事了5年前端的老程序员,辞职目前在做讲师,今年年初我花了一个月整理了一份最适合2019年学习的web前端干货,从最基础的HTML+CSS+JS到移动端HTML5到各种框架都有整理,送给每一位前端小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。"
加QQ群:645199623(招募中)
加微❤:QD_666_QD