const scene = new THREE.Scene(); // render settings const render_frame_height = 512; // jelly movement simulation settings const stiffness = 0.1; const damping = 0.1; // model files /////////////////// // precalculated constants/variables and initializing variables // navbar height const navbar_height = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--logo_height')) + parseInt(getComputedStyle(document.documentElement).getPropertyValue('--logo_margin')) * 2; // jelly simulation variables const jelly_position = new THREE.Vector2(); const velocity = new THREE.Vector2(); // calculate damping multiplier from damping value const damping_multiplier = 1 - damping; // calculate render frame aspect ratio const render_frame_aspect = window.innerWidth / render_frame_height; // calculate boolean telling if aspect ration is vertical (taller than wide) //const aspect_ratio_vertical = render_frame_aspect < 1; //console.log(aspect_ratio_vertical); // calculate half of the render frame size const half_frame_size = new THREE.Vector2(window.innerWidth / 2, render_frame_height / 2); /////////////////////////////////////////////////////////////// const camera = new THREE.PerspectiveCamera( 45, render_frame_aspect, 0.1, 1000 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, 512 ); document.body.appendChild( renderer.domElement ); // set background color to rgb(6, 6, 6) renderer.setClearColor(0x060606); // loading model const loader = new THREE.GLTFLoader(); loader.load("assets/models/scene.glb", handle_load); function handle_load(gltf) { scene.add(gltf.scene); } // function to get mouse position inside the render frame const mouse_pos = new THREE.Vector2(); window.addEventListener("mousemove", function(e) { // get mouse position inside the render frame and make one axis in range from -1 to 1 while taking aspect ratio into account on the second axis depending if aspect ratio is vertical or not //if (aspect_ratio_vertical) { // if aspect ratio is vertical // mouse_pos.x = (e.clientX / half_frame_size.x - 1) * render_frame_aspect; // mouse_pos.y = (e.clientY - navbar_height) / half_frame_size.y + 1; //} else { // if aspect ratio is not vertical mouse_pos.x = e.clientX / half_frame_size.x - 1; mouse_pos.y = ((navbar_height - e.clientY) / half_frame_size.y + 1) / -render_frame_aspect; //} // clamp y to range from -2 to 2 mouse_pos.y = Math.min(Math.max(mouse_pos.y, -2), 2); }); // make camera above the scene model camera.position.y = 4; // rotate camera to look down camera.rotation.x = -Math.PI / 2; function animate() { requestAnimationFrame( animate ); // jelly movement simulation // change velocity by distance beetween target position and curent jelly positition then multiplied by stiffness velocity.x += (mouse_pos.x * 3 - jelly_position.x) * stiffness; velocity.y += (mouse_pos.y * 3 - jelly_position.y) * stiffness; // change position by velocity jelly_position.x += velocity.x; jelly_position.y += velocity.y; // set camera position x and y to jelly position camera.position.x = jelly_position.x; camera.position.z = jelly_position.y; // translate div displayed over the render frame to the position of the jelly position document.getElementById("main_box").style.transform = "translate(" + (jelly_position.x * 50) + "px, " + (jelly_position.y * 50) + "px)"; // if velocity is not 0 then multiply it by damping multiplier. do it for each axis separately if (velocity.x != 0) { velocity.x *= damping_multiplier; } if (velocity.y != 0) { velocity.y *= damping_multiplier; } renderer.render( scene, camera ); }; animate();