Select a color at random from the array, animate it, then repeat the process by selecting a new random color from the

Currently, I am utilizing gsap and three js to animate a light source.

I have an array containing various colors that I would like to cycle through randomly during the animation process.

My objective is to continuously loop through the random color selection for an infinite duration.

While using onCompleteAll: change, the transition between colors occurs abruptly at the end of each duration, lacking the smooth animation effect I desire.

In an attempt to rectify this issue, I switched to onComplete: change. However, this event never seems to trigger, resulting in only two colors being cycled through instead of the entire array.

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

Are there any glaring errors in my code or potential solutions to this dilemma?

Below is the snippet of code in question:

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);
  }
 

Thank you for any assistance provided.

EDIT: It should be noted that although other animations within my project utilize oncomplete and onupdate events, none of them are related to the light source and do not call the change function.

Answer №1

This solution involves utilizing tweening recursively, although it may not be the most conventional approach for GSAP:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="26524e5443436616081715100816">[email protected]</a>";
import { OrbitControls } from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3b4f53495e5e7b0b150a080d150b">[email protected]</a>/examples/jsm/controls/OrbitControls";
import {gsap} from "https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef889c8e9fafdcc1dedec1dd">[email protected]</a>";

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.2,
    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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What purpose does tagging serve in my template for polymer property binding?

I'm currently exploring the way Polymer handles the rendering of properties in a custom element's template. I've come across some interesting behavior that I haven't been able to fully grasp yet. Specifically, I noticed that certain pro ...

Accessing JavaScript results in PHP

Hello everyone! I am working on creating a dropdown menu for selecting time using JavaScript to get the computer's current time. My goal is to have an output that automatically selects the option in the dropdown if it matches the computer's time. ...

Tips for resolving a double click issue with a jQuery slide up/down animation

When I click a button, there is an animation that makes a div slide up and then down again. It functions the way I want it to, but the first time you click it, it doesn't work; you have to click twice for it to respond. Someone recommended using... ...

Error occurred due to a reference to a function being called before it was

Occasionally, I encounter a "Reference Error" (approximately once in every 200 attempts) with the code snippet below. var securityPrototype = { init: function(){ /* ... */ }, encryptionKey: function x() { var i = x.identifier; ...

Having difficulty in executing the node app.js script

I am currently learning node.js and encountering an issue when trying to run the app.js file using the command node app.js. The terminal shows no output, neither errors nor any other information. Here is the sequence of steps I have followed: $ brew insta ...

Having difficulty executing the playwright tests

Trying to execute the playwright test from the specified location results in a message prompting to run npm install -D @playwright/test before running the test. Despite having already installed playwright as a dev dependency, the test is still not being ex ...

JavaScript: Can you clarify the value of this variable using five sets of double quotations?

Could you please review the code snippet below for me? <script type="text/javascript"> function recentpostslist(json) { document.write('<ul class="recommended">'); var i; var j; for (i = 0; i < json.feed.entry.length; i++) { ...

50% greater than the highest of the other values

I'm a beginner when it comes to JavaScript and I need help setting a maximum value of 50% of the selling price. Can someone offer guidance? The fields I have are called "sale_price" and "discount". click here for image description What is the best ...

Which is better: Array of Objects or Nested Object structures?

I have a simple programming query that I'm hoping you can help clarify. Currently, I am dealing with numerous objects and I am contemplating whether it's more efficient to search for content within an array of objects or within a nested object s ...

The AJAX response did not include the <script> element

Currently working on a WordPress theme where I am implementing AJAX to load new archive pages. However, encountering an issue where the entire block of Javascript code is not being included in the newly fetched content. Let's say, initially the struc ...

Transform an array into an array of objects using the reduce method

optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'] result = [ {start: bengaluru, end: salem}, {start: salem, end: erode}, {start: erode, end: tiruppur}, {start: tiruppur, en ...

Attempting to open and display the contents of a text file (.txt) within a modal dialog box upon clicking a button

I am attempting to develop a modal that will appear when the user clicks on a specific button. The goal is for this modal to showcase text retrieved from a separate file stored on the server. My aim is to show this text within a dialog box modal. So far, ...

Issues with the Jquery feedback plugin's functionality are currently preventing it

I wanted to incorporate a feedback feature into my web application. To do this, I searched on Google and found a suitable jQuery plugin. I followed the documentation provided by the plugin, including the library in my HTML file, and then wrote the code as ...

"Executing the command 'npm run dev' is successful, however, the command 'next dev' does not yield the expected result

Trying out Next for the first time using npx create-next-app, but running into issues with the scripts. While npm run dev works without any problems, executing next dev gives me an error saying zsh: command not found: next. Any idea why this is happening? ...

The Vue component fails to refresh when the state in the store undergoes changes

Trying to create a simple todo list in Vue, but aiming to abstract everything out and utilize a dummy REST API for practice with production-level Vue projects has left my head spinning. While GET, PUT, and POST requests appear to be functioning properly, I ...

Converting Arrays into Objects with Multiple Dimensions

I have been attempting to transform this complex array into an object. However, I am facing an issue where only the second part of the array is being saved in the object, while the first part is missing. Is there a way to ensure that the entire array gets ...

Securing child paths in Vue.js

Having trouble protecting child routes from parent routes, facing some issues export default new Router({ routes: [ //frontend routes { {path: 'auth', component: Auth, children: authroutes, beforeEnter: (to, from, n ...

Verifying that the data has been successfully saved using JavaScript

When a user submits a small chunk of data via AJAX using a standard update action and a remote form, the information is sent to the action as javascript. The response is then rendered in javascript utilizing format.js. def update @message = Message.wher ...

Unable to resolve an unresolved issue with a jquery or javascript bug

I am currently facing some issues with my jQuery code in both Firebug and Chrome's developer tools. Any assistance would be greatly appreciated. Kindly make the necessary updates in the provided fiddle. Please follow this link to access the fiddle: ...

The X axis of the Perspective Camera in Three.js has been inverted

I am encountering an issue in my scene where I have two cameras - one orthographic and one perspective. The orthographic camera displays everything correctly, but the perspective camera shows the scene's X axis upside down. Is there a solution to fix ...