蒲公英效果
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style type="text/CSS">
- *{margin: 0;padding: 0;}
- html,body{
- width: 100%;
- height: 100%;
- overflow: hidden;
- background-color: #000;
- }
- </style>
- </head>
- <body>
- <canvas id="cvs" width="100%" height="100%"></canvas>
- <script type="text/javascript">
- var bgcvs = {
- init:function(){
- //canvas 环境搭建
- this.cvs = document.getElementById('cvs');
- this.cvs.width = window.innerWidth;
- this.cvs.height = window.innerHeight;
- this.ctx = this.cvs.getContext('2d');
- //canvas 环境搭建完成
- // 定义粒子对象 200 个, 随机大小
- this.circleArr = [];
- for(var i=0;i<200;i++){
- this.circleArr.push({
- x : Math.random() * this.cvs.width,//x 是小点点的圆心坐标 X 值
- y : Math.random() * this.cvs.height,//y 是小点点的圆心坐标 Y 值
- r : Math.random() * 4 + 2, //r 为小点点的半径
- sx: Math.random() / 2 - 0.25, //sx,x 轴方向的移动速度
- sy: Math.random() / 2 - 0.25, //sy,y 轴方向的移动速度
- });
- }
- this.render();
- },
- render:function(){
- var cvs = bgcvs.cvs ,
- ctx = bgcvs.ctx ,
- circleArr = bgcvs.circleArr,
- connectPoint = [];// 该数组用来存放加了连接标记的点 (只有这里的点才和别的点连接)
- ctx.clearRect(0,0,cvs.width,cvs.height);// 因为 canvas 需要不断重绘所以要先清除画布
- ctx.fillStyle = 'black';
- ctx.fillRect(0,0,cvs.width,cvs.height);
- var lingshiArr = circleArr;
- for(var i=0;i<circleArr.length;i++){
- var x = circleArr[i].x , y = circleArr[i].y , r = circleArr[i].r , sx = circleArr[i].sx , sy = circleArr[i].sy;// 获取基本的变量, 为了操作方便
- if(x <= r || x>= cvs.width - r){// 这里的判断是, 当小点点 X 轴运动到左右两边时回弹
- circleArr[i].sx = -circleArr[i].sx;
- circleArr[i].sy = circleArr[i].sy;
- }
- if(y <= r || y>= cvs.height - r){// 这里的判断是, 当小点点 Y 轴运动到上下两边时回弹
- circleArr[i].sx = circleArr[i].sx;
- circleArr[i].sy = -circleArr[i].sy;
- }
- ctx.beginPath();// 开始绘制小点点
- ctx.arc(x,y,r,0,Math.PI*2,false);
- ctx.fillStyle = 'red';
- ctx.fill();
- ctx.closePath();// 结束绘制小点点
- circleArr[i].x += circleArr[i].sx / 2;
- circleArr[i].y += circleArr[i].sy / 2;
- if(i <circleArr.length - 2 && i % 2 == 0){// 这里判断 %2 为 0 的小点点让它具备连接其他点的权限
- var pointObj = {};
- pointObj.firstPoint = circleArr[i];
- pointObj.secondArr = [];
- for(var j = 0;j<lingshiArr.length;j++){
- if(checkPoint(circleArr[i],lingshiArr[j]) <=100 && checkPoint(circleArr[i],lingshiArr[j])>= 20){// 判断小点点是否在连接点的范围内即 > 20px <100px 范围内
- pointObj.secondArr.push(lingshiArr[j]);
- //lingshiArr.splice(i, 1);
- }
- }
- connectPoint.push(pointObj);
- }
- }
- drawLine(connectPoint);
- window.requestAnimationFrame(bgcvs.render);
- function drawLine(connetPointArr){
- //ctx.strokeStyle = 'rgba(255,255,255,0.5)';
- ctx.strokeStyle = 'red';
- ctx.lineWidth = 1;
- ctx.shadowBlur = 0;
- /// 两层循环, 以连接点为起始点, 不断向范围内的点连接, 最理想的情况下是蒲公英的样子即一对多
- for(var k = 0;k<connetPointArr.length;k++){
- var firstPoint = connetPointArr[k].firstPoint;
- var secondArr = connetPointArr[k].secondArr;
- for(var z=0;z<secondArr.length;z++){
- ctx.beginPath();
- ctx.moveTo(firstPoint.x,firstPoint.y);
- ctx.lineTo(secondArr[z].x,secondArr[z].y);
- ctx.stroke();
- ctx.closePath();
- }
- }
- };
- function checkPoint(startPoint,targetPoint){// 固定判断点是否在圆周内的方法
- var xdiff = targetPoint.x - startPoint.x,
- ydiff = targetPoint.y - startPoint.y;
- return Math.pow((xdiff * xdiff + ydiff * ydiff),0.5);
- };
- }
- };
- bgcvs.init();
- </script>
- </body>
- </html>
来源: http://www.qdfuns.com/article/44581/dc1ac27dc4f38b08945aced81763afaf.html