canvas粒子动画背景的实现示例


Posted in HTML / CSS onSeptember 03, 2018

效果 :)

不带连线效果:

canvas粒子动画背景的实现示例

带连线的效果:

canvas粒子动画背景的实现示例

教程

要实现这样的效果其实很简单,大概分为这么几个步骤:

创建canvas

首先需要在需要展示粒子背景的父元素中创建一个canvas标签, 指定widthheight, 在我们生成随机点坐标的时候需要用widthheight来做参照。widthheight等于父元素的宽和高。

// 假如父元素是body
const ele = document.body;
const canvas = document.createElement('canvas');
canvas.width = ele.clientWidth;
canvas.height = ele.clientHeight;
// 将canvas标签插入
ele.appendChild(canvas);

随机生成一定数量的点坐标信息

widthheight做参照随机生成一定数量的点坐标信息,包含x, y, rateX(点在X轴的移动速率), rateY(点在Y轴移动的速率), rateXrateY决定了点的运动轨迹。

const points = [];
// 随机生成点的坐标,需指定radius的最大值
function getPoint(radius) {
  const x = Math.ceil(Math.random() * this.width), // 粒子的x坐标
    y = Math.ceil(Math.random() * this.height), // 粒子的y坐标
    r = +(Math.random() * this.radius).toFixed(4), // 粒子的半径
    rateX = +(Math.random() * 2 - 1).toFixed(4), // 粒子在x方向运动的速率
    rateY = +(Math.random() * 2 - 1).toFixed(4); // 粒子在y方向运动的速率

  return { x, y, r, rateX, rateY };
}

// 随机生成100个点的坐标信息
for (let i = 0; i < 100; i++) {
  points.push(this.getPoint());
}

将生成的点数组画到canvas上

function drawPoints() {
  points.forEach((item, i) => {
    ctx.beginPath();
    ctx.arc(item.x, item.y, item.r, 0, Math.PI*2, false);
    ctx.fillStyle = '#fff';
    ctx.fill();
    // 根据rateX和rateY移动点的坐标
    if(item.x > 0 && item.x < width && item.y > 0 && item.y < height) {
      item.x += item.rateX * rate;
      item.y += item.rateY * rate;
    } else {
      // 如果粒子运动超出了边界,将这个粒子去除,同时重新生成一个新点。
      points.splice(i, 1);
      points.push(getPoint(radius));
    }
  });
}

画线

遍历点数组,两两比较点坐标,如果两点之间距离小于某个值,在两个点之间画一条直线,lineWidth随两点之间距离改变,距离越大,线越细。

// 计算两点之间的距离
function dis(x1, y1, x2, y2) {
  var disX = Math.abs(x1 - x2),
    disY = Math.abs(y1 - y2);

  return Math.sqrt(disX * disX + disY * disY);
}

function drawLines() {
  const len = points.length;
  //对圆心坐标进行两两判断
  for(let i = 0; i < len; i++) {
    for(let j = len - 1; j >= 0; j--) {
      const x1 = points[i].x,
        y1 = points[i].y,
        x2 = points[j].x,
        y2 = points[j].y,
        disPoint = dis(x1, y1, x2, y2);

      // 如果两点之间距离小于150,画线
      if(disPoint <= 150) {
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.strokeStyle = '#fff';
        //两点之间距离越大,线越细,反之亦然
        ctx.lineWidth = 1 - disPoint / distance;
        ctx.stroke();
      }
    }
  }
}

动画

使用requestAnimationFrame循环调用draw方法(draw方法里包含画点和画线),同时在draw的时候根据rateXrateY来改动点的位置。

// 调用draw函数开启动画
(function draw() {
  ctx.clearRect(0, 0, width, height);
  drawPoints();
  // 如果不需要画线,取消下面这行代码即可。
  drawLines();
  window.requestAnimationFrame(draw);
}());

完整代码请看: https://github.com/PengJiyuan/particle-bg

我的Github:https://github.com/PengJiyuan

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
轻松掌握CSS3中的字体大小单位rem的使用方法
May 24 HTML / CSS
CSS3实现自定义Checkbox特效实例代码
Apr 24 HTML / CSS
HTML5应用之文件上传
Dec 30 HTML / CSS
html5 canvas实现圆形时钟代码分享
Dec 25 HTML / CSS
HTML5 localStorage使用总结
Feb 22 HTML / CSS
html5的input的required使用中遇到的问题及解决方法
Apr 24 HTML / CSS
HTML5声音录制/播放功能的实现代码
May 03 HTML / CSS
HTML5中的websocket实现直播功能
May 21 HTML / CSS
Canvas实现保存图片到本地的示例代码
Jun 28 HTML / CSS
amazeui模态框弹出后立马消失并刷新页面
Aug 19 HTML / CSS
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
Aug 07 HTML / CSS
css中:last-child不生效的解决方法
Aug 05 HTML / CSS
html5中去掉input type date默认样式的方法
Sep 06 #HTML / CSS
html5新特性与用法大全
Sep 13 #HTML / CSS
HTML5新控件之日期和时间选择输入的实现代码
Sep 13 #HTML / CSS
Html5中的桌面通知Notification的实现
Sep 25 #HTML / CSS
详解canvas drawImage()方法绘制图片不显示的问题
Oct 08 #HTML / CSS
HTML5 和小程序实现拍照图片旋转、压缩和上传功能
Oct 08 #HTML / CSS
传统HTML页面实现模块化加载的方法
Oct 15 #HTML / CSS
You might like
php引用返回与取消引用的详解
2013/06/08 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
laravel orm 关联条件查询代码
2019/10/21 PHP
jQuery EasyUI API 中文文档 - Draggable 可拖拽
2011/09/29 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
2013/10/15 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
全面理解JavaScript中的闭包
2016/05/12 Javascript
Angular2内置指令NgFor和NgIf详解
2016/08/03 Javascript
BOM系列第二篇之定时器requestAnimationFrame
2016/08/17 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
bootstrap fileinput实现文件上传功能
2017/08/23 Javascript
前端开发不得不知的10个最佳ES6特性
2017/08/30 Javascript
BootStrap数据表格实例代码
2017/09/13 Javascript
微信小程序录音与播放录音功能
2017/12/25 Javascript
bootstrap-table+treegrid实现树形表格
2019/07/26 Javascript
webpack proxy 使用(代理的使用)
2020/01/10 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
小程序实现密码输入框
2020/11/16 Javascript
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
2015/10/13 Python
python模拟Django框架实例
2016/05/17 Python
python 获取list特定元素下标的实例讲解
2018/04/09 Python
pandas 获取季度,月度,年度首尾日期的方法
2018/04/11 Python
Python中logging实例讲解
2019/01/17 Python
Python常见数据类型转换操作示例
2019/05/08 Python
Python tornado上传文件的功能
2020/03/26 Python
Python3.7安装pyaudio教程解析
2020/07/24 Python
pytorch 移动端部署之helloworld的使用
2020/10/30 Python
行政部工作岗位职责范本
2014/03/05 职场文书
董事长助理工作职责范本
2014/07/01 职场文书
简易版租房协议书范本
2014/10/13 职场文书
数学教师个人工作总结
2015/02/06 职场文书
抢劫罪辩护词
2015/05/21 职场文书
2016年小学圣诞节活动总结
2016/03/31 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
Django项目如何正确配置日志(logging)
2021/04/29 Python
Python中第三方库Faker的使用详解
2022/04/02 Python