Hi, I am trying to create an effect where an airplane flies in front of the camera and it loops. My approach to this problem is the code below. However, it is too hard coded. I want to know if there is a better method to get a similar result.
Also: I want to add an effect that when I hover over the aircraft the aircraft stops in mid-air and I can rotate it. It would be helpful knowing how to add that too.
Thank you.
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { TWEEN } from 'https://unpkg.com/three@0.139.0/examples/jsm/libs/tween.module.min.js';
const scene = new THREE.Scene();
scene.background = new THREE.Color('gainsboro');
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(-25, 15, 1 );
camera.lookAt(15, 5, -8);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
const loader = new GLTFLoader();
let airplane;
loader.load('./airplane/plane.glb', function (gltf) {
airplane = gltf.scene;
scene.add(airplane);
const ambientLight = new THREE.AmbientLight('white', 0.5);
scene.add(ambientLight);
const light = new THREE.DirectionalLight('white', 0.5);
light.position.set(1, 1, 1);
scene.add(light);
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
const curvePoints = [
new THREE.Vector3(0, 0, 80), // Start
new THREE.Vector3(0, 2, 70), // Accelerate on runway
new THREE.Vector3(0, 4, 60), // Preparing for lift off
new THREE.Vector3(0, 6, 50), // Lift off
new THREE.Vector3(0, 8, 40), // Initial climb
new THREE.Vector3(0, 10, 30), // Continue climb
new THREE.Vector3(0, 12, 20), // Nearly leveled off
new THREE.Vector3(0, 140, 10), // Level off
new THREE.Vector3(0, 160, 0), // Straight flight
new THREE.Vector3(0, 150, -10), // Continue straight flight
new THREE.Vector3(0, 14, -20), // Begin descent
new THREE.Vector3(0, 12, -30), // Continue descent
new THREE.Vector3(0, 10, -40), // Halfway through descent
new THREE.Vector3(0, 8, -50), // Nearly final approach
new THREE.Vector3(0, 6, -60), // Final approach
new THREE.Vector3(0, 4, -70), // Preparing for touch down
new THREE.Vector3(0, 2, -200), // Touch down
new THREE.Vector3(0, 0, -200), // Taxi
// new THREE.Vector3(0, 0, -40), // Continue taxi
new THREE.Vector3(0, 0, 0), // Nearly at start
new THREE.Vector3(0, 0, 40), // Back to start
new THREE.Vector3(0, 0, 150) // Ready for next round
];
const trajectory = new THREE.CatmullRomCurve3(curvePoints);
const animationDuration = 5000;
new TWEEN.Tween()
.to({}, animationDuration)
.onUpdate(() => {
const t = TWEEN.now() / animationDuration;
const positionOnCurve = trajectory.getPoint(t);
airplane.position.lerp(positionOnCurve, 0.005);
})
.repeat(Infinity)
.start();
new TWEEN.Tween(airplane.rotation)
.to({ x: -Math.PI/16, y: Math.PI/32, z: Math.PI/8 }, animationDuration)
.easing(TWEEN.Easing.Cubic.InOut)
.repeat(Infinity)
.yoyo(true)
.start();
function animate() {
requestAnimationFrame(animate);
TWEEN.update();
renderer.render(scene, camera);
light.position.copy(camera.position);
}
animate();
});
2024-01-25 22-16-21.mkv (2.6 MB)