import * as THREE from 'https://cdn.skypack.dev/three@0.135.0'; import { GLTFLoader } from 'https://cdn.skypack.dev/three@0.135.0/examples/jsm/loaders/GLTFLoader.js'; // Global vars const container = document.getElementById("background"); let scene; let camera; let renderer; let modelMoon; let modelPlanet; // Animations global vars let incrementer = 0.01; let reverse = false; const rotationSpeed = 0.001; const orbitRadius = 1; let lastRender = 0 // Helper function setupContainer (container) { const width = container.offsetWidth; const height = container.offsetHeight; const aspect = width / height; camera.aspect = aspect; camera.updateProjectionMatrix(); renderer.setSize(width, height); }; async function loadModel(path) { return new Promise((resolve) => new GLTFLoader().load(path, resolve)); } // Init function initScene() { // Scene renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.shadowMap.enabled = true; container.appendChild(renderer.domElement); scene = new THREE.Scene(); scene.background = new THREE.Color(0xdfc465); scene.fog = new THREE.Fog(0x56bac9, 5, 25); // Camera camera = new THREE.PerspectiveCamera(40, 1, 1, 100); camera.position.set(1, 1, 11); // Listeners setupContainer(container); window.addEventListener("resize", () => setupContainer(container), false); } function initLights() { // Global Light const hemiLight = new THREE.HemisphereLight(0xeab044, 0x444444); hemiLight.position.set(4, 0, 2); scene.add(hemiLight); const dirLight = new THREE.DirectionalLight(0xffffff); dirLight.position.set(3, 10, 10); dirLight.castShadow = true; dirLight.shadow.camera.top = 2; dirLight.shadow.camera.bottom = -2; dirLight.shadow.camera.left = -2; dirLight.shadow.camera.right = 2; dirLight.shadow.camera.near = 0.1; dirLight.shadow.camera.far = 40; scene.add(dirLight); } async function initModels() { // Load Models modelPlanet = (await loadModel('models/LP_planet_only.glb')).scene; modelMoon = (await loadModel('models/LP_planet_moon.glb')).scene; modelPlanet.position.set(1, 1, 0); modelPlanet.castShadow = true; modelPlanet.receiveShadow = true; scene.add(modelPlanet); modelMoon.position.set(1, 1, 0); modelMoon.castShadow = true; modelMoon.receiveShadow = true; scene.add(modelMoon); } // Animation function easeInOut() { if (reverse) { incrementer -= 0.005; } else { incrementer += 0.005; } if (incrementer >= 1 || incrementer <= 0) { reverse = !reverse; } return incrementer < 0.5 ? 2 * incrementer * incrementer : 1 - Math.pow(-2 * incrementer + 2, 2) / 2; }; function animateScene() { if ((performance.now() - lastRender) > (1000 / 60)) { modelPlanet.position.set(1, easeInOut() / 4 + 0.5, 0); modelPlanet.rotation.y += rotationSpeed; // const x = Math.cos(incrementer) * orbitRadius; // const z = Math.sin(incrementer) * orbitRadius; modelMoon.position.set(0, 1 - easeInOut() - 2, 0); modelMoon.rotation.y -= rotationSpeed + 0.01; renderer.render(scene, camera); } requestAnimationFrame(animateScene); } // Main export async function init() { initScene(); initLights(); await initModels(); animateScene(); } init();