H5 鼠标点击粒子扩散效果

news2024/11/20 9:15:41

🧐别人的博客中有这样的效果,于是自己就尝试实现了一下。
效果如图
在这里插入图片描述
源码如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">

    <style>
        .blastParticle {
            position: absolute;
            transform: translate(-50%, -50%);
            pointer-events: none;
        }


        body {
            overflow: hidden;
        }



        .hint-text {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100vw;
            height: 100vh;
            user-select: none;
        }
    </style>
</head>

<body>
    <div class="hint-text">
        点击鼠标左键,查看粒子效果
    </div>


    <script type="module">
        import { Randoms } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/randoms.js";
        import { Animation } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/animation.js";
        import { Maths } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/maths.js";


        /**
         * 爆炸粒子效果
         */
        function blastParticle(params = {}) {
            
            let { left = 0, top = 0, width = 200, height = 200, count = 20, rr = [10, 20], duration = 1 } = params

            // 通过recovery拾取回收canvas 减少dom产生量
            let canvas = document.querySelector('canvas.blastParticle.recovery') || document.createElement("canvas")
            canvas.classList.remove('recovery')

            let ctx = canvas.getContext('2d')
            canvas.width = width;
            canvas.height = height;

            canvas.classList.add('blastParticle')
            canvas.style.left = left + 'px'
            canvas.style.top = top + 'px'


            let cx = width / 2
            let cy = height / 2

            class Particle {
                constructor({ x, y, r, tx, ty, ts, color, duration }) {
                    this.x = x;
                    this.y = y;
                    this.r = r;
                    this.tx = tx;
                    this.ty = ty;
                    this.ts = ts;
                    this.color = color

                    this.timestemp = +new Date()

                    this.update = () => {
                        if ((+new Date() - this.timestemp) > 1000 * duration) return;

                        let timeProportion = (+new Date() - this.timestemp) / (1000 * duration)
                        let proportion = Animation.easeOut(timeProportion)

                        this.x = x + tx * proportion
                        this.y = y + ty * proportion
                        this.r = r * (1 - timeProportion)

                        ctx.fillStyle = color
                        ctx.beginPath()
                        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2)
                        ctx.closePath();
                        ctx.fill()
                    }
                }
            }



            // 记录开始时间 用于停止渲染标记
            let startTimestemp = +new Date()

            function renderer(particles) {
                ctx.clearRect(0, 0, width, height)
                for (const p of particles) {
                    p.update()
                }

                if (+new Date() - startTimestemp < duration * 1000) {
                    console.log("渲染中");
                    requestAnimationFrame(() => { renderer(particles) })
                }
                else {
                    console.log('渲染结束');
                    canvas.classList.add('recovery');
                }
            }

            // 粒子列表
            let particleList = []
            for (let i = 0; i < count; i++) {
                // 随机方向
                let tx = 2 * Math.random() - 1
                let ty = 2 * Math.random() - 1
                // 乘以半径
                tx *= cx;
                ty *= cy;
                let particle = new Particle({ x: cx, y: cy, r: Randoms.getRandomInt(...rr), tx, ty, ts: 0, duration, color: Randoms.getRandomColor() })
                particleList.push(particle)
            }
            // 执行渲染
            renderer(particleList)
            document.body.appendChild(canvas)
        }

        document.addEventListener("click", (ev) => {
            blastParticle({ left: ev.x, top: ev.y, duration: .5 })
        })
    </script>
</body>

</html>

在线预览
https://linyisonger.github.io/H5.Examples/
源码仓库
https://github.com/linyisonger/H5.Examples.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1661697.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文彻底读懂信息安全等级保护:包含等保标准、等保概念、等保对象、等保流程及等保方案(附:等保相关标准文档)

1. 什么是等级保护&#xff1f; 1.1. 概念 信息安全等级保护是指根据我国《信息安全等级保护管理办法》的规定&#xff0c;对各类信息系统按照其重要程度和保密需求进行分级&#xff0c;并制定相应的技术和管理措施&#xff0c;确保信息系统的安全性、完整性、可用性。根据等…

CTFHUB-技能树-Web题-RCE(远程代码执行)-文件包含

CTFHUB-技能树-Web题-RCE&#xff08;远程代码执行&#xff09; 文件包含 文章目录 CTFHUB-技能树-Web题-RCE&#xff08;远程代码执行&#xff09;文件包含解题方法1:![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/71f7355b3c124dfe8cdf1c95e6991553.png#pic_ce…

Docker快速搭建NAS服务——NextCloud

Docker快速搭建NAS服务——NextCloud 文章目录 前言NextCloud的搭建docker-compose文件编写运行及访问 总结 前言 本文主要讲解如何使用docker在本地快速搭建NAS服务&#xff0c;这里主要写如下两种&#xff1a; FileBrowser1&#xff1a;是一个开源的Web文件管理器&#xff…

我觉得POC应该贴近实际

今天我看到一位老师给我一份测试数据。 这是三个国产数据库。算是分布式的。其中有两个和我比较熟悉&#xff0c;但是这个数据看上去并不好。看上去第一个黄色的数据库数据是这里最好的了。但是即使如此&#xff0c;我相信大部分做数据库的人都知道。MySQL和PostgreSQL平时拿出…

常用七大加密软件排行榜|好用加密文件软件分享

数据安全与隐私保护已成为我们每个人都必须面对的重要问题。 文件加密软件作为保障数据安全的关键工具&#xff0c;其重要性不言而喻。 在众多的加密软件中&#xff0c;哪些软件能够在保障数据安全的同时&#xff0c;又具备良好的易用性和稳定性呢&#xff1f; 本文将为您揭秘…

YOLO系列笔记(十)—— 基础:卷积层及其计算公式

卷积层及其计算公式 前言定义与功能计算过程与输出尺寸没有填充的情况有填充的情况 网络结构中的表示分析一&#xff1a;数字的含义分析二&#xff1a;分支的含义 前言 卷积层是在深度学习领域中非常常见、基础且重要的一种神经网络层。许多初学者可能会对卷积层的功能、其计算…

【Git】Github创建远程仓库并与本地互联

创建仓库 点击生成新的仓库 创建成功后会生成一个这样的文件 拉取到本地 首先先确保本地安装了git 可以通过终端使用 git --version来查看是否安装好了git 如果显示了版本信息&#xff0c;说明已经安装好了git&#xff0c;这时候我们就可以进入我们想要clone到问目标文件夹 …

数据库开启远程连接

服务器端添加一个允许远程连接的root用户: mysql -u root -p create user root192.168.10.20 identified by admin; //创建一个192.168.10.20地址远程连接的root用户 grant all privileges on *.* to root192.168.10.20; //赋予远程root用户所有的权…

【计算机毕业设计】springboot河北任丘非物质文化遗产数字化传承

当今社会进入了科技进步、经济社会快速发展的新时代。国际信息和学术交流也不断加强&#xff0c; 计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统购物方式采取了人工的管理方法&#xff0c;但这种管理方法存在着许…

TypeScript学习日志-第二十一天(声明文件d.ts)

声明文件d.ts 在使用 Typescript 并使用第三方库 的时候 我们会发现会有很多的提示或补全&#xff0c;这都是声明文件起的作用&#xff0c;但是有写冷门的第三方库是没有声明文件的&#xff0c;这时候引用就会报错&#xff0c;我们就使用 express 库作为例子来展示一下&#x…

视频怎么打水印?6个软件教你快速进行视频水印制作

视频怎么打水印&#xff1f;6个软件教你快速进行视频水印制作 添加水印是保护视频版权、提升视频专业性的重要手段之一。以下是六款软件&#xff0c;它们能够帮助你快速进行视频水印制作&#xff0c;让你的视频更具个性和专业性&#xff1a; 1.迅捷视频剪辑软件&#xff1a;…

Docker快速搭建NAS服务——FileBrowser

Docker快速搭建NAS服务——FileBrowser 文章目录 前言FileBrowser的搭建docker-compose文件编写运行及访问 总结 前言 本文主要讲解如何使用docker在本地快速搭建NAS服务&#xff0c;这里主要写如下两种&#xff1a; FileBrowser1&#xff1a;是一个开源的Web文件管理器&…

TikTok自动评论、回复的脚本怎么制作?

在当今数字化的时代&#xff0c;社交媒体平台如TikTok已经成为人们日常生活的一部分&#xff0c;为了更有效地在TikTok上进行营销或互动&#xff0c;许多用户和企业开始寻找自动化工具&#xff0c;如自动评论和回复的脚本&#xff0c;以节省时间并提高效率。 本文将科普如何制…

5.11学习记录

20长安杯部分 检材 1 的操作系统版本 CentOS Linux 7.6.1810 (Core) 检材 1 中&#xff0c;操作系统的内核版本是 3.10.0-957.el7.x86_64 检材 1 中磁盘包含一个 LVM 逻辑卷&#xff0c;该 LVM 开始的逻辑区块地址&#xff08;LBA&#xff09;是 2099200 物理卷&#xff…

【福利来袭】免费领取量化交易软件,轻松炒股!

随着科技的发展和信息的普及&#xff0c;量化交易逐渐成为投资者们提高投资效率和盈利能力的重要工具。为了让更多的投资者能够轻松参与量化交易&#xff0c;让投资者能够更加便捷地进行炒股。本文将详细介绍两款免费量化交易软件&#xff0c;帮助投资者更好地了解和选择适合自…

Linux的编译器

程序编译的过程 程序的编译过程是将源代码转换为可执行文件的一系列步骤。这个过程涉及多个阶段&#xff0c;主要包括预处理、编译、汇编和链接。下面详细介绍每个阶段&#xff1a; 1. 预处理&#xff08;Preprocessing&#xff09; 在实际编译之前&#xff0c;源代码文件首…

vs2019 里 C++ 20规范的 string 类的源码注释

&#xff08;1&#xff09;读源码&#xff0c;可以让我们更好的使用这个类&#xff0c;掌握这个类&#xff0c;知道咱们使用了库代码以后&#xff0c;程序大致具体是怎么执行的。而不用担心程序出不知名的意外的问题。也便于随后的代码调试。 string 类实际是 库中 basic_strin…

STC8增强型单片机开发【定时器Timer⭐】

目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中&#xff0c;定时器&#xff08;Timer&#xff09;是一个极其重要的组件&#xff0c;它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…

【机器学习】逻辑化讲清PCA主成分分析

碎碎念&#xff1a;小编去年数学建模比赛的时候真的理解不了主成分分析中的“主成分”的概念&#xff01;&#xff01;但是&#xff0c;时隔两年&#xff0c;在机器学习领域我又行了&#xff0c;终于搞明白了&#xff01;且看正文&#xff01;再分享一个今天听到的播客中非常触…

ICode国际青少年编程竞赛- Python-4级训练场-绿色能量1

ICode国际青少年编程竞赛- Python-4级训练场-绿色能量1 1、 Dev.step(3) Dev.turnLeft() Dev.step(3) Spaceship.step(4) Spaceship.turnRight() Spaceship.step(4) Dev.step(3) while Item[1].y ! Dev.y:wait()2、 Dev.step(4) while Item[0].x ! Dev.x:wait() Dev.turnLe…