效果展示圖:
image.png
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>粒子線條canvas效果</title>
<style>
body{ background-color:#292929}
#J_dotLine{
display: block;
margin: 0 auto;
}
</style>
</head>
<body>
<!--
**canvasAPI
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API
**大神教程
1汰扭、http://www.cnblogs.com/axes/p/4960171.html
-->
<canvas id="J_dotLine" style="background-color: #F7F7F7;"></canvas>
<script>
function Dotline(option){
this.opt = this.extend({
dom:'J_dotLine',//畫布id
cw:1000,//畫布寬
ch:500,//畫布高
ds:100,//點的個數
r:0.5,//圓點半徑
dis:100//觸發(fā)連線的距離
},option);
this.c = document.getElementById(this.opt.dom);//canvas元素id
this.ctx = this.c.getContext('2d');
this.c.width = this.opt.cw;//canvas寬
this.c.height = this.opt.ch;//canvas高
this.dotSum = this.opt.ds;//點的數量
this.radius = this.opt.r;//圓點的半徑
this.disMax = this.opt.dis*this.opt.dis;//點與點觸發(fā)連線的間距
this.dots = [];
//requestAnimationFrame控制canvas動畫
var RAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
window.setTimeout(callback, 1000 / 60);
};
var _self = this;
//增加鼠標效果
var mousedot = {x:null,y:null,label:'mouse'};
this.c.onmousemove = function(e){
var e = e || window.event;
mousedot.x = e.clientX - _self.c.offsetLeft;
mousedot.y = e.clientY - _self.c.offsetTop;
};
this.c.onmouseout = function(e){
mousedot.x = null;
mousedot.y = null;
}
//控制動畫
this.animate = function(){
_self.ctx.clearRect(0, 0, _self.c.width, _self.c.height);
_self.drawLine([mousedot].concat(_self.dots));
RAF(_self.animate);
};
}
//合并配置項东且,es6直接使用obj.assign();
Dotline.prototype.extend = function(o,e){
for(var key in e){
if(e[key]){
o[key]=e[key]
}
}
return o;
};
//畫點
Dotline.prototype.addDots = function(){
var dot;
for(var i=0; i<this.dotSum; i++){//參數
dot = {
x : Math.floor(Math.random()*this.c.width)-this.radius,
y : Math.floor(Math.random()*this.c.height)-this.radius,
ax : (Math.random() * 2 - 1) / 1.5,
ay : (Math.random() * 2 - 1) / 1.5
}
this.dots.push(dot);
}
};
//點運動
Dotline.prototype.move = function(dot){
dot.x += dot.ax;
dot.y += dot.ay;
//點碰到邊緣返回
dot.ax *= (dot.x>(this.c.width-this.radius)||dot.x<this.radius)?-1:1;
dot.ay *= (dot.y>(this.c.height-this.radius)||dot.y<this.radius)?-1:1;
//繪制點
this.ctx.beginPath();
this.ctx.arc(dot.x, dot.y, this.radius, 0, Math.PI*2, true);
this.ctx.stroke();
};
//點之間畫線
Dotline.prototype.drawLine = function(dots){
var nowDot;
var _that = this;
//自己的思路:遍歷兩次所有的點珊泳,比較點之間的距離,函數的觸發(fā)放在animate里
this.dots.forEach(function(dot){
_that.move(dot);
for(var j=0; j<dots.length; j++){
nowDot = dots[j];
if(nowDot===dot||nowDot.x===null||nowDot.y===null) continue;//continue跳出當前循環(huán)開始新的循環(huán)
var dx = dot.x - nowDot.x,//別的點坐標減當前點坐標
dy = dot.y - nowDot.y;
var dc = dx*dx + dy*dy;
if(Math.sqrt(dc)>Math.sqrt(_that.disMax)) continue;
// 如果是鼠標薯演,則讓粒子向鼠標的位置移動
if (nowDot.label && Math.sqrt(dc) >Math.sqrt(_that.disMax)/2) {
dot.x -= dx * 0.02;
dot.y -= dy * 0.02;
}
var ratio;
ratio = (_that.disMax - dc) / _that.disMax;
_that.ctx.beginPath();
_that.ctx.lineWidth = ratio / 2;
_that.ctx.strokeStyle = 'rgba(0,0,0,' + (ratio + 0.2) + ')';
_that.ctx.moveTo(dot.x, dot.y);
_that.ctx.lineTo(nowDot.x, nowDot.y);
_that.ctx.stroke();//不描邊看不出效果
//dots.splice(dots.indexOf(dot), 1);
}
});
};
//開始動畫
Dotline.prototype.start = function(){
var _that = this;
this.addDots();
setTimeout(function() {
_that.animate();
}, 100);
}
//調用
window.onload = function(){
var dotline = new Dotline({
dom:'J_dotLine',//畫布id
cw:800,//畫布寬
ch:500,//畫布高
ds:50,//點的個數
r:0.5,//圓點半徑
dis:80//觸發(fā)連線的距離
}).start();
}
</script>
</body>
</html>