用前端html如何实现2024烟花效果
用HTML、CSS和JavaScript编写的网页,主要用于展示“2024新年快乐!”的文字形式烟花效果。下面是对代码主要部分的分析:
HTML结构
- 包含三个
<canvas>元素,用于绘制动画。 - 引入百度统计的脚本。
CSS样式
- 设置
body的背景为黑色,并使得canvas元素绝对定位,覆盖整个页面。
JavaScript 功能
-
百度统计脚本:页面开始时引入了百度统计的脚本,用于网页访问数据分析。
-
获取URL参数:
GetRequest函数用于解析URL中的查询字符串参数。 -
烟花碎片(Shard)类:
- 每个
Shard代表烟花爆炸后的一个碎片。 - 包含碎片的位置、颜色、大小、速度等属性。
draw方法用于在canvas上绘制碎片。update方法用于更新碎片的位置和状态。
- 每个
-
火箭(Rocket)类:
- 表示发射的烟花火箭。
- 包含火箭的位置、速度、颜色等属性。
draw方法用于在canvas上绘制火箭。update方法用于更新火箭的位置。explode方法用于模拟火箭爆炸,生成多个Shard实例。
-
初始化和动画循环:
- 获取所有canvas元素和对应的2D渲染上下文。
- 根据屏幕大小调整字体大小,以适应屏幕宽度,并在一个
canvas上绘制“2024新年快乐!”文字。 - 通过读取绘制的文字的像素数据,确定烟花爆炸的目标位置。
- 使用
requestAnimationFrame创建动画循环,不断更新和绘制火箭和碎片,模拟烟花效果。
-
辅助函数:
lerp(线性插值函数):用于平滑地在两个值之间插值,常用于动画效果中。
-
执行流程:
-
页面加载完成后,动画循环开始运行。
-
每隔一定帧数,生成一个新的
Rocket实例,模拟火箭发射。 -
当火箭达到一定高度后,调用
explode方法,生成多个Shard实例,模拟烟花爆炸。 -
碎片根据预设的目标位置移动,最终形成“2024新年快乐!”的文字形状。
<!DOCTYPE html> <html lang="en"> <script>var _hmt = _hmt || [];(function () {var hm = document.createElement("script");hm.src = "https://hm.baidu.com/hm.js?c923daf3182a4b0ce01878475080aadc";var s = document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm, s);})(); </script><head><meta charset="UTF-8"><title>2024,新年快乐!</title> </head> <style>body {margin: 0;overflow: hidden;background: black;}canvas {position: absolute;} </style><body><canvas></canvas><canvas></canvas><canvas></canvas><script>function GetRequest() {var url = decodeURI(location.search); //获取url中"?"符后的字串var theRequest = new Object();if (url.indexOf("?") != -1) {var str = url.substr(1);strs = str.split("&");for (var i = 0; i < strs.length; i++) {theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);}}return theRequest;}class Shard {constructor(x, y, hue) {this.x = x;this.y = y;this.hue = hue;this.lightness = 50;this.size = 15 + Math.random() * 10;const angle = Math.random() * 2 * Math.PI;const blastSpeed = 1 + Math.random() * 6;this.xSpeed = Math.cos(angle) * blastSpeed;this.ySpeed = Math.sin(angle) * blastSpeed;this.target = getTarget();this.ttl = 100;this.timer = 0;}draw() {ctx2.fillStyle = `hsl(${this.hue}, 100%, ${this.lightness}%)`;ctx2.beginPath();ctx2.arc(this.x, this.y, this.size, 0, 2 * Math.PI);ctx2.closePath();ctx2.fill();}update() {if (this.target) {const dx = this.target.x - this.x;const dy = this.target.y - this.y;const dist = Math.sqrt(dx * dx + dy * dy);const a = Math.atan2(dy, dx);const tx = Math.cos(a) * 5;const ty = Math.sin(a) * 5;this.size = lerp(this.size, 1.5, 0.05);if (dist < 5) {this.lightness = lerp(this.lightness, 100, 0.01);this.xSpeed = this.ySpeed = 0;this.x = lerp(this.x, this.target.x + fidelity / 2, 0.05);this.y = lerp(this.y, this.target.y + fidelity / 2, 0.05);this.timer += 1;} elseif (dist < 10) {this.lightness = lerp(this.lightness, 100, 0.01);this.xSpeed = lerp(this.xSpeed, tx, 0.1);this.ySpeed = lerp(this.ySpeed, ty, 0.1);this.timer += 1;} else {this.xSpeed = lerp(this.xSpeed, tx, 0.02);this.ySpeed = lerp(this.ySpeed, ty, 0.02);}} else {this.ySpeed += 0.05;//this.xSpeed = lerp(this.xSpeed, 0, 0.1);this.size = lerp(this.size, 1, 0.05);if (this.y > c2.height) {shards.forEach((shard, idx) => {if (shard === this) {shards.splice(idx, 1);}});}}this.x = this.x + this.xSpeed;this.y = this.y + this.ySpeed;}}class Rocket {constructor() {const quarterW = c2.width / 4;this.x = quarterW + Math.random() * (c2.width - quarterW);this.y = c2.height - 15;this.angle = Math.random() * Math.PI / 4 - Math.PI / 6;this.blastSpeed = 6 + Math.random() * 7;this.shardCount = 15 + Math.floor(Math.random() * 15);this.xSpeed = Math.sin(this.angle) * this.blastSpeed;this.ySpeed = -Math.cos(this.angle) * this.blastSpeed;this.hue = Math.floor(Math.random() * 360);this.trail = [];}draw() {ctx2.save();ctx2.translate(this.x, this.y);ctx2.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2);ctx2.fillStyle = `hsl(${this.hue}, 100%, 50%)`;ctx2.fillRect(0, 0, 5, 15);ctx2.restore();}update() {this.x = this.x + this.xSpeed;this.y = this.y + this.ySpeed;this.ySpeed += 0.1;}explode() {for (let i = 0; i < 70; i++) {shards.push(new Shard(this.x, this.y, this.hue));}}}console.log(GetRequest('val').val)// INITIALIZATIONconst [c1, c2, c3] = document.querySelectorAll('canvas');const [ctx1, ctx2, ctx3] = [c1, c2, c3].map(c => c.getContext('2d'));let fontSize = 200;const rockets = [];const shards = [];const targets = [];const fidelity = 3;let counter = 0;c2.width = c3.width = window.innerWidth;c2.height = c3.height = window.innerHeight;ctx1.fillStyle = '#000';const text = '2024新年快乐!'let textWidth = 99999999;while (textWidth > window.innerWidth) {ctx1.font = `900 ${fontSize--}px Arial`;textWidth = ctx1.measureText(text).width;}c1.width = textWidth;c1.height = fontSize * 1.5;ctx1.font = `900 ${fontSize}px Arial`;ctx1.fillText(text, 0, fontSize);const imgData = ctx1.getImageData(0, 0, c1.width, c1.height);for (let i = 0, max = imgData.data.length; i < max; i += 4) {const alpha = imgData.data[i + 3];const x = Math.floor(i / 4) % imgData.width;const y = Math.floor(i / 4 / imgData.width);if (alpha && x % fidelity === 0 && y % fidelity === 0) {targets.push({ x, y });}}ctx3.fillStyle = '#FFF';ctx3.shadowColor = '#FFF';ctx3.shadowBlur = 25;// ANIMATION LOOP(function loop() {ctx2.fillStyle = "rgba(0, 0, 0, .1)";ctx2.fillRect(0, 0, c2.width, c2.height);//ctx2.clearRect(0, 0, c2.width, c2.height);counter += 1;if (counter % 15 === 0) {rockets.push(new Rocket());}rockets.forEach((r, i) => {r.draw();r.update();if (r.ySpeed > 0) {r.explode();rockets.splice(i, 1);}});shards.forEach((s, i) => {s.draw();s.update();if (s.timer >= s.ttl || s.lightness >= 99) {ctx3.fillRect(s.target.x, s.target.y, fidelity + 1, fidelity + 1);shards.splice(i, 1);}});requestAnimationFrame(loop);})();// HELPER FUNCTIONSconst lerp = (a, b, t) => Math.abs(b - a) > 0.1 ? a + t * (b - a) : b;function getTarget() {if (targets.length > 0) {const idx = Math.floor(Math.random() * targets.length);let { x, y } = targets[idx];targets.splice(idx, 1);x += c2.width / 2 - textWidth / 2;y += c2.height / 2 - fontSize / 2;return { x, y };}}</script></body></html>
步骤 1: 页面结构和引入脚本
-
HTML定义了三个
canvas元素用于绘制烟花动画。 -
引入百度统计脚本,用于收集页面访问数据。
-
步骤 2: 样式设置
-
页面背景设置为黑色,
canvas元素被设置为绝对定位,覆盖整个屏幕。 -
步骤 3: JavaScript 功能实现
3.1 获取URL参数
-
GetRequest函数解析当前URL的查询字符串,将参数保存在一个对象中返回。 -
3.2 定义烟花碎片(Shard)类
-
每个
Shard实例代表烟花爆炸后的一个碎片。 -
包含位置、颜色、大小、速度等属性。
-
draw方法用于绘制碎片。 -
update方法用于更新碎片的状态和位置,包括模拟重力影响和向目标位置移动。 -
3.3 定义火箭(Rocket)类
-
每个
Rocket实例代表一个发射的烟花火箭。 -
包含位置、速度、颜色等属性。
-
draw方法用于绘制火箭。 -
update方法用于更新火箭的位置,模拟火箭上升。 -
3.4 初始化和动画循环
-
初始化:根据屏幕大小调整字体大小,确保“2024新年快乐!”文字适应屏幕宽度,并在
canvas上绘制该文字。通过读取文字像素数据来确定烟花爆炸的目标位置。 -
动画循环:使用
requestAnimationFrame循环不断更新和绘制火箭和碎片,以及检测碎片是否达到目标位置或生命周期结束。 -
3.5 辅助函数
-
lerp函数:用于在两个数值之间进行线性插值,帮助平滑动画效果。 -
步骤 4: 执行动画
-
初始化画布:调整画布大小以适应窗口,绘制“2024新年快乐!”文字,并基于此文字的像素数据确定烟花目标位置。
-
启动动画循环:
- 每隔一定时间间隔,创建一个新的
Rocket实例,模拟火箭发射。 - 更新每个火箭的位置,当火箭达到一定高度时触发爆炸,生成多个
Shard实例。 - 更新每个
Shard的位置,使其朝目标位置移动。 - 当
Shard到达目标位置或生命周期结束时,从数组中移除。
- 每隔一定时间间隔,创建一个新的
-
渲染烟花效果:通过不断更新
canvas上的火箭和碎片位置,以及绘制这些元素,形成动态的烟花效果。碎片最终会根据预设的目标位置排列,形成“2024新年快乐!”的文字形状。 -
通过这些步骤,代码实现了一个视觉吸引的新年烟花祝福动画,既展示了编程技巧,也增添了节日气氛。
-
explode方法在火箭达到顶点时被调用,生成多个Shard实例。
-
相关文章:
用前端html如何实现2024烟花效果
用HTML、CSS和JavaScript编写的网页,主要用于展示“2024新年快乐!”的文字形式烟花效果。下面是对代码主要部分的分析: HTML结构 包含三个<canvas>元素,用于绘制动画。引入百度统计的脚本。 CSS样式 设置body的背景为黑…...
Redis应用-在用户数据里的应用
1.社区电商的业务闭环 接下来介绍的社区电商是以Redis作为主体技术、以MySQL和RocketMQ作为辅助技术实现的。 (1)社区电商运作模式 社区电商的关键点在于社区,而电商则是辅助性质(次要地位,流量变现)。社区可以分成很多种社区,比如美食社区、美妆社区、影评社区、妈妈社区…...
C++ 中面向对象编程如实现数据隐藏
在C中,面向对象编程(OOP)通过封装(Encapsulation)来实现数据隐藏。封装是OOP的一个核心概念,它允许将对象的属性和行为(即数据和方法)组合在一起,并对外隐藏对象的内部实…...
JavaEE 【知识改变命运】04 多线程(3)
文章目录 多线程带来的风险-线程安全线程不安全的举例分析产出线程安全的原因:1.线程是抢占式的2. 多线程修改同一个变量(程序的要求)3. 原子性4. 内存可见性5. 指令重排序 总结线程安全问题产生的原因解决线程安全问题1. synchronized关键字…...
gz中生成模型
生成模型 通过服务调用生成 还记得parameter_bridge 吗? 我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递(传感器数据)。之前的例子 另一个 parameter_bridge 实例用于服务桥接(动态生成模型…...
前端(Axios和Promis)
Promise 语法 <script>// 创建promise对象// 此函数需要再传入两个参数,都是函数类型let pnew Promise((resolve,reject)>{if(3>2){resolve({name:"李思蕾",age:23,地址:"河南省"});}else{reject("error");}});console.log(p);p.th…...
AI Agent:重塑业务流程自动化的未来力量(2/30)
《AI Agent:重塑业务流程自动化的未来力量》 摘要:整体思路是先介绍 AI Agent 的基本情况,再深入阐述其实现业务流程自动化的方法和在不同领域的应用,接着分析其价值和面临的挑战,最后得出结论,为读者全面…...
前端页面导出word
html-docx-js bug: vite使用html-docx.js会报错,点击下载上方文件替换即可 正文 npm install html-docx-js -S npm install file-saver -S<template><div id"managerReport">word内容......</div> </template><script>&l…...
【考前预习】1.计算机网络概述
往期推荐 子网掩码、网络地址、广播地址、子网划分及计算-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解,史上最全】-CSDN博客 浅学React和JSX-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生 serverless-CSDN博客 浅谈维度建模、数据分析…...
ubuntu20.04复现 Leg-KILO
这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录,例如 /opt/opencv-3.2:出错: 使用多线程编译错误1: stdlib.h: 没有那个文件或目录错误2:er…...
Ensembl数据库下载参考基因组(常见模式植物)bioinfomatics 工具37
拟南芥参考基因组_拟南芥数据库-CSDN博客 1 Ensembl数据库网址 http://plants.ensembl.org/index.html #官网 如拟南芥等 那么问题来了,基因组fa文件和gff文件在哪里? 2 参考案例 拟南芥基因组fa在这里 注释gff文件在这里...
简单介绍web开发和HTML CSS_web网站开发流程
一、Web 开发:探索互联网世界的基石 1.1 什么是 Web 开发 Web 开发,简单来说,就是构建能够通过浏览器访问的网站的过程。Web 代表着全球广域网,也就是我们熟知的万维网(www),它连接着世界各地的…...
Docker 中使用 PHP 通过 Canal 同步 Mysql 数据到 ElasticSearch
一、Mysql 的安装和配置 1.使用 docker 安装 mysql,并且映射端口和 root 账号的密码 # 获取镜像 docker pull mysql:8.0.40-debian# 查看镜像是否下载成功 docker images# 运行msyql镜像 docker run -d -p 3388:3306 --name super-mysql -e MYSQL_ROOT_PASSWORD12…...
数据结构之五:排序
void*类型的实现:排序(void*类型)-CSDN博客 一、插入排序 1、直接插入排序 思想:把待排序的数据逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。 单趟&#x…...
科研绘图系列:R语言绘制热图和散点图以及箱线图(pheatmap, scatterplot boxplot)
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载图1图2图3系统信息参考介绍 R语言绘制热图和散点图以及箱线图(pheatmap, scatterplot & boxplot) 加载R包 library(magrittr) library(dplyr) library(ve…...
基于 webRTC Vue 的局域网 文件传输工具
文件传输工具,匿名加密,只需访问网页,即可连接到其他设备,基于 webRTC 和 Vue.js coturn TURN 服务器 docker pull coturn/coturn docker run -d --networkhost \-v $(pwd)/my.conf:/etc/coturn/turnserver.conf \coturn/coturn…...
LeetCode 718. 最长重复子数组 java题解
https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ 动态规划 class Solution {public int findLength(int[] nums1, int[] nums2) {int len1nums1.length,len2nums2.length;int[][] dpnew int[len11][len21];dp[0][0]0;//没有意义,…...
算法知识-15-深搜
一、概念 深度优先搜索(Deep First Search, DFS)是一种用于遍历或搜索树或图的算法。这种策略沿着树的深度遍历树的节点,尽可能深地搜索树的分支。 二、关键步骤 选择起点:根据题目要求,选择一个或多个节点作为搜索…...
区块链dapp 开发详解(VUE3.0)
1、安装metamask 插件。 2、使用封装的工具包: wagmi . 3、 wagmi 操作手册地址:connect | Wagmi 4、注意事项: 因为最初是react 版本,所以在VUE版的官方文档有很多地方在 import 用的是 wagmi,需要改为 wagmi/vue 。 连接成功后打印的内容如下&…...
Plugin [id: ‘flutter‘] was not found in any of the following sources解决方法
文章目录 错误描述解决方法修正方案:继续使用 apply from修正后的 build.gradle说明警告的处理进一步验证 错误描述 Plugin [id: ‘flutter’] was not found in any of the following sources: Gradle Core Plugins (not a core plugin, please see https://docs…...
【Blender进阶】VSCode调试大型项目:从模块导入到参数解析的实战避坑指南
1. 为什么需要VSCode调试Blender大型项目 当你刚开始接触Blender脚本开发时,可能习惯直接在Blender内置的文本编辑器中编写和测试代码。这种方式对于简单的单文件脚本还算方便,但随着项目规模扩大,你会遇到几个明显的痛点: 首先&a…...
Kettle新手必看:从零开始安装配置Pentaho Data Integration(附MySQL驱动避坑指南)
Kettle实战入门:从零搭建ETL开发环境与MySQL连接全攻略 开篇:为什么选择Kettle作为你的第一个ETL工具? 第一次接触数据集成领域时,面对五花八门的ETL工具列表,很多开发者都会感到无从下手。作为一个从传统数据库管理…...
LS-Dyna模态分析实战:从模型构建到结果解读的全流程指南
1. 认识LS-Dyna模态分析:为什么它值得掌握 我第一次接触LS-Dyna模态分析是在一个汽车零部件振动问题排查项目中。当时客户抱怨某款发动机支架在特定转速下会出现异常噪音,我们团队花了三天时间都没找到症结所在。直到用LS-Dyna做了模态分析,才…...
OpenClaw云端体验方案:星图GPU一键部署Qwen3.5-9B镜像
OpenClaw云端体验方案:星图GPU一键部署Qwen3.5-9B镜像 1. 为什么选择云端体验OpenClaw 第一次接触OpenClaw时,我被它的自动化能力深深吸引,但本地安装过程却让我这个非专业开发者望而却步。记得当时在macOS上折腾了整整一个下午,…...
Qwen2.5-1.5B效果展示:金融术语解释+财报摘要生成准确率实测
Qwen2.5-1.5B效果展示:金融术语解释财报摘要生成准确率实测 1. 测试背景与目的 在金融领域,准确理解专业术语和快速分析财务报告是两项核心需求。传统方式需要专业人士花费大量时间进行解释和分析,而AI模型的出现让自动化处理成为可能。 本…...
PDF-Extract-Kit-1.0精彩案例:IEEE论文PDF中LaTeX公式无损提取演示
PDF-Extract-Kit-1.0精彩案例:IEEE论文PDF中LaTeX公式无损提取演示 1. 引言:当学术研究遇上PDF公式提取难题 如果你经常需要阅读或处理学术论文,尤其是IEEE这类技术文档,一定遇到过这样的烦恼:看到一篇论文里的公式非…...
Nunchaku-flux-1-dev在网络安全领域的应用:威胁检测与防御
Nunchaku-flux-1-dev在网络安全领域的应用:威胁检测与防御 1. 引言 网络安全问题越来越复杂,传统的防护手段常常力不从心。每天都有新的攻击手法出现,企业安全团队疲于应对。有没有一种更智能的方式,能够自动识别威胁、快速响应…...
用ESP32-S3做个桌面小玩意:语音助手、GIF时钟和网络摄像头三合一(附开源代码与避坑指南)
ESP32-S3三合一桌面终端:从零构建智能语音助手、动态时钟与摄像监控系统 引言:当极客精神遇见桌面美学 在创客圈里流传着一句话:"如果你桌面上没有至少三个正在吃灰的开发板,说明你不够极客。"而今天我们要做的…...
HC32F460串口DMA发送中断接收避坑指南:静电干扰、丢字节问题与中断配置详解
HC32F460串口通信实战:DMA发送与中断接收的深度优化指南 在华大HC32F460系列MCU的实际应用中,串口通信作为最基础也最关键的通信接口之一,其稳定性和效率直接影响整个系统的可靠性。不同于STM32等传统MCU的固定中断映射机制,HC32F…...
Kali与编程・暴力破解・大白话版(超好懂)
大家好,我是 Kali 与编程讲师老 K,B 站和网易云课堂讲师,致力于帮助小白轻松学会 Kali 与编程,接下来你将搞懂什么是《暴力破解》。 暴力破解,说白了就是用程序自动不停地试密码,一个一个试,直…...
