Spinning Global Lighting and Bouncing in three.js

I am trying to create a 3D object that automatically rotates around the Y axis while still allowing users to scale and custom rotate the object with their mouse.

This is what I have so far:

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

var deskCanvas = document.getElementById("desk")

const scene = new THREE.Scene();
scene.position.y = -13;
scene.add(new THREE.AxesHelper(0));

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
const initialCameraPosition = new THREE.Vector3(
    -23, 17, 36);
camera.position.x = initialCameraPosition.x;
camera.position.y = initialCameraPosition.y;
camera.position.z = initialCameraPosition.z;

const renderer = new THREE.WebGLRenderer({ canvas: deskCanvas, alpha: true });
renderer.shadowMap.enabled = true;
renderer.setPixelRatio(10 * window.devicePixelRatio);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

const loader = new GLTFLoader();

const lightCandle = new THREE.SpotLight(0xffffff, 2000);
lightCandle.position.set(8, 40, -15);
scene.add(lightCandle);

const lightLaptop = new THREE.SpotLight(0xffffff, 2000);
lightLaptop.position.set(-10, 40, -15);
scene.add(lightLaptop);

loader.load(
    '/desk.glb',
    function(gltf) {
        var obj = gltf.scene;
        scene.add(obj);
        obj.castShadow = true;
        obj.receiveShadow = true;
        obj.traverse(function(child) {
            if (child.isMesh) {
                child.castShadow = true;
                child.receiveShadow = true;
            }
        });
    },
    (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
    },
    (error) => {
        console.log(error);
    }
);

window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
    camera.updateProjectionMatrix();
    render();
}

const target = new THREE.Vector3(-0.5, 1.2, 0);
const rotSpeed = 100;
function animate() {

    requestAnimationFrame(animate);

    const p = camera.position;
    camera.position.y = p.y;
    camera.position.x =
        p.x * Math.cos(rotSpeed) + p.z * Math.sin(rotSpeed);
    camera.position.z =
        p.z * Math.cos(rotSpeed) - p.x * Math.sin(rotSpeed);
    camera.lookAt(target);

    render();

}

function render() {
    renderer.render(scene, camera);
}

animate();

The object rotates as intended for only 20 seconds before it starts zooming (scaling up) on its own...

I suspect there may be an error in my calculation within the animate function, but I'm not sure how to fix it.

Is there another way to achieve this effect without using the rotation formula? Perhaps with Tailwind CSS or just regular CSS?

Answer №1

Attempting to replicate Matsuyama-sensei's work from , I initially succeeded in achieving the desired effect but encountered a setback towards the end. Despite this, I have decided to proceed with the result.

Below is the updated code that I am working with:

const target = new THREE.Vector3(-0.5, 1.2, 0)
var frame = 1
function easeOutCirc(x) {
    return Math.sqrt(1 - Math.pow(x - 1, 4))
}
function animate() {

    frame = frame <= 100 ? frame + 1 : frame
    requestAnimationFrame(animate)

    if (frame <= 100) {
        var rotSpeed = -easeOutCirc(frame / 120) * Math.PI * 20
        const p = initialCameraPosition
        camera.position.y = p.y
        camera.position.x =
            p.x * Math.cos(rotSpeed) + p.z * Math.sin(rotSpeed)
        camera.position.z =
            p.z * Math.cos(rotSpeed) - p.x * Math.sin(rotSpeed)
        camera.lookAt(target)
        console.log(rotSpeed)
    } else {
        controls.update()
    }


    render()

}

The remainder of the content remains unchanged from the original query.

UPDATE

By setting controls.autoRotate = true, I was able to resolve all issues and achieve the desired outcome.

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

Exploring the world of XD plugins, utilizing npm packages and Node.js APIs

Is it feasible to integrate npm packages and Node.js APIs into my Adobe XD plugin development process? ...

Filtering nested objects in JavaScript based on a specific property value

I have a list of objects nested in JavaScript and I need to filter them based on a specific search string and property value. My goal is to extract only the categories with children that are not hidden and contain at least one profile with a name matching ...

The Ajax success callback is failing to update the background-image property after receiving a successful JSON response

I am struggling with setting a background image in wordpress despite receiving a successful ajax response. The image url is being returned successfully in the json response, but I can't seem to set it as a background image. Here is the ajax function ...

Node.js refusing to acknowledge the get request handler for the homepage of the website

My Node.js server setup is quite simple: const express = require('express'); const app = express(); const http = require("http"); const path = require('path'); const favicon = require('serve-favicon'); // Public fil ...

Understanding the Difference Between WARN and ERR in npm Peer Dependency Resolution

I encountered a puzzling situation where two projects faced the same issue, yet npm resolved them differently: https://github.com/Sairyss/domain-driven-hexagon npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! W ...

Tips on deactivating automatic email client-specific content (such as Gmail or Outlook) in your emails

I have inserted the following code => <span style="font-size:12px;"><b>Name:</b></span></font><font size="1"><span style="font-size:12px;">Pratik</span> However, when viewed in a browser (such as Outlook ...

A step-by-step guide to showing images in React using a JSON URL array

I successfully transformed a JSON endpoint into a JavaScript array and have iterated through it to extract the required key values. While most of them are text values, one of them is an image that only displays the URL link. I attempted to iterate through ...

Can a custom spellchecking feature be integrated into an HTML textarea?

Question: I am wondering if it is feasible to incorporate a personalized spell checking feature into a Textarea field. Background: Currently, I am utilizing the b-form-textarea component from bootstrap-vue to present a textarea where users can input a li ...

Is it possible to apply the active class to the current list menu item in Mark using server-side techniques instead of client-side JS

When a menu item is clicked, I want to add the active class to that specific menu item. For example, if someone clicks on the contact page, the contact option in the menu should receive the active class. I am currently working with NodeJS and Koa. Below is ...

The Material-UI dialog is experiencing a flickering issue when incorporating Redux to manage the open

I am currently facing an issue with moving the open state of a material-ui dialog to redux in order to prevent it from closing during a rerender. However, I am encountering difficulties with the dialog's behavior when a rerender occurs. Even though th ...

Error: The validation of a JSON request failed as schema.validate is not a recognized function

As a beginner, I am currently immersed in a node.js API authentication tutorial. Everything was going smoothly until I had to refactor my code into separate files. Now, every time I send a JSON request via Postman, I keep encountering the error message "Ty ...

What is the syntax for inserting a text (value) into a text input field in HTML using PHP?

I'm having trouble getting the input field to populate with "Hello" when the button is clicked. I've checked for a solution, but can't seem to find one. Any help would be appreciated. Thank you. <!DOCTYPE html> <html> <head&g ...

Tips on sending information from Express to my HBS template

var Ticket = require('./models/ticket.js'); module.exports = function (app) { app.get('/',function (req, res) { Ticket.find({},function (err, tickets) { if(err) { res.sen ...

Tips on updating service variable values dynamically

I need to update a date value that is shared across all controllers in my website dynamically. The goal is to have a common date displayed throughout the site by updating it from any controller and having the new value reflected on all controllers. Can yo ...

Determine the character count of the text within an *ngFor loop

I am a beginner in Angular (8) and I am trying to determine the length of the input value that I have created using a *ngFor loop as shown below: <div *ngFor="let panel of panels; index as i" class="panel" [id]="'panel-' + panel.id"> & ...

The JQuery function .remove() will not properly remove dynamically added elements

I am facing an issue when trying to remove an element from a page. Every time I click on a button on the page, it adds a div with the following structure: <div class="holder-div" style="position: relative;display: inline-block;"> ...

Python web scraping: Extracting data from HTML tag names

Seeking help with extracting user data from a website by retrieving User IDs directly from tag names. I am utilizing python selenium and beautiful soup to extract the UID specifically from the div tag. For instance: <"div id="UID_**60CE07D6DF5C02A987E ...

Is there a way to adjust the image opacity of a background using Material UI?

Is there a way to adjust the opacity of a background image using Material UI? I attempted to achieve this by utilizing the makeStyles hook in Material UI. Here is an example of my code: import React from 'react'; import {Box,Typography } from &ap ...

Leveraging AJAX, PHP, and MySQL for showcasing tabular information

My goal is to dynamically display a column of data labeled as [pin], depending on the values of [plan] and [order_id]. Specifically, when plan=9 and order_id=0. I am looking to achieve this without having to reload the entire page by utilizing Ajax. Below ...

Always ensure that only one div is visible at a time

I am currently working on a project where I cannot use ng-cloak due to the way the css files are loaded. I have been exploring alternative solutions and have tried a few different approaches. My main goal is to ensure that two icons are never shown at the ...