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

使用GSAP与Three.js实现灯光颜色随机平滑切换动画的问题

解决GSAP+Three.js灯光颜色无限平滑随机切换问题

问题根源

  • 使用repeat: -1和yoyo: true时,onComplete回调永远不会触发——因为动画会无限重复,没有真正的"完成"状态;onCompleteAll也只会在所有动画(含重复轮次)全部结束时触发,这里无限重复自然不会生效。
  • change函数里直接赋值camlight3.color = tempColor,会绕过GSAP的过渡逻辑,导致颜色直接跳变,没有平滑效果。

修正方案

放弃repeat和yoyo,改为在每次动画完成后,生成新的随机颜色并启动下一段过渡动画,通过递归调用实现无限循环:

var std = [
  new THREE.Color().setHex(0x009dff),
  new THREE.Color().setHex(0x001aff),
  new THREE.Color().setHex(0x4000ff),
  new THREE.Color().setHex(0x7300ff)
];

var camlight3;

// 初始化灯光(取消注释并确保this._camera已正确定义)
camlight3 = new THREE.PointLight(std[Math.floor(Math.random() * std.length)], 60, 80, 0.0);
camlight3.power = 60;
camlight3.position.x += 10;
camlight3.position.y += 25;
camlight3.position.z -= 120;
this._camera.add(camlight3);

// 启动首次颜色过渡动画
animateToRandomColor();

function animateToRandomColor() {
  // 生成排除当前颜色的随机索引(可选,避免连续重复同色)
  let currentIndex = std.findIndex(color => color.equals(camlight3.color));
  let randomIndex;
  do {
    randomIndex = Math.floor(Math.random() * std.length);
  } while (randomIndex === currentIndex);
  
  const targetColor = std[randomIndex];
  
  // 使用GSAP过渡到目标颜色
  gsap.to(camlight3.color, {
    duration: 2,
    r: targetColor.r,
    g: targetColor.g,
    b: targetColor.b,
    onComplete: animateToRandomColor // 动画完成后递归调用,实现无限循环
  });
}

关键说明

  • 递归调用animateToRandomColor确保每次过渡完成后自动生成新的随机颜色并启动下一段动画,实现无限平滑切换。
  • 可选的颜色去重逻辑(do-while循环)避免连续切换到同一种颜色,提升视觉效果;如果不需要可以直接去掉,只保留randomIndex = Math.floor(Math.random() * std.length)。
  • 始终通过GSAP修改camlight3.color的r/g/b属性,保证过渡效果生效,避免直接赋值导致的跳变。

内容的提问来源于stack exchange,提问作者user3112634

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:40:36