跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
JavaScript大前端算法

基于 Canvas 和 Web Audio API 的交互式烟花动画实现

基于 Canvas 和 Web Audio API 构建交互式烟花动画,采用双层画布渲染拖尾效果与混合模式增强亮度。核心模块包含音效合成、状态管理及粒子物理系统,支持重力、空气阻力模拟。通过对象池优化性能,适配 iOS 刘海屏及触摸交互,实现全屏 PWA 体验。

CloudNative发布于 2026/3/23更新于 2026/5/34 浏览
基于 Canvas 和 Web Audio API 的交互式烟花动画实现

一个基于 Canvas 和 Web Audio API 的交互式烟花动画


一、整体架构

┌─────────────────────────────────────────────────────────────┐
│ HTML 结构 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ SVG 图标 │ │ Canvas 容器 │ │ 控制面板/菜单 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ CSS 样式 │
├─────────────────────────────────────────────────────────────┤
│ JavaScript 逻辑 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ FireworkSound│ │ Store │ │ Shell/Star/Spark │ │
│ │ 音效模块 │ │ 状态管理 │ │ 粒子系统 │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

二、HTML 结构部分

1. 头部元信息
<meta charset="UTF-8">
<title>2026 新年快乐!万事如意!</title>
<meta name="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 支持
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content=>



"black-translucent"
<meta name="apple-mobile-web-app-title" content="烟花盛宴">
<link rel="apple-touch-icon" href="...">
<link rel="manifest" href="data:application/json;base64,...">

说明:

  • 支持添加到 iOS 主屏幕
  • 半透明状态栏适配刘海屏
  • 内联 PWA manifest(Base64 编码)
3. SVG 图标定义
<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="icon-play" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></symbol>
  <symbol id="icon-pause" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></symbol>
  <!-- 其他图标省略 -->
</svg>

说明:

  • 使用 SVG symbol 定义可复用的图标
  • 通过 <use href="#icon-xxx"> 引用
  • 优点:矢量图标、可缩放、体积小
4. Canvas 画布容器
<div id="canvas-container">
  <canvas id="trails-canvas"></canvas><!-- 拖尾轨迹层 -->
  <canvas id="main-canvas"></canvas><!-- 主画面层 -->
</div>

双层 Canvas 设计原理:

层级作用渲染方式
trails-canvas绘制烟花拖尾效果渐变透明覆盖实现残影
main-canvas绘制当前帧的粒子和 UI 元素每帧清空重绘
5. 控制面板
<div id="controls">
  <div id="pause-btn" class="btn"><svg fill="white" width="24" height="24"><use href="#icon-pause"></use></svg></div>
  <div id="shutter-btn" class="btn"><svg fill="white" width="24" height="24"><use href="#icon-shutter-slow"></use></svg></div>
  <div id="settings-btn" class="btn"><svg fill="white" width="24" height="24"><use href="#icon-settings"></use></svg></div>
</div>

按钮功能:

  • 暂停/播放:控制动画运行
  • 快门模式:切换长曝光效果
  • 设置:打开设置菜单
6. 设置菜单
<div id="menu">
  <div id="menu__header">设置</div>
  <form>
    <div class="form-option form-option--select">
      <label>烟花类型</label><select id="shell-type"></select>
    </div>
    <div class="form-option form-option--checkbox">
      <label><input id="auto-launch" type="checkbox"/><span>自动发射</span></label>
    </div>
    <!-- 更多选项省略 -->
  </form>
</div>
7. 首次交互提示(iOS 适配)
<div id="audio-prompt">
  <div id="audio-prompt__icon">🎆</div>
  <div id="audio-prompt__text">点击屏幕开始烟花盛宴</div>
  <div id="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,
  enabled: true,
  soundType: 'realistic',
  isUnlocked: false,
  init() {
    this.ctx = new (window.AudioContext || window.webkitAudioContext)();
  },
  unlock() {
    if (this.isUnlocked) return true;
    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) {}
};

Web Audio API 核心概念:

组件作用示例用途
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;
    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);
  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: new Set(),
  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();
  },
  subscribe(listener) {
    this._listeners.add(listener);
    return () => this._listeners.delete(listener);
  },
  load() {},
  persist() {}
};

发布 - 订阅模式流程:

用户操作 → updateConfig() → store.setState() → _dispatch() → renderApp()
↓ 更新 DOM
3. Shell 烟花类
class Shell {
  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) {
    const launchX = position * (width - hpad * 2) + hpad;
    const launchY = height;
    const burstY = minHeight - (launchHeight * (minHeight - vpad));
    const launchDistance = launchY - burstY;
    const launchVelocity = Math.pow(launchDistance * 0.04, 0.64);
    const comet = Star.add(
      launchX, launchY,
      this.color || COLOR.White,
      Math.PI,
      launchVelocity,
      launchVelocity * 400
    );
    comet.heavy = true;
    comet.sparkFreq = 16;
    comet.onDeath = () => this.burst(comet.x, comet.y);
    FireworkSound.playLaunch();
  }
  burst(x, y) {
    const speed = this.size / 96;
    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;
    });
    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 的区别:

特性StarSpark
大小3px0.75px
空气阻力0.980.9
用途主要烟花粒子闪光效果
寿命较长较短
6. 渲染循环
function update(frameTime, lag) {
  if (!canInteract()) return;
  const timeStep = frameTime * simSpeed;
  const speed = simSpeed * lag;
  updateGlobals(timeStep, lag);
  const starDrag = 1 - (1 - Star.airDrag) * speed;
  const sparkDrag = 1 - (1 - Spark.airDrag) * speed;
  const gAcc = timeStep / 1000 * GRAVITY;
  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) => {
      // 类似星星的物理更新...
    });
  });
  render(speed);
}
7. 渲染函数
function render(speed) {
  const { dpr, width, height } = mainStage;
  const trailsCtx = trailsStage.ctx;
  const mainCtx = mainStage.ctx;
  colorSky(speed);
  trailsCtx.scale(dpr, dpr);
  mainCtx.scale(dpr, dpr);
  trailsCtx.globalCompositeOperation = 'source-over';
  trailsCtx.fillStyle = `rgba(0, 0, 0, ${longExposure ? 0.0025 : 0.1 * speed})`;
  trailsCtx.fillRect(0, 0, width, height);
  trailsCtx.globalCompositeOperation = 'lighten';
  mainCtx.clearRect(0, 0, width, height);
  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);
  }
  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();
  });
  trailsCtx.lineWidth = Spark.drawWidth;
  trailsCtx.lineCap = 'butt';
  if (speedBarOpacity) {
    mainCtx.globalAlpha = speedBarOpacity;
    mainCtx.fillStyle = COLOR.Blue;
    mainCtx.fillRect(0, height - 6, width * simSpeed, 6);
    mainCtx.globalAlpha = 1;
  }
  trailsCtx.resetTransform();
  mainCtx.resetTransform();
}
8. 天空颜色计算
const currentSkyColor = { r: 0, g: 0, b: 0 };
const targetSkyColor = { r: 0, g: 0, b: 0 };

function colorSky(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. 点击发射
function handlePointerStart(event) {
  activePointerCount++;
  FireworkSound.unlock();
  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; }
  else if (event.onCanvas) { launchShellFromConfig(event); }
}
2. 键盘快捷键
function handleKeydown(event) {
  if (event.keyCode === 80) togglePause();
  if (event.keyCode === 79) toggleMenu();
  if (event.keyCode === 27) toggleMenu(false);
}
3. 自动发射序列
function startSequence() {
  if (isFirstSeq) {
    isFirstSeq = false;
    const shell = new Shell(crysanthemumShell(shellSizeSelector()));
    shell.launch(0.5, 0.5);
    return 2400;
  }
  if (finaleSelector()) {
    seqRandomShell();
    if (currentFinaleCount < finaleCount) {
      currentFinaleCount++;
      return 170;
    } else {
      currentFinaleCount = 0;
      return 6000;
    }
  }
  const rand = Math.random();
  if (rand < 0.2) return seqSmallBarrage();
  if (rand < 0.6) return seqRandomShell();
  if (rand < 0.8) return seqTwoRandom();
  return seqTriple();
}

六、性能优化要点

优化技术说明效果
对象池复用 Star/Spark 对象减少 GC 压力
颜色分组按颜色分组批量渲染减少 Canvas 状态切换
双缓冲trails-canvas 保留历史轨迹实现拖尾效果
requestAnimationFrame与屏幕刷新同步流畅动画
空气阻力模拟粒子速度衰减自然消散效果
设备像素比适配scale(dpr, dpr)高清显示

七、iOS 适配

1. Meta 标签优化
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="烟花盛宴">
<meta name="format-detection" content="telephone=no">
<link rel="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) return true;
  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;
}
4. 手势防护
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 - 数学工具函数
本地文件
└── style.css - 额外样式(可选)

总结

这是一个功能完整的交互式烟花动画网页,主要特点:

  1. 视觉效果:双层 Canvas 实现拖尾效果,混合模式增强亮度
  2. 音效系统:8 种不同风格的音效,Web Audio API 实时生成
  3. 物理模拟:重力、空气阻力、粒子生命周期
  4. 状态管理:发布 - 订阅模式,localStorage 持久化
  5. 性能优化:对象池、颜色分组、requestAnimationFrame
  6. 跨平台:完整的 iOS/移动端适配

目录

  1. 一、整体架构
  2. 二、HTML 结构部分
  3. 1. 头部元信息
  4. 2. iOS PWA 支持
  5. 3. SVG 图标定义
  6. 4. Canvas 画布容器
  7. 5. 控制面板
  8. 6. 设置菜单
  9. 7. 首次交互提示(iOS 适配)
  10. 三、CSS 样式部分
  11. 1. 全局样式与触摸优化
  12. 2. 混合模式
  13. 3. 动画过渡
  14. 4. 音频提示动画
  15. 四、JavaScript 核心模块
  16. 1. FireworkSound 音效模块
  17. 2. Store 状态管理
  18. 3. Shell 烟花类
  19. 4. Star 星星粒子
  20. 5. Spark 火花粒子
  21. 6. 渲染循环
  22. 7. 渲染函数
  23. 8. 天空颜色计算
  24. 五、用户交互
  25. 1. 点击发射
  26. 2. 键盘快捷键
  27. 3. 自动发射序列
  28. 六、性能优化要点
  29. 七、iOS 适配
  30. 1. Meta 标签优化
  31. 2. CSS 触摸优化
  32. 3. Web Audio 解锁
  33. 4. 手势防护
  34. 5. iOS 支持功能表
  35. 八、文件依赖
  36. 外部库
  37. 本地文件
  38. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 网络安全自学路线:从基础到进阶的核心技能体系
  • 机器学习:KNN 算法详解
  • 使用 Java Flight Recorder 分析微信 API 服务的 GC 行为与内存泄漏
  • SystemVerilog 全面教程:从基础到高级验证
  • OpenClaw + GitHub Copilot GPT-5.4 技术修复指南
  • VcXsrv Windows X Server 使用指南:在 Windows 上运行 Linux 图形应用
  • Java 规则引擎核心原理与生产级落地实战
  • C++ 哈希表实现:unordered_map/set、位图与布隆过滤器
  • ToDesk 集成 ToClaw:AI Agent 实现远程桌面自动化执行
  • 探索 LLaMA3:Meta 最新语言模型技术解析与应用前景
  • CANN 生态 cann-dataset:AIGC 大模型全链路数据管理方案
  • Ascend C 实现高性能 SwiGLU 激活融合算子,加速大模型前馈网络
  • 35 道常见前端 Vue 面试题及解析
  • 归并排序与数组逆序对详解
  • Stable Diffusion 1.5 皮革服装 LoRA 镜像部署指南
  • OpenClaw 本地部署与飞书集成指南
  • 高校师生工作室任务管理系统设计与实现(Python Flask/Django)
  • OpenClaw + cpolar:将本地 AI 变为随身工具,实现远程访问与开发
  • mdev 与 udev:嵌入式与桌面 Linux 设备管理对比
  • 机器人 3D 位姿详解:5 种旋转表示法与机器学习应用

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online