134 lines
3.3 KiB
JavaScript
134 lines
3.3 KiB
JavaScript
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();
|