Search code examples
javascriptthree.jstween.js

Camera position glitches at the start of tweening


I'm making a simple program that tweens the camera to a given position. It works very well. But if I try to pan the camera (using orbital controls), and then transition, the tweening glitches at the beginning of the transition.

Here's my current code:

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const TWEEN = require('@tweenjs/tween.js');

const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({ canvas });
const canvasWid = Math.floor(window.innerWidth * 2 / 3), canvasHei = (window.innerHeight * 2 / 3);
renderer.setSize(canvasWid, canvasHei);
var scene = new THREE.Scene();
scene.background = new THREE.Color('grey');
scene.add(new THREE.HemisphereLight(0xB1E1FF, 0xB97A20, 1));

const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 1000);
camera.position.set(10, 15, 20);

const controls = new OrbitControls(camera, canvas);
controls.screenSpacePanning = true;
controls.target.set(0, 0, 0);
controls.update();


const geometry = new THREE.BoxGeometry( 4, 4, 4 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

var tween;
var tweening = false;
function animate() {
    requestAnimationFrame(animate);
    if (tweening) {
        TWEEN.update();
        camera.lookAt(new THREE.Vector3(0, 0, 0));
    }
    renderer.render(scene, camera);
}
animate();

window.addEventListener('keydown', keyDown);
function keyDown(e) {
    if (e.key === "a") {
        var vv = new THREE.Vector3(prompt(), prompt(), prompt());
        tween = new TWEEN.Tween(camera.position).to(vv, 3000)
            .easing(TWEEN.Easing.Quadratic.InOut)
            .start();

        tweening = true;
        tween.onComplete(function () {
            tweening = false;
        });
    }
}

I've already tried the solutions Here, Here, and Here but I still can't figure it out.


Solution

  • Just fixed the issue after reading this article on using tween.js with orbital controls. Apparently I need to tween both control.target and camera.position