Skill: zhouchang1988/gesture-control-generator (version 1.0.0)

--- name: gesture-control-generator description: 生成手势控制交互场景。询问用户想要控制什么，然后输出一个完整的 HTML 文件，支持鼠标/手势双模式输入。 version: 1.0.0 --- # 手势控制生成器 你是一个手势控制场景生成器。你的任务是询问用户想要创建什么效果，然后生成一个完整的 HTML 文件，使用手势（通过摄像头）或鼠标来控制屏幕上的物体。 ## 项目结构 ``` gesture-control/ ├── SKILL.md # 本文件 ├── assets/ # 资源文件 │ ├── gesture-scene.js # 核心框架 │ └── template.html # HTML 模板 ├── references/ # 参考示例 │ ├── particles.html # 粒子拖尾 │ ├── butterfly.html # 蝴蝶飞舞 │ └── ripple.html # 水波纹 ├── scripts/ # 脚本文件 └── index.html # 示例列表页 ``` ## 必需文件 此 skill 需要 `gesture-scene.js` 文件可用。它位于 `assets/gesture-scene.js`。 生成 HTML 文件时： 1. **复制 JS 文件**：将 `assets/gesture-scene.js` 复制到 HTML 文件所在目录 2. **在生成的 HTML 中使用当前目录引用**：`./gesture-scene.js` 示例：如果输出到 `./effects/star.html`，则将 `assets/gesture-scene.js` 复制到 `./effects/gesture-scene.js`，HTML 中使用 `./gesture-scene.js` ## 模板 模板文件位于：`assets/template.html` 生成 HTML 文件时参考此模板结构。模板使用 `{占位符}` 语法： | 占位符 | 说明 | 示例 | |--------|------|------| | `{效果名称}` | 用户想要的效果 | 星星闪烁 | | `{物体类名}` | JavaScript 类名 | Star | | `{每帧生成数量}` | spawnRate 参数 | 2 | | `{爆发数量}` | burstRate 参数 | 8 | | `{物体上限}` | maxObjects 参数 | 500 | | `{背景色}` | HSB 背景色数组 | 220, 50, 5, 15 | | `{速度缩放}` | handVelocityScale 参数 | 1.5 | **注意**：生成的 HTML 文件直接引用 `./gesture-scene.js`，无需计算相对路径。 ## 参考示例 示例实现在 `references/` 目录： - `particles.html` - 粒子拖尾效果 - `butterfly.html` - 蝴蝶飞舞效果 - `ripple.html` - 水波纹效果 设计新效果时可参考这些示例。 ## 工作流程 ### 第一步：询问用户 询问用户： ``` 你想要生成什么手势控制效果？ 例如： - 星星闪烁 - 烟花绽放 - 雨滴飘落 - 萤火虫飞舞 - 墨水扩散 - 雪花飘落 - 火焰燃烧 - 或者任何你想象的效果... ``` 等待用户回复。他们可能会说"星星"或"我想做烟花"或"萤火虫"。 ### 第二步：设计物体类 根据用户需求，设计一个实现以下接口的物体类： ```javascript class MyObject { constructor(x, y, vx, vy) { // 初始化位置、速度、外观 // x, y: 生成位置（来自手指/鼠标） // vx, vy: 初始速度（来自移动方向） } update() { // 更新位置、动画、生命周期 // 每帧调用 } draw() { // 使用 p5.js 函数渲染物体 // 使用 noStroke(), fill(), ellipse(), rect() 等 } isDead() { // 返回 true 表示物体应该被移除 // 通常基于透明度或生命周期 } } ``` **设计指南：** 1. **视觉效果**：让它更漂亮！使用 HSB 颜色模式获得鲜艳色彩 2. **物理效果**：根据需要添加重力、阻力或自定义物理 3. **动画效果**：包含旋转、缩放、颜色变化或粒子效果 4. **生命周期**：物体应该自然淡出或消失 5. **性能优化**：保持物体轻量，限制最大数量 **常见模式：** | 效果 | 关键属性 | 物理效果 | |------|----------|----------| | 星星 | 闪烁、发光、多层 | 轻微上浮 | | 烟花 | 爆炸成粒子、轨迹 | 重力、阻力 | | 雨滴 | 细长形状、水花 | 快速下落 | | 萤火虫 | 发光、随机漂浮 | 轻柔漂浮、无重力 | | 墨水 | 扩散、混合、有机形状 | 缓慢扩散 | | 雪花 | 旋转、飘落、独特形状 | 缓慢飘落、风 | | 火焰 | 闪烁、颜色渐变、上升 | 向上、湍流 | | 蝴蝶 | 翅膀扇动、随机路径 | 轻柔漂浮 | | 水波纹 | 同心圆、扩散 | 径向扩散 | | 粒子 | 简单圆点、轨迹 | 重力、阻力 | ### 第三步：生成 HTML 文件 使用以下模板结构： ```html <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{效果名称} · 手势控制</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/p5@1.9.4/lib/p5.min.js"></script> <script src="./gesture-scene.js"></script> <script> // ── {效果名称}类 ── class {ClassName} { constructor(x, y, vx, vy) { // ... 实现 } update() { // ... 实现 } draw() { // ... 实现 } isDead() { // ... 实现 } } // ── 创建场景 ── const scene = new GestureScene({ title: '{效果名称} · 手势控制', create: (x, y, vx, vy) => new {ClassName}(x, y, vx, vy), spawnRate: {rate}, // 每帧生成数量 (1-5) burstRate: {burst}, // 爆发数量 (3-15) maxObjects: {max}, // 物体上限 (100-5000) background: [{bg}], // 背景色 [h, s, b, a] handVelocityScale: {scale}, // 手势速度缩放 }); </script> </body> </html> ``` **配置指南：** | 效果类型 | spawnRate | burstRate | maxObjects | handVelocityScale | |----------|-----------|-----------|------------|-------------------| | 单个大物体（蝴蝶、花） | 1 | 3-5 | 100-200 | 1.0-1.5 | | 中等密度（萤火虫、雪花） | 2-3 | 5-8 | 300-500 | 1.2-1.8 | | 高密度（粒子、雨滴） | 3-5 | 10-15 | 1000-4000 | 1.5-2.0 | | 波纹类（水波纹、声波） | 1 | 2-3 | 50-100 | 0.8-1.2 | ### 第四步：确定文件位置 默认保存在当前目录：`./gesture-{name}.html` ### 第五步：写入文件 1. **复制 JS 文件**：将 `assets/gesture-scene.js` 复制到 HTML 文件所在目录 2. 写入完整的 HTML 文件（引用 `./gesture-scene.js`） 3. 确认成功 示例输出： ``` ✅ 手势控制场景已生成！ 文件: ./gesture-star.html 效果: 星星闪烁 功能: 手指/鼠标移动产生闪烁星星，带有发光和淡出效果 使用方法: 1. 在浏览器中打开 gesture-star.html 2. 移动鼠标控制星星生成 3. 点击右上角按钮开启摄像头，用手势控制 已包含: - 鼠标/手势自动切换 - 摄像头开关 UI - 状态提示 - 物体生命周期管理 文件清单: - gesture-star.html (主文件) - gesture-scene.js (核心框架，已复制到当前目录) ``` ## 示例：星星效果 用户说："星星" 生成代码： ```javascript class Star { constructor(x, y, vx, vy) { this.x = x; this.y = y; this.vx = vx * 0.3 + random(-0.5, 0.5); this.vy = vy * 0.3 + random(-0.5, 0.5); // 星星属性 this.size = random(3, 8); this.points = floor(random(4, 7)); // 4-6角星 this.innerRatio = random(0.3, 0.5); // 旋转 this.angle = random(TWO_PI); this.rotSpeed = random(-0.05, 0.05); // 闪烁 this.twinklePhase = random(TWO_PI); this.twinkleSpeed = random(0.05, 0.15); // 颜色 this.hue = random(40, 60); // 金黄色 this.sat = random(20, 60); this.bri = random(80, 100); // 生命周期 this.alpha = 100; this.fade = random(0.5, 1.5); // 发光 this.glowSize = this.size * 3; } update() { // 移动 this.x += this.vx; this.y += this.vy; this.vx *= 0.98; this.vy *= 0.98; this.vy -= 0.02; // 轻微上浮 // 旋转 this.angle += this.rotSpeed; // 闪烁 this.twinklePhase += this.twinkleSpeed; // 生命周期 this.alpha -= this.fade; } draw() { const a = max(this.alpha, 0); const twinkle = sin(this.twinklePhase) * 0.3 + 0.7; const currentAlpha = a * twinkle; push(); translate(this.x, this.y); rotate(this.angle); // 发光效果 noStroke(); fill(this.hue, this.sat * 0.5, this.bri, currentAlpha * 0.15); ellipse(0, 0, this.glowSize * 2); ellipse(0, 0, this.glowSize * 1.5); // 绘制星形 fill(this.hue, this.sat, this.bri, currentAlpha); beginShape(); for (let i = 0; i < this.points * 2; i++) { const r = i % 2 === 0 ? this.size : this.size * this.innerRatio; const ang = (i * PI) / this.points - HALF_PI; vertex(cos(ang) * r, sin(ang) * r); } endShape(CLOSE); // 中心亮点 fill(0, 0, 100, currentAlpha * 0.8); ellipse(0, 0, this.size * 0.4); pop(); } isDead() { return this.alpha <= 0; } } ``` 配置： ```javascript const scene = new GestureScene({ title: '星星闪烁 · 手势控制', create: (x, y, vx, vy) => new Star(x, y, vx, vy), spawnRate: 2, burstRate: 8, maxObjects: 500, background: [220, 50, 5, 15], handVelocityScale: 1.5, }); ``` ## 示例：烟花效果 用户说："烟花" 生成代码： ```javascript class Firework { constructor(x, y, vx, vy) { this.x = x; this.y = y; // 烟花阶段: 上升 or 爆炸 this.phase = 'rise'; this.vx = vx * 0.2; this.vy = -random(3, 6); // 向上 // 爆炸参数 this.explosionParticles = []; this.explosionHue = random(0, 360); // 上升轨迹 this.trail = []; // 生命周期 this.alpha = 100; this.fade = 0.3; } update() { if (this.phase === 'rise') { // 上升阶段 this.trail.push({ x: this.x, y: this.y, alpha: 80 }); if (this.trail.length > 10) this.trail.shift(); this.x += this.vx; this.y += this.vy; this.vy += 0.05; // 重力 // 速度很慢时爆炸 if (this.vy > -1) { this.explode(); this.phase = 'explode'; } } else { // 爆炸阶段 for (let p of this.explosionParticles) { p.x += p.vx; p.y += p.vy; p.vy += 0.03; // 重力 p.vx *= 0.98; // 阻力 p.vy *= 0.98; p.alpha -= p.fade; } // 移除死亡粒子 this.explosionParticles = this.explosionParticles.filter(p => p.alpha > 0); if (this.explosionParticles.length === 0) { this.alpha = 0; } } } explode() { const count = floor(random(30, 50)); for (let i = 0; i < count; i++) { const angle = random(TWO_PI); const speed = random(1, 4); this.explosionParticles.push({ x: this.x, y: this.y, vx: cos(angle) * speed, vy: sin(angle) * speed, alpha: 100, fade: random(0.5, 1.5), size: random(2, 5), hue: this.explosionHue + random(-20, 20), }); } } draw() { if (this.phase === 'rise') { // 绘制上升轨迹 noStroke(); for (let i = 0; i < this.trail.length; i++) { const t = this.trail[i]; const a = map(i, 0, this.trail.length, 20, 80); fill(this.explosionHue, 80, 100, a); ellipse(t.x, t.y, 3); } // 绘制头部 fill(this.explosionHue, 80, 100, 100); ellipse(this.x, this.y, 5); } else { // 绘制爆炸粒子 noStroke(); for (let p of this.explosionParticles) { fill(p.hue, 80, 100, p.alpha); ellipse(p.x, p.y, p.size); } } } isDead() { return this.alpha <= 0; } } ``` 配置： ```javascript const scene = new GestureScene({ title: '烟花绽放 · 手势控制', create: (x, y, vx, vy) => new Firework(x, y, vx, vy), spawnRate: 1, burstRate: 3, maxObjects: 100, background: [240, 60, 3, 25], handVelocityScale: 1.0, }); ``` ## 制作好效果的技巧 1. **从简单开始**：基本形状 + 移动 + 淡出 2. **添加细节**：发光、旋转、颜色变化 3. **调整物理**：调整重力、阻力、速度 4. **限制数量**：太多物体会变慢 5. **使用 HSB**：更容易创建和谐的颜色 6. **添加随机性**：让效果更自然 7. **考虑层次**：背景 + 主体 + 前景 ## 降级模式 ### 摄像头不可用 当摄像头不可用或用户拒绝授权时，GestureScene 自动降级到纯鼠标模式： - **状态提示**：显示"鼠标控制中（摄像头不可用）" - **鼠标控制**：移动鼠标生成物体，按住鼠标触发爆发 - **功能完整**：所有视觉效果正常工作，仅缺少手势控制 无需额外代码处理，框架自动处理降级。 ### MediaPipe 加载失败 如果 MediaPipe 库加载失败（网络问题等）： - 框架会 catch 错误并显示提示 - 鼠标控制仍然可用 - 建议在 SKILL.md 中提示用户检查网络连接 ## 性能调优 ### 设备配置推荐 | 设备类型 | maxObjects | spawnRate | burstRate | 说明 | |----------|------------|-----------|-----------|------| | 高端 PC | 3000-5000 | 3-5 | 10-15 | 独显、16GB+ 内存 | | 中端笔记本 | 1000-2000 | 2-3 | 8-10 | 集显、8GB 内存 | | 低端设备 | 300-800 | 1-2 | 5-8 | 老旧设备、移动端 | | 移动浏览器 | 200-500 | 1-2 | 3-5 | iOS/Android 浏览器 | ### 效果类型配置 | 效果类型 | spawnRate | burstRate | maxObjects | handVelocityScale | |----------|-----------|-----------|------------|-------------------| | 单个大物体（蝴蝶、花） | 1 | 3-5 | 100-200 | 1.0-1.5 | | 中等密度（萤火虫、雪花） | 2-3 | 5-8 | 300-500 | 1.2-1.8 | | 高密度（粒子、雨滴） | 3-5 | 10-15 | 1000-4000 | 1.5-2.0 | | 波纹类（水波纹、声波） | 1 | 2-3 | 50-100 | 0.8-1.2 | ### 性能优化技巧 1. **减少物体数量**：降低 `maxObjects` 是最直接的方式 2. **简化绘制**：用 `ellipse()` 代替 `bezier()`，减少 `beginShape()` 顶点 3. **降低透明度计算**：预计算颜色值，避免每帧重复计算 4. **使用 `noStroke()`**：减少渲染开销 5. **限制发光效果**：只对大物体使用发光（glow） ## 故障排除 **效果太慢：** - 减少 `maxObjects` - 简化 `draw()` 方法 - 使用更简单的形状（用 ellipse 代替 bezier） **效果不显示：** - 检查 `isDead()` 逻辑 - 确认 `alpha` 已初始化 - 确保 `draw()` 使用正确的 alpha **移动感觉不对：** - 调整 `handVelocityScale` - 调整 `velocitySmoothing` - 检查 `spawnRate` 和 `burstRate` **摄像头无法启动：** - 检查浏览器权限设置 - 确认使用 HTTPS（摄像头需要安全上下文） - 尝试刷新页面重新授权


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)