Вращение GLB в Threejs

Я пытаюсь заставить мой трехмерный объект вращаться вокруг оси Y самостоятельно, не отключая возможность пользователя масштабировать и настраивать поворот объекта с помощью мыши.

Я сделал что-то вроде этого:

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

var canvasOfDesk = 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: canvasOfDesk, 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.info((xhr.loaded / xhr.total) * 100 + '% loaded')
    },
    (error) => {
        console.info(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()

Объект вращается так, как я хочу, но всего 20 секунд. После этого я замечаю, что объект масштабируется (увеличивается) сам по себе...

Я подозреваю, что это связано с ошибкой расчета в моей функции animate, но я не знаю, как это исправить.

Есть ли способ добиться того же эффекта без использования формулы вращения? (с CSS попутного ветра или просто CSS, может быть?)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, я попробовал скопировать Мацуяму-сенсея https://www.craftz.dog/, чтобы попытаться получить тот же эффект. Мой код сначала работает немного так, как я хочу, а затем терпит неудачу в конце, я буду с этим жить.

Вот мой новый код:

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.info(rotSpeed)
    } else {
        controls.update()
    }


    render()

}

Остальное то же, что и в вопросе.

РЕДАКТИРОВАТЬ

Именно controls.autoRotate = true мне все исправило.

Другие вопросы по теме