博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
H5+canvas动态粒子背景
阅读量:4583 次
发布时间:2019-06-09

本文共 5986 字,大约阅读时间需要 19 分钟。

首先,效果图为:

 H5代码为

样式设计CSS:

最重要的就是js代码了。这里一步步来实现上述粒子效果。

通过看图我们可以发现,就是由很多圆点跟线条组成的动态效果,那么要实现的就是绘制N个圆形,以及在一定距离内的两个原点之间连线。

1.首先获取到canvas对象,以及获取屏幕的宽,高,创建一个圆点列表。

var canvas = document.getElementById('canvas');            var ctx = canvas.getContext('2d');                        var w = canvas.width = canvas.offsetWidth;            var h = canvas.height = canvas.offsetHeight;            var circles = [];

2.绘制N个原点,这里随便多少个都可以,暂定60个。要绘制圆形,需要用到canvas的arc()方法,具体思路见,那么我们这里定义一个方法

function drawCircle(ctx) {                    ctx.beginPath();                    ctx.arc(this.x, this.y, this.r, 0, 360);                    ctx.fillStyle = 'rgba(204, 204, 204, 0.3)';                    ctx.fill();                }

该方法就可以通过canvas对象实现创建圆形了。那么看上述方法中的this.s, this.y表示的坐标,其实是这一方法定义在一个对象中,因为我们要创建很多圆形,所以定义了一个js对象,并且给该对象加入了画圆,画线,以及原点不断移动的方法。

//创建对象:圆            //x, y为坐标点, r为半径, _mx, _my为移动的距离            function circle(x, y) {                this.x = x;                this.y = y;                this.r = Math.random() * 10;                this._mx = 1 - (Math.random() * 2);                this._my = 1 - (Math.random() * 2);                                this.drawCircle = drawCircle;                function drawCircle(ctx) {                    ctx.beginPath();                    ctx.arc(this.x, this.y, this.r, 0, 360);                    ctx.fillStyle = 'rgba(204, 204, 204, 0.3)';                    ctx.fill();                }                                this.move = move;                function move(w, h) {                    this._mx = (this.x < w && this.x > 0) ? this._mx : (-this._mx);                    this._my = (this.y < h && this.y > 0) ? this._my : (-this._my);                    this.x += this._mx / 2;                    this.y += this._my / 2;                }                                this.drawLine = drawLine;                function drawLine(ctx, _circle) {                    var dx = this.x - _circle.x;                    var dy = this.y - _circle.y;                    var d = Math.sqrt(dx * dx + dy * dy);                    if (d < 150) {                        ctx.beginPath();                        ctx.moveTo(this.x, this.y);                        ctx.lineTo(_circle.x, _circle.y);                        ctx.strokeStyle = 'rgba(204, 204, 204, 0.3)';                        ctx.stroke();                    }                }            }

由上述代码可以看到,只需要传入相应的(x, y)坐标点,就可以创建一个原点。

其中r半径是随机函数产生的随机数,所以最后生成的原点大小不一。

偏移量_mx,_my也是随机数,由1 - (Math.random() * 2)可以看出偏移范围为(-1, 1),所以我们可以看到有的点向左,有的向下,向左,向右,方向不一,能一定程度保证所有点均匀分布在屏幕中。

需要注意的是this.drawCircle = drawCircle;在对象中定义了方法之后还需要把方法添加到 JavaScript 对象。

移动方法move(),确保原点要在屏幕内移动,所以对于偏移量有个判断,当坐标超出坐标范围后,偏移量正负变换,即向之前移动方向的反方向移动。

两点之间画线的方法,这里设定两点之间连线的范围为0~150,超过150就不会再连线了。具体连线方法也可见。方法中涉及到求两点之间的直线距离,Math.sqrt(dx * dx + dy * dy),这个应该也好理解。

3. 定义了绘制圆点的方法,那么我们要再定义一个方法将所有的点画出来。这里就要用到最开始定义的圆点列表circles。

    ...
function init(num) {                for(var i = 0; i < num; i ++) {                    circles.push(new circle(Math.random() * w, Math.random() * h));                }                draw();            }

body上的onload方法表示网页进入时触发的方法,一打开网页就要马上加载init方法。

init方法,可以看到,是创建了60个circle实例push进原点列表中了,而创建的实例的坐标点都是随机的范围再(0, 0) ~ (w, h)。创建好实例后就要开始画点了啊!调用draw方法。

function draw() {                ctx.clearRect(0, 0, w, h);                for(var i = 0; i < circles.length; i ++) {                    circles[i].move(w, h);                    circles[i].drawCircle(ctx);                    for(var j = i + 1; j < circles.length; j++) {                        circles[i].drawLine(ctx, circles[j]);                    }                }                requestAnimationFrame(draw);            }

在上述方法中,遍历所有原点,调用circle对象的方法,画圆以及移动,里面的for循环表示每个当前点都与数组后面的点相连即可,即不需要考虑后面的点与前面的点相连问题,因为两点之间连一次就可以了,所以j从1 + 1开始。

这里更新页面用requestAnimationFrame替代setTimeout。

window.requestAnimationFrame = window.requestAnimationFrame                                         || window.mozRequestAnimationFrame                                         || window.webkitRequestAnimationFrame                                         || window.msRequestAnimationFrame;

 

4. 到目前为止,就实现了60个点在屏幕上移动,且150距离内的两点会有连线,那么为了更好的体验效果,我们可以加入鼠标进入屏幕的互动效果。

鼠标进入后会生成一个半径确定的(这里假定8,都可以)不同颜色的原点,且该点在与任意点距离在150以内时要有连线。

那么,需要创建一个对象继承circle,重写画圆方法。

function currentCircle(x, y) {                circle.call(this, x, y);                                this.drawCircle = drawCircle;                function drawCircle(ctx) {                    ctx.beginPath();                    ctx.arc(this.x, this.y, 8, 0, 360);                    ctx.fillStyle = 'rgba(255, 77, 54, 0.6)';                    ctx.fill();                }            }

其实,这里也可以不定义这个对象,可以把circle对象改一下,将颜色也定为参数即可。

好了,对象定义好了,那么就要创建实例了,初始状态为

var current_circle = new currentCircle(0, 0);

 

在屏幕中移动以及离开屏幕的事件响应也可以有了。clientX为鼠标指针向对于浏览器页面(或客户区)的水平坐标。

window.onmousemove = function(e) {                e = e || window.event;                current_circle.x = e.clientX;                current_circle.y = e.clientY;            }            window.onmouseout = function() {                current_circle.x = null;                current_circle.y = null;             }

最后,鼠标点与其他点的连线,修改draw方法

function draw() {                ctx.clearRect(0, 0, w, h);                for(var i = 0; i < circles.length; i ++) {                    circles[i].move(w, h);                    circles[i].drawCircle(ctx);                    for(var j = i + 1; j < circles.length; j++) {                        circles[i].drawLine(ctx, circles[j]);                    }                }                 if (current_circle.x) {                    current_circle.drawCircle(ctx);                    for (var k = 0; k < circles.length; k++) {                        current_circle.drawLine(ctx, circles[k])                    }                }                requestAnimationFrame(draw);            }

加了一个判断,如果current_circle的x坐标不为0了(初始状态为0,见实例创建),那么就要画鼠标点了,且遍历所有的圆点,能连线的都连线。到这里,开头的动图上的效果都实现了。

最后,原码下载地址GitHub:

 

转载于:https://www.cnblogs.com/sakurayj/p/10309941.html

你可能感兴趣的文章
poj 1002:487-3279(水题,提高题 / hash)
查看>>
RAC环境上搭建DG
查看>>
OS X Mountain Lion高手进阶
查看>>
精通CSS:高级Web标准解决方案(第2版)(Amazon第一CSS畅销书全新改版)
查看>>
初识电流环
查看>>
MySQL每天自动增加分区
查看>>
在线生成坐标值,方便布局使用
查看>>
ab测试工具的使用
查看>>
RTL基本知识:编译命令指定隐性线网类型
查看>>
java中BigDecimal在金融行业中的使用
查看>>
66.Plus One
查看>>
爬虫——小结
查看>>
sticky bit
查看>>
sqlserver 中 where 条件和 join 条件的作用比较
查看>>
jvm解析和调优
查看>>
Linux 连接mysql服务器
查看>>
linux内核学习:中断中推后执行的部分
查看>>
数据库系统概论【基础篇】
查看>>
shell脚本中大于,大于等于,小于,小于等于、不等于的表示方法
查看>>
xcode 快捷键
查看>>