Home > Net >  Pick random color from array animate, repeat, pick a new random color from array?
Pick random color from array animate, repeat, pick a new random color from array?

Time:11-08

So I am using gsap and three js my aim is to animate a light

I have an array of colors i wish to use i have code set up so 1 of these colors are picked randomly

now i can get it to pick random colors and repeat infinity ... this is what I want .....

now when I use onCompleteAll: change, this works all good and fine BUT it doesn't animate the colors it just "jumps" to the next color when the duration is done so no animation it just changes straight away when the time is up

so I thought Oh well easy enough to fix i will use onComplete: change, instead now this never fires tho? so what ends up happening is the colors change and animate perfectly but only 2 of the colors from the array because the change(); function never gets fired so either does the new random value

Math.floor(Math.random() * std.length)

can anyone spot any obvious mistakes or know of any fixes?

here is my code:

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

var randomIndex, randomColor, tempColor, camlight3;

randomIndex = Math.floor(Math.random() * std.length); 
     randomColor = std[randomIndex];
     tempColor = randomColor;

// Three.js camera 
    /*  camlight3 = new THREE.PointLight(tempColor, 60, 80, 0.0);
        camlight3.power = 60;
        camlight3.position.x  = 10;
        camlight3.position.y  = 25;
        camlight3.position.z -= 120;
        this._camera.add(camlight3); */


gsap.to(camlight3.color,  

{ 
     
  duration: 2,
  r: tempColor.r, g: tempColor.g, b: tempColor.b,
  onCompleteAll: change,
  yoyo: true,
  repeat: -1,
  repeatRefresh: true,
    
});

function change() {
     randomIndex = Math.floor(Math.random() * std.length); 
     randomColor = std[randomIndex];
     tempColor = randomColor;
     camlight3.color = tempColor;
     console.log(tempColor);
  }
 

thanks for any help

EDIT i should mention I have other animations doing on that use the oncomplete and onupdate if that matters non of the other though call change or are associated with the light

CodePudding user response:

I made it working with calling of tweening recursively (not sure how correct this approach for GSAP):

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/[email protected]";
import { OrbitControls } from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls";
import {gsap} from "https://cdn.skypack.dev/[email protected]";

console.clear();

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 10, 10);
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", (event) => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;

let floor = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10).rotateX(-Math.PI * 0.5),
    new THREE.MeshStandardMaterial({ color: 0xffffff })
  );
scene.add(floor);

let colors = [0xff00ff, 0x00ffff, 0xffff00, 0xff0000, 0x00ff00, 0x0000ff];
let getColor = () => {return colors[Math.floor(Math.random() * colors.length)]};
let light = new THREE.SpotLight(getColor(), 0.5, 0, Math.PI * 0.1, 0.5);
let nextColor = new THREE.Color(getColor());
light.position.set(5, 7, 0);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));

let lightHelper = new THREE.SpotLightHelper(light);
scene.add(lightHelper);

(function runSequence(){
  gsap.to(light.color, {
    r: nextColor.r, 
    g: nextColor.g, 
    b: nextColor.b, 
    duration: 0.5,
    onComplete: function(){
      nextColor.set(getColor());
      runSequence();
    }
  });
})(); // random colors

let clock = new THREE.Clock();

renderer.setAnimationLoop(() => {
  let t = clock.getElapsedTime();
  controls.update();
  light.position.x = Math.sin(t * 0.25) * 5;
  lightHelper.update();
  renderer.render(scene, camera);
});
</script>

  • Related