You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于指定坐标实现P5.js雨滴波纹屏保的问题

P5.js雨滴波纹屏保实现方案

核心问题分析

  1. 原始代码直接遍历所有坐标绘制圆圈,且所有圆圈共享同一个尺寸变量,无法控制逐个生成的节奏,导致一次性出现所有波纹。
  2. 颜色切换逻辑错误:循环设置fill最终只会应用最后一个颜色,且没有给每个圆圈分配独立的颜色状态,无法实现单个波纹的颜色切换。

修复后的完整代码

// 存储所有波纹的独立状态,每个波纹是一个对象
let ripples = [];
// 合并预设坐标为对象数组,更易维护
const locations = [
  {x: 50, y: 50}, {x: 50, y: 350}, {x: 100, y: 300},
  {x: 150, y: 250}, {x: 100, y: 100}, {x: 150, y: 150},
  {x: 200, y: 200}, {x: 250, y: 250}, {x: 300, y: 300},
  {x: 350, y: 50}, {x: 300, y: 100}, {x: 250, y: 150},
  {x: 350, y: 350}, {x: 50, y: 200}, {x: 100, y: 200},
  {x: 300, y: 200}, {x: 350, y: 200}, {x: 200, y: 50},
  {x: 200, y: 100}, {x: 200, y: 300}, {x: 200, y: 350}
];
// 预设颜色数组
const colorShift = [color("#00C2BF"), color("#33FFFC"), color("#33A2FF"), color("#3380FF")];
// 控制波纹生成的时间间隔(单位:帧)
let spawnInterval = 30;
let frameTracker = 0;

function setup() {
  createCanvas(400, 400);
  background("#004CC2");
  noStroke(); // 可根据需求恢复stroke("white")和strokeWeight(1)
}

function draw() {
  // 半透明背景实现波纹轨迹淡出效果
  background("#004CC2", 10);

  // 按间隔随机生成新波纹
  frameTracker++;
  if (frameTracker >= spawnInterval) {
    spawnRandomRipple();
    frameTracker = 0;
    // 随机调整间隔,让生成节奏更自然
    spawnInterval = random(20, 60);
  }

  // 反向遍历更新波纹,避免删除元素导致的遍历异常
  for (let i = ripples.length - 1; i >= 0; i--) {
    const ripple = ripples[i];
    // 扩张波纹尺寸
    ripple.size += 1;
    // 更新颜色索引,实现平滑颜色切换
    ripple.colorIndex = (ripple.colorIndex + 0.02) % colorShift.length;

    // 绘制波纹,取整确保颜色数组索引有效
    fill(colorShift[floor(ripple.colorIndex)]);
    circle(ripple.x, ripple.y, ripple.size);

    // 当波纹触及画布边缘时移除该波纹
    const edgeDistance = min(ripple.x, width - ripple.x, ripple.y, height - ripple.y);
    if (ripple.size / 2 >= edgeDistance) {
      ripples.splice(i, 1);
    }
  }
}

// 从预设坐标中随机选取位置生成新波纹
function spawnRandomRipple() {
  const randomLoc = random(locations);
  ripples.push({
    x: randomLoc.x,
    y: randomLoc.y,
    size: 0, // 从0开始扩张
    colorIndex: random(0, colorShift.length) // 随机初始颜色
  });
}

关键修改说明

1. 独立状态管理解决批量生成问题

  • 用ripples数组存储每个波纹的独立状态(坐标、尺寸、颜色索引),替代原来共享的全局变量,确保每个波纹的生命周期独立可控。
  • 通过spawnRandomRipple函数从预设坐标数组中随机选点,结合帧计数器控制生成间隔,实现波纹逐个随机出现的效果。

2. 单个波纹独立颜色切换

  • 给每个波纹分配colorIndex属性,在绘制循环中逐步递增并对颜色数组长度取模,让每个波纹独立切换颜色。
  • 用floor(ripple.colorIndex)确保从颜色数组中获取有效整数索引,避免颜色异常。

3. 生命周期优化

  • 当波纹半径触及画布边缘时,从数组中移除该波纹,避免无效绘制占用性能。
  • 使用半透明背景(background("#004CC2", 10))实现波纹淡出的轨迹效果,比直接重置背景更贴近真实水波视觉。

4. 代码可读性优化

  • 将原始的locationsX和locationsY合并为对象数组,避免坐标对应错误,更易维护。
  • 用const声明常量,提升代码稳定性。

内容的提问来源于stack exchange,提问作者Aidan A.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:31:02