js粒子效果(一)
效果:

代码:
<!doctype html>
<html>
<head><meta charset="utf-8"><title>HTML5鼠标经过粒子散开动画特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 100%;background: #fff;touch-action: none;content-zooming: none;}canvas {position: absolute;width: 100%;height: 100%;background: #fff;}</style>
</head>
<body>
<canvas></canvas><script>"use strict";{// particles classclass Particle {constructor(k, i, j) {this.i = i;this.j = j;this.init();this.x = this.x0;this.y = this.y0;this.pos = posArray.subarray(k * 3, k * 3 + 3);this.pointer = pointer;}init() {this.x0 = canvas.width * 0.5 + this.i * canvas.width / 240;this.y0 = canvas.height * 0.5 + this.j * canvas.height / 160;}move() {const dx = this.pointer.x - this.x;const dy = this.pointer.y - this.y;const d = Math.sqrt(dx * dx + dy * dy);const s = 1000 / d;this.x += -s * (dx / d) + (this.x0 - this.x) * 0.02;this.y += -s * (dy / d) + (this.y0 - this.y) * 0.02;// update buffer positionthis.pos[0] = this.x;this.pos[1] = this.y;this.pos[2] = 0.15 * s * s;}}// webGL canvasconst canvas = {init(options) {// set webGL contextthis.elem = document.querySelector("canvas");const gl = (this.gl =this.elem.getContext("webgl", options) ||this.elem.getContext("experimental-webgl", options));if (!gl) return false;// compile shadersconst vertexShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,`precision highp float;attribute vec3 aPosition;uniform vec2 uResolution;void main() {gl_PointSize = max(2.0, min(30.0, aPosition.z));gl_Position = vec4(( aPosition.x / uResolution.x * 2.0) - 1.0, (-aPosition.y / uResolution.y * 2.0) + 1.0, 0.0,1.0);}`);gl.compileShader(vertexShader);const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,`precision highp float;void main() {vec2 pc = 2.0 * gl_PointCoord - 1.0;gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0 - dot(pc, pc));}`);gl.compileShader(fragmentShader);const program = (this.program = gl.createProgram());gl.attachShader(this.program, vertexShader);gl.attachShader(this.program, fragmentShader);gl.linkProgram(this.program);gl.useProgram(this.program);// resolutionthis.uResolution = gl.getUniformLocation(this.program, "uResolution");gl.enableVertexAttribArray(this.uResolution);// canvas resizethis.resize();window.addEventListener("resize", () => this.resize(), false);return gl;},resize() {this.width = this.elem.width = this.elem.offsetWidth;this.height = this.elem.height = this.elem.offsetHeight;for (const p of particles) p.init();this.gl.uniform2f(this.uResolution, this.width, this.height);this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight);}};const pointer = {init(canvas) {this.x = 0.1 + canvas.width * 0.5;this.y = canvas.height * 0.5;this.s = 0;["mousemove", "touchstart", "touchmove"].forEach((event, touch) => {document.addEventListener(event,e => {if (touch) {e.preventDefault();this.x = e.targetTouches[0].clientX;this.y = e.targetTouches[0].clientY;} else {this.x = e.clientX;this.y = e.clientY;}},false);});}};// init webGL canvasconst particles = [];const gl = canvas.init({alpha: true,stencil: true,antialias: true,depth: false});// additive blending "lighter"gl.blendFunc(gl.SRC_ALPHA, gl.ONE);gl.enable(gl.BLEND);// init pointerpointer.init(canvas);// init particlesconst nParticles = 240 * 80;const posArray = new Float32Array(nParticles * 3);let k = 0;for (let i = -120; i < 120; i++) {for (let j = -40; j < 40; j++) {particles.push(new Particle(k++, i, j));}}// create position bufferconst aPosition = gl.getAttribLocation(canvas.program, "aPosition");gl.enableVertexAttribArray(aPosition);const positionBuffer = gl.createBuffer();// draw all particlesconst draw = () => {gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);gl.bufferData(gl.ARRAY_BUFFER,posArray,gl.DYNAMIC_DRAW);gl.drawArrays(gl.GL_POINTS, 0, nParticles);}// main animation loopconst run = () => {requestAnimationFrame(run);for (const p of particles) p.move();draw();};requestAnimationFrame(run);}
</script>
<div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';"></div>
</body>
</html>
相关文章:
js粒子效果(一)
效果: 代码: <!doctype html> <html> <head><meta charset"utf-8"><title>HTML5鼠标经过粒子散开动画特效</title><style>html, body {position: absolute;overflow: hidden;margin: 0;padding: 0;width: 100%;height: 1…...
程序员必备工具篇 / 程序员必备基础:Git
前言 掌握 Git 命令是每位程序员必备的基础,之前一直是用 smartGit 工具,直到看到大佬们都是在用 Git 命令操作的,回想一下,发现有些 Git 命令我都忘记了,于是写了这篇博文,复习一下~ https://github.com/whx123/JavaHome 公众号:顺哥轻创 文章目录 Git 是什么?Git …...
MacBook使用指南
一、安装及卸载Windows系统 1、卸载Windows系统 步骤① 点击下侧任务栏中的“启动台”,进入程序坞,点击"其他",选择“启动转换助理” 步骤② 点击“继续”,接着点击“恢复”,即可卸载Windows系统 2、安装Windows系统 …...
数据库的事务的基本特性,事务的隔离级别,事务隔离级别如何在java代码中使用,使用MySQL数据库演示不同隔离级别下的并发问题
文章目录 数据库的事务的基本特性事务的四大特性(ACID)4.1、原子性(Atomicity)4.2、一致性(Consistency)4.3、隔离性(Isolation)4.4、持久性(Durability) 事务的隔离级别5.1、事务不…...
Robust taboo search for the quadratic assignment problem-二次分配问题的鲁棒禁忌搜索
文章目录 摘要关键字结论研究背景1. Introduction 常用基础理论知识2. The quadratic assignment problem3. Taboo search3.1. Moves3.2 Taboo list3.3. Aspiration function3.4. Taboo list size4. Random problems5. Parallel taboo search 研究内容、成果7. Conclusion 潜在…...
Linux:创建进程 -- fork,到底是什么?
相信大家在初学进程时,对fork函数创建进程一定会有很多的困惑,比如: 1.fork做了什么事情?? 2.为什么fork函数会有两个返回值?3.为什么fork的两个返回值,会给父进程谅回子进程pid,给子进程返回0?4.fork之后:父子进…...
基于SpringBoot+vue的token验证
后端: 1,写一个验证token的拦截器 import com.fasterxml.jackson.databind.ObjectMapper; import com.ffyc.news.model.CommonData; import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; impor…...
Clickhouse设置多磁盘存储策略
设置多磁盘存储 clickhouse安装完成以后,配置了一个默认的存储空间, 这个只能配置一个目录,如果要使用多个磁盘目录,则需要配置磁盘组策略 查看当前的存储策略 select name, path, formatReadableSize(free_space) as free, fo…...
Python开发运维:Django 4.2.7 使用Celery 5.3.5 完成异步和定时任务
目录 一、实验 1.Django使用Celery完成异步和定时任务 二、问题 1. 如何查看Django版本 一、实验 1.Django使用Celery完成异步和定时任务 (1)安装Django (2)新建Django项目 (3)初始框架 (4)urls.py引用视图views from django.contrib import admin from django.urls imp…...
媒体增加日活量的有效策略
随着数字媒体的蓬勃发展,提高日活量成为媒体平台追求的重要目标之一。日活量的增加不仅意味着更广泛的影响力,还能为媒体平台带来更多的商业机会。以下是一些有效的策略,可帮助媒体提高日活量: admaoyan猫眼聚合 内容优质化&#…...
es6新特性总结
1、支持了let和const,为了防止var声明变量带来的变量提升 (1)、存在块级作用域不存在变量提升(考虑暂时性死区) (2)、不允许重复声明(包括普通变量和函数参数)变量提升…...
Spring Boot + hutool 创建海报图片
Spring Boot hutool 创建海报图片 /*** 分享,生成图片* param id* return*/GetMapping("/getShareImg")public void getShareImg(String id,HttpServletResponse response) throws IOException {CouponConsignSaleClassify byId couponConsignSaleClassifyService…...
0002Java程序设计-springboot在线考试系统小程序
文章目录 **摘 要****目录**系统实现开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅🐧裙:776871563 摘 要 本毕业设计的内容是设计并且实现一个基于springboot的在线考试系统小程序。它是在Windows下,以MYSQL为数据库开发平台&…...
Linux(Centos)上使用crontab实现定时任务(定时执行脚本)
场景 Windows中通过bat定时执行命令和mysqldump实现数据库备份: Windows中通过bat定时执行命令和mysqldump实现数据库备份_mysqldump bat-CSDN博客 上面讲windows中使用bat实现定时任务的方式,如果是在linux上可以通过crontab实现。 cron是服务名称。…...
【Leetcode合集】20. 有效的括号
20. 有效的括号 20. 有效的括号 代码仓库地址: https://github.com/slience-me/Leetcode 个人博客 :https://slienceme.xyz 给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串…...
OpenGL 绘制线(Qt)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里同样对OpenGL中的绘制线操作进行封装,便于后续的操作,很多形状也都是基于线来生成的,如圆形等。 二、实现代码 LineDrawable.h #ifndef LINE_DRAWABLE_H #define LINE_DRAWABLE_H#include...
Java | 多线程并发编程CountDownLatch实践
关注:CodingTechWork 引言 在一次数据割接需求中,数据需要通过编程的方式进行转移割接到新平台,此时若串行化方式,无疑会拉锯此次战斗,所以首当其冲要使用并发编程来降低割接时长。 本次主要考虑使用CountDownLatc…...
分布式定时任务系列6:XXL-job触发日志过大引发的CPU告警
传送门 分布式定时任务系列1:XXL-job安装 分布式定时任务系列2:XXL-job使用 分布式定时任务系列3:任务执行引擎设计 分布式定时任务系列4:任务执行引擎设计续 分布式定时任务系列5:XXL-job中blockingQueue的应用 …...
Spark RDD、DataFrame和Dataset的区别和联系
一、三种数据介绍 是Spark中的三种不同的数据结构,它们都可以用于分布式数据处理,但是它们的实现方式和使用方法略有不同。 RDD(弹性分布式数据集) RDD是Spark最初的核心数据结构,它是一个分布式的、只读的、可容错的…...
代码随想录算法训练营第四十五天|139.单词拆分、背包问题总结
LeetCode 139. 单词拆分 题目链接:139. 单词拆分 - 力扣(LeetCode) 这道题使用完全背包来实现,我们首先考虑字符串是否可以由字符串列表组成,因此dp数组大小为n 1 ,其意义是,在n个位置时是否能…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
