跳到主要内容
基于Canvas和Web Audio API的交互式烟花动画网页游戏 | 极客日志
Python
基于Canvas和Web Audio API的交互式烟花动画网页游戏 > 一个基于 Canvas 和 Web Audio API 的交互式烟花动画网页 * * 目录 整体架构 HTML 结构 CSS 样式 JavaScript 核心模块 用户交互 性能优化 iOS 适配 文件依赖 * * 一、整体架构 * * 二、HTML 结构部分 1\. 头部元信息 **说明:** 设置字符编码为 UTF-8 页面标题显示新年祝福 viewport-fit=cover 适配 iP…
剑仙 发布于 2026/4/7 更新于 2026/5/22 22K 浏览
一个基于 Canvas 和 Web Audio API 的交互式烟花动画网页
目录
整体架构
HTML 结构
CSS 样式
JavaScript 核心模块
用户交互
性能优化
iOS 适配
文件依赖
一、整体架构
┌─────────────────────────────────────────────────────────────┐ │ HTML 结构 │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ SVG 图标 │ │ Canvas 容器 │ │ 控制面板/菜单 │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ CSS 样式 │ ├─────────────────────────────────────────────────────────────┤ │ JavaScript 逻辑 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │ │ FireworkSound│ │ Store │ │ Shell/Star/Spark │ │ │ │ 音效模块 │ │ 状态管理 │ │ 粒子系统 │ │ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ └─────────────────────────────────────────────────────────────┘
二、HTML 结构部分
1. 头部元信息
<metacharset="UTF-8 "><title>2026 新年快乐!万事如意!</title><metaname="viewport"content ="width =device-width , initial-scale =1 , maximum-scale =1 , user-scalable=no, viewport-fit=cover">
说明:
设置字符编码为 UTF-8
页面标题显示新年祝福
viewport-fit=cover 适配 iPhone X 系列刘海屏
禁用用户缩放,防止误操作
2. iOS PWA 支持 <metaname ="apple-mobile-web-app-capable" content="yes" ><metaname="apple-mobile-web-app-status-bar-style" content="black-translucent" ><metaname="apple-mobile-web-app-title" content="烟花盛宴" ><linkrel="apple-touch-icon" href="..." ><linkrel="manifest" href="data:application/json;base64,..." >
支持添加到 iOS 主屏幕
半透明状态栏适配刘海屏
内联 PWA manifest(Base64 编码)
3. SVG 图标定义 <svgxmlns="http://www.w3.org/2000/svg" ><symbolid="icon-play" viewBox="0 0 24 24" ><pathd="M8 5v14l11-7z" /></symbol><symbolid="icon-pause" viewBox="0 0 24 24" ><pathd="M6 19h4V5H6v14zm8-14v14h4V5h-4z" /></symbol><symbolid="icon-close" viewBox="0 0 24 24" >...</symbol><symbolid="icon-settings" viewBox="0 0 24 24" >...</symbol><symbolid="icon-shutter-fast" viewBox="0 0 24 24" >...</symbol><symbolid="icon-shutter-slow" viewBox="0 0 24 24" >...</symbol></svg>
使用 SVG symbol 定义可复用的图标
通过 <use href="#icon-xxx"> 引用
优点:矢量图标、可缩放、体积小
4. Canvas 画布容器 <divid="canvas-container"><canvasid="trails-canvas"></canvas > <canvasid="main-canvas"></canvas > </div >
层级 作用 渲染方式 trails-canvas绘制烟花拖尾效果 渐变透明覆盖实现残影 main-canvas绘制当前帧的粒子和UI元素 每帧清空重绘
5. 控制面板 <divid="controls" ><divid="pause-btn" class="btn" ><svgfill="white" width="24" height="24" ><usehref="#icon-pause" ></use></svg></div><divid="shutter-btn" class="btn" ><svgfill="white" width="24" height="24" ><usehref="#icon-shutter-slow" ></use></svg></div><divid="settings-btn" class="btn" ><svgfill="white" width="24" height="24" ><usehref="#icon-settings" ></use></svg></div></div>
暂停/播放 :控制动画运行
快门模式 :切换长曝光效果
设置 :打开设置菜单
6. 设置菜单 <divid="menu "><divid="menu__header">设置</div ><form ><divclass="form -option form -option --select "><label >烟花类型</label ><selectid="shell-type"></select ></div ><divclass="form -option form -option --select "><label >烟花大小</label ><selectid="shell-size"></select ></div ><divclass="form -option form -option --checkbox "><label ><inputid="auto-launch"type="checkbox"/><span >自动发射</span ></label ></div ><divclass="form -option form -option --checkbox "><label ><inputid="finale-mode"type="checkbox"/><span >终场模式</span ></label ></div ><divclass="form -option form -option --checkbox "><label ><inputid="hide-controls"type="checkbox"/><span >隐藏控制</span ></label ></div ><divclass="form -option form -option --checkbox "><label ><inputid="sound-enabled"type="checkbox"checked/><span >声音效果</span ></label ></div ><divclass="form -option form -option --select "><label >声音类型</label ><selectid="sound-type"></select ></div ></form ></div >
7. 首次交互提示(iOS 适配) <divid="audio -prompt"><divid="audio -prompt__icon">🎆</div ><divid="audio -prompt__text">点击屏幕开始烟花盛宴</div ><divid="audio -prompt__hint">Tap to start fireworks</div ></div >
iOS Safari 要求用户交互后才能播放音频
此提示引导用户点击以解锁音频
三、CSS 样式部分
1. 全局样式与触摸优化 *{position : relative;box-sizing : border-box;-webkit-tap-highlight-color : transparent;-webkit-touch-callout: none;-webkit-user-select : none;user-select : none;touch-action : manipulation;}html {background-color : #000 ;}body {overflow : hidden;color :rgba (255 , 255 , 255 , 0.5 );font-family :"Russo One" , arial, sans-serif;overscroll-behavior : none;padding :env (safe-area-inset-top)env (safe-area-inset-right)env (safe-area-inset-bottom)env (safe-area-inset-left);}
2. 混合模式 #canvas-container canvas {position : absolute;mix-blend-mode : lighten;}
lighten 混合模式使亮色粒子在黑色背景上更加突出
多个亮色叠加会产生更亮的效果
3. 动画过渡 .hide {opacity : 0 ;visibility : hidden;transition : opacity 0.3s , visibility 0.3s ;}
使用 opacity + visibility 组合实现平滑的显示/隐藏动画
visibility 延迟隐藏,避免点击穿透
4. 音频提示动画 #audio-prompt__icon {font-size : 80px ;animation : pulse 1.5s ease-in-out infinite;}@keyframes pulse{0% , 100% {transform :scale (1 );opacity : 1 ;}50% {transform :scale (1.1 );opacity : 0.7 ;}}
四、JavaScript 核心模块
1. FireworkSound 音效模块 const FireworkSound ={ctx: null,// AudioContext 实例enabled: true ,// 是否启用声音soundType: 'realistic' ,// 当前声音类型isUnlocked: false ,// iOS 音频解锁状态init(){// 初始化 Web Audio APIthis .ctx =new(window.AudioContext | | window.webkitAudioContext)();},unlock(){// iOS 音频解锁:播放静音缓冲区if (this.isUnlocked)returntrue;if (this.ctx.state ==='suspended' ){this.ctx.resume();}const buffer =this.ctx.createBuffer(1 ,1 ,22050 );const source =this.ctx.createBufferSource(); source.buffer = buffer; source.connect(this.ctx.destination); source.start(0 );this.isUnlocked =true ;},playLaunch(){/* 发射音效 */ },playBurst(size){/* 爆炸音效 */ }};
组件 作用 示例用途 AudioContext音频上下文,管理所有音频节点 new AudioContext()OscillatorNode振荡器,生成周期性波形 正弦波、方波、锯齿波 GainNode增益节点,控制音量 音量包络、淡入淡出 BiquadFilter双二阶滤波器 低通、高通、带通滤波 BufferSource缓冲源,播放采样数据 白噪声、爆炸声
playRealisticBurst(size =1 ){// 1 . 生成白噪声缓冲区const duration =0.6 + size *0.2 ;const bufferSize =this.ctx .sampleRate * duration;const buffer =this.ctx .createBuffer (1 , bufferSize,this.ctx .sampleRate );const data = buffer.getChannelData (0 );for(let i =0 ; i < bufferSize; i ++){const t = i / bufferSize;const noise = Math.random ()*2 -1 ;// 随机噪声 [-1, 1] const envelope = Math.pow (1 - t,1.5 );// 指数衰减包络 data[i] = noise * envelope;}// 2 . 创建低通滤波器模拟爆炸闷响const filter =this.ctx .createBiquadFilter (); filter .type ='lowpass'; filter .frequency .setValueAtTime (3000 * size,this.ctx .currentTime ); filter .frequency .exponentialRampToValueAtTime (200 ,this.ctx .currentTime + duration *0.7 );// 3 . 音量包络:快速起音,缓慢衰减const gain =this.ctx .createGain (); gain.gain .setValueAtTime (0 ,this.ctx .currentTime ); gain.gain .linearRampToValueAtTime (volume,this.ctx .currentTime +0.02 );// 起音 20ms gain.gain .exponentialRampToValueAtTime (0.01 ,this.ctx .currentTime + duration);// 衰减// 4 . 连接节点并播放 noise.connect (filter ); filter .connect (gain); gain.connect (this.ctx .destination ); noise.start (this.ctx .currentTime );}
类型 中文名 特点 realistic 真实 白噪声 + 低频冲击 + 噼啪声 cinematic 电影感 深沉隆隆声 + 闪烁火花 classic 经典烟花 清脆爆破声 retro 复古8位 方波游戏机风格 soft 柔和轻柔 正弦波轻柔音效 synth 电子合成 多振荡器合成器 drum 鼓点贝斯 底鼓 + 军鼓 + 踩镲 whistle 哨子爆破 口哨式发射 + 爆破
2. Store 状态管理 const store ={_listeners: newSet(),// 订阅者集合state: {paused: false ,longExposure: false ,menuOpen: false ,config: {shell: 'Random' ,size: '3' ,autoLaunch: true ,finale: false ,hideControls: false ,soundEnabled: true ,soundType: 'realistic' }},setState(nextState){this.state = Object .assign({},this.state, nextState);this._dispatch();// 通知所有订阅者this.persist();// 持久化到 localStorage},subscribe(listener){this._listeners.add(listener);return ()=>this._listeners.delete(listener);},load(){// 从 localStorage 加载配置},persist(){// 保存配置到 localStorage}};
用户操作 → updateConfig () → store.setState () → _dispatch () → renderApp () ↓ 更新 DOM
3. Shell 烟花类 classShell{constructor(options){this.size = options.size;// 爆炸半径this.starCount = options.starCount;// 星星数量this.starLife = options.starLife;// 星星寿命(毫秒)this.color = options.color;// 颜色this.glitter = options.glitter;// 闪光类型this.pistil = options.pistil;// 是否有花心this.ring = options.ring;// 是否环形}launch(position, launchHeight){// 1 . 计算发射位置和目标高度const launchX = position *(width - hpad *2 )+ hpad;const launchY = height;const burstY = minHeight -(launchHeight *(minHeight - vpad));const launchDistance = launchY - burstY;// 2 . 计算发射速度(抛物线运动近似)const launchVelocity = Math .pow(launchDistance *0.04 ,0.64 );// 3 . 创建彗星(上升的火球)const comet = Star .add( launchX, launchY,this.color | |COLOR .White , Math .PI ,// 向上发射 launchVelocity, launchVelocity *400 // 寿命); comet.heavy =true;/ / 减少空气阻力 comet.sparkFreq =16;/ / 火花频率/ / 4. 设置死亡回调为爆炸 comet.onDeath=()=>this.burst(comet.x, comet.y);/ / 5. 播放发射音效 FireworkSound.playLaunch();}burst(x, y){/ / 1. 计算爆炸速度const speed =this.size / 96 ;// 2 . 创建粒子弧(圆形分布)createParticleArc(0 ,PI_2 ,this.starCount,1 ,(angle)=>{const star = Star .add( x, y,this.color, angle, Math .pow(Math .random(),0.45 )* speed,// 非线性速度分布this.starLife + Math .random()*this.starLife *this.starLifeVariation ); star.onDeath = onDeath;// 设置死亡效果});// 3 . 播放爆炸音效const soundSize = Math .min(2 ,this.size /200 ); FireworkSound .playBurst(soundSize);}}
类型 中文名 特点 视觉效果 Crysanthemum 菊花 经典球形爆炸,密集粒子 大型圆形散开 Palm 棕榈 垂直拖尾,像棕榈树 向下垂落 Ring 圆环 环形爆炸 空心圆环 Crossette 十字 爆炸后分裂成四个小星星 二次爆炸 Floral 花簇 小型二次爆炸 多层绽放 Crackle 噼啪 金色火花,噼啪声 金色闪烁 Willow 垂柳 长时间下坠的火花 长尾下垂 Falling Leaves 落叶 飘落的金色粒子 缓慢飘落 Horse Tail 马尾 水平拖尾 横向展开
4. Star 星星粒子 const Star ={drawWidth:3 ,airDrag:0.98 ,airDragHeavy:0.992 ,active:createParticleCollection (),// 按颜色分组的活跃粒子_pool:[],// 对象池,复用粒子对象add (x, y, color, angle, speed, life, speedOffX, speedOffY){// 从池中获取或创建新对象const instance =this._pool.pop ()||{}; instance.x = x ; instance.y = y ; instance.prevX = x ;// 上一帧位置(用于绘制轨迹) instance.prevY = y ; instance.color = color ; instance.speedX = Math.sin (angle)* speed +(speedOffX ||0 ); instance.speedY = Math.cos (angle)* speed +(speedOffY ||0 ); instance.life = life; instance.sparkFreq =0 ;// 火花频率this.active [color] .push (instance);return instance;},returnInstance(instance){ instance.onDeath && instance.onDeath (instance); instance.onDeath =null;this._pool.push (instance);// 回收到池中}};
避免频繁创建/销毁对象
减少垃圾回收(GC)压力
提高大量粒子时的性能
5. Spark 火花粒子 const Spark ={drawWidth:0.75 ,airDrag:0.9 ,active:createParticleCollection (),_pool:[],add (x, y, color, angle, speed, life){const instance =this._pool .pop ()||{}; instance.x = x ; instance.y = y ; instance.prevX = x ; instance.prevY = y ; instance.color = color ; instance.speedX = Math.sin (angle)* speed; instance.speedY = Math.cos (angle)* speed; instance.life = life;this.active [color] .push (instance);return instance;}};
特性 Star Spark 大小 3px 0.75px 空气阻力 0.98 0.9 用途 主要烟花粒子 闪光效果 寿命 较长 较短
6. 渲染循环 functionupdate(frameTime, lag){if (!canInteract())return ;const timeStep = frameTime * simSpeed;const speed = simSpeed * lag;// 1 . 更新全局状态(自动发射等)updateGlobals(timeStep, lag);// 2 . 计算物理参数const starDrag =1 -(1 - Star.airDrag)* speed;// 空气阻力系数const sparkDrag =1 -(1 - Spark.airDrag)* speed;const gAcc = timeStep /1000 *GRAVITY;// 重力加速度// 3 . 更新所有粒子COLOR_CODES_W_INVIS.forEach(color=> {// 更新星星 Star.active[color].forEach((star, i, stars)=>{ star.life -= timeStep;if (star.life <=0 ){ stars.splice(i,1 ); Star.returnInstance(star);}else {// 保存上一帧位置 star.prevX = star.x; star.prevY = star.y;// 物理更新 star.x += star.speedX * speed; star.y += star.speedY * speed; star.speedX *= starDrag; star.speedY *= starDrag; star.speedY += gAcc;// 重力// 旋转效果if (star.spinRadius){ star.spinAngle += star.spinSpeed * speed; star.x += Math.sin(star.spinAngle)* star.spinRadius * speed; star.y += Math.cos(star.spinAngle)* star.spinRadius * speed;}// 火花效果if (star.sparkFreq){ star.sparkTimer -= timeStep;while (star.sparkTimer <0 ){ star.sparkTimer += star.sparkFreq; Spark.add(star.x, star.y, star.sparkColor,...);}}}});// 更新火花 Spark.active[color].forEach((spark, i, sparks)=>{// 类似星星的物理更新...});});// 4 . 渲染render(speed);}
7. 渲染函数 functionrender(speed){const{ dpr, width, height }= mainStage;const trailsCtx = trailsStage.ctx;const mainCtx = mainStage.ctx;// 1 . 更新天空颜色colorSky(speed);// 2 . 设置变换 trailsCtx.scale(dpr, dpr); mainCtx.scale(dpr, dpr);// 3 . 绘制拖尾效果(渐变黑色覆盖) trailsCtx.globalCompositeOperation ='source-over' ; trailsCtx.fillStyle =`rgba(0, 0, 0, ${longExposure ?0.0025:0.1* speed})` ; trailsCtx.fillRect(0 ,0 , width, height);// 4 . 设置混合模式 trailsCtx.globalCompositeOperation ='lighten' ;// 5 . 清空主画布 mainCtx.clearRect(0 ,0 , width, height);// 6 . 绘制爆炸闪光while (BurstFlash.active.length){const bf = BurstFlash.active.pop();const gradient = trailsCtx.createRadialGradient(bf.x, bf.y,0 , bf.x, bf.y, bf.radius); gradient.addColorStop(0.05 ,'white' ); gradient.addColorStop(0.25 ,'rgba(255, 160, 20, 0.2)' ); gradient.addColorStop(1 ,'rgba(255, 160, 20, 0)' ); trailsCtx.fillStyle = gradient; trailsCtx.fillRect(bf.x - bf.radius, bf.y - bf.radius, bf.radius *2 , bf.radius *2 );}// 7 . 绘制星星轨迹 trailsCtx.lineWidth = Star.drawWidth; trailsCtx.lineCap ='round' ;COLOR_CODES.forEach(color=> {const stars = Star.active[color]; trailsCtx.strokeStyle = color; trailsCtx.beginPath(); stars.forEach(star=> { trailsCtx.moveTo(star.x, star.y); trailsCtx.lineTo(star.prevX, star.prevY);}); trailsCtx.stroke();});// 8 . 绘制火花 trailsCtx.lineWidth = Spark.drawWidth; trailsCtx.lineCap ='butt' ;// 类似星星的绘制...// 9 . 绘制速度条if (speedBarOpacity){ mainCtx.globalAlpha = speedBarOpacity; mainCtx.fillStyle =COLOR.Blue; mainCtx.fillRect(0 , height -6 , width * simSpeed,6 ); mainCtx.globalAlpha =1 ;}// 10 . 重置变换 trailsCtx.resetTransform(); mainCtx.resetTransform();}
8. 天空颜色计算 const currentSkyColor ={r:0 ,g:0 ,b:0 };const targetSkyColor ={r:0 ,g:0 ,b:0 };functioncolorSky(speed){const maxSkySaturation =30 ;// 最大天空饱和度const maxStarCount =500 ;// 达到最大亮度所需的星星数量let totalStarCount =0 ; targetSkyColor.r =0 ; targetSkyColor.g =0 ; targetSkyColor.b =0 ;// 累计所有颜色的亮度COLOR_CODES.forEach(color=> {const tuple =COLOR_TUPLES[color];const count = Star.active[color].length; totalStarCount += count; targetSkyColor.r += tuple.r * count; targetSkyColor.g += tuple.g * count; targetSkyColor.b += tuple.b * count;});// 非线性映射,模拟人眼感知const intensity = Math.pow(Math.min(1 , totalStarCount / maxStarCount),0 .3 );// 归一化并应用强度const maxColorComponent = Math.max(1 , targetSkyColor.r, targetSkyColor.g, targetSkyColor.b); targetSkyColor.r = targetSkyColor.r / maxColorComponent * maxSkySaturation * intensity; targetSkyColor.g = targetSkyColor.g / maxColorComponent * maxSkySaturation * intensity; targetSkyColor.b = targetSkyColor.b / maxColorComponent * maxSkySaturation * intensity;// 平滑过渡const colorChange =10 ; currentSkyColor.r +=(targetSkyColor.r - currentSkyColor.r)/ colorChange * speed; currentSkyColor.g +=(targetSkyColor.g - currentSkyColor.g)/ colorChange * speed; currentSkyColor.b +=(targetSkyColor.b - currentSkyColor.b)/ colorChange * speed;// 应用到背景 appNodes.canvasContainer.style.backgroundColor =`rgb(${currentSkyColor.r |0}, ${currentSkyColor.g |0}, ${currentSkyColor.b |0})` ;}
五、用户交互
1. 点击发射 functionhandlePointerStart(event ){ activePointerCount++; FireworkSound.unlock();// iOS 音频解锁 FireworkSound.resume ();const btnSize =44 ;// 点击顶部按钮区域if (event .y < btnSize){if (event .x < btnSize){togglePause();return ;}if (event .x > mainStage.width/2 - btnSize/2& & event .x < mainStage.width/2 + btnSize/2 ){toggleLongExposure();return ;}if (event .x > mainStage.width - btnSize){toggleMenu();return ;}}// 点击画布发射烟花if (!canInteract())return ;if (updateSpeedFromEvent(event )){ isUpdatingSpeed =true ;}elseif (event .onCanvas){launchShellFromConfig(event );}}
2. 键盘快捷键 functionhandleKeydown (event){if (event.keyCode ===80 )togglePause ();
3. 自动发射序列 functionstartSequence(){if (isFirstSeq){ isFirstSeq =false;const shell =newShell(crysanthemumShell(shellSizeSelector())); shell.launch(0 .5 ,0 .5 );// 首发居中return2400;}if (finaleSelector()){// 终场模式:快速连续发射seqRandomShell();if (currentFinaleCount < finaleCount){ currentFinaleCount++;return170;// 170ms 间隔}else { currentFinaleCount =0 ;return6000;// 暂停 6 秒}}// 随机选择发射模式const rand = Math.random();if (rand <0 .2 )returnseqSmallBarrage();// 小型连发if (rand <0 .6 )returnseqRandomShell();// 单发if (rand <0 .8 )returnseqTwoRandom();// 双发returnseqTriple();// 三发}
六、性能优化要点 优化技术 说明 效果 对象池 复用 Star/Spark 对象 减少 GC 压力 颜色分组 按颜色分组批量渲染 减少 Canvas 状态切换 双缓冲 trails-canvas 保留历史轨迹 实现拖尾效果 requestAnimationFrame 与屏幕刷新同步 流畅动画 空气阻力模拟 粒子速度衰减 自然消散效果 设备像素比适配 scale(dpr, dpr)高清显示
七、iOS 适配
1. Meta 标签优化 <metaname="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"><metaname="apple-mobile-web-app-capable"content="yes"><metaname="apple-mobile-web-app-status-bar-style"content="black-translucent"><metaname="apple-mobile-web-app-title"content="烟花盛宴"><metaname="format-detection"content="telephone=no"><linkrel="manifest"href="data:application/json;base64,...">
2. CSS 触摸优化 *{-webkit-tap-highlight-color : transparent;-webkit-touch-callout: none;-webkit-user-select : none;touch-action : manipulation;}body {overscroll-behavior : none;padding :env (safe-area-inset-*);}
3. Web Audio 解锁 unlock (){if (this.isUnlocked)returntrue;
4. 手势防护 // 禁用 iOS 缩放手势 document.addEventListener('gesturestart' ,(e)=> e.preventDefault()); document.addEventListener('gesturechange' ,(e)=> e.preventDefault()); document.addEventListener('gestureend' ,(e)=> e.preventDefault());// 防止双击缩放let lastTouchEnd =0; document.addEventListener('touchend' ,(e)=>{const now = Date.now();if (now - lastTouchEnd <=300){ e.preventDefault();} lastTouchEnd = now;});
5. iOS 支持功能表 功能 状态 说明 添加到主屏幕 ✅ 支持全屏运行 声音播放 ✅ 用户交互后解锁 刘海屏适配 ✅ 安全区域 padding 禁用缩放 ✅ 手势防护 禁用橡皮筋效果 ✅ overscroll-behavior 触摸响应 ✅ Pointer Events
八、文件依赖
外部库 ├── fscreen@1 .0.1 .js - 全屏 API 兼容库 ├── Stage@0 .1.4 .js - Canvas 舞台管理 └── MyMath.js - 数学工具函数
本地文件
总结
视觉效果 :双层 Canvas 实现拖尾效果,混合模式增强亮度
音效系统 :8 种不同风格的音效,Web Audio API 实时生成
物理模拟 :重力、空气阻力、粒子生命周期
状态管理 :发布-订阅模式,localStorage 持久化
性能优化 :对象池、颜色分组、requestAnimationFrame
跨平台 :完整的 iOS/移动端适配
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online