fridge_bites/assets/js/threejs-scene.js

68 lines
2.0 KiB
JavaScript

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// Сцена, камера, рендерер
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xeaf8eb);
const width = 430;
const height = 350;
const camera = new THREE.PerspectiveCamera(
75,width / height, 0.1, 1000
);
camera.position.set(9, 3, 3); // Слегка сверху и сбоку
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true, canvas: document.querySelector('#food-3d'), });
renderer.setSize(width, height, false);
// Еда
const loader = new GLTFLoader();
let foodModel;
loader.load('/assets/food_3d.glb', function(gltf) {
foodModel = gltf.scene;
foodModel.position.set(0, -1, 1.5);
foodModel.scale.set(25, 25, 30);
scene.add(foodModel);
}, function (xhr) {
// called while loading is progressing
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function (error) {
// called when loading has errors
console.log('An error happened', error);
});
// Свет (не обязателен для MeshNormalMaterial, но пригодится для других)
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
directionalLight.position.set(3, 5, 2);
directionalLight.castShadow = false;
scene.add(directionalLight);
const hemisphereLight = new THREE.HemisphereLight(0xaaaaaa, 0x444444, 0.6);
scene.add(hemisphereLight);
let mouseX = 0;
let mouseY = 0;
window.addEventListener('mousemove', (event) => {
// Нормализуем координаты мыши в [-1, 1]
mouseX = (event.clientX / window.innerWidth) * 2 - 1;
mouseY = -((event.clientY / window.innerHeight) * 2 - 1);
});
function animate() {
requestAnimationFrame(animate);
foodModel.position.z = 1.5 + mouseX * 0.7;
foodModel.position.y = -1 + mouseY * -0.7;
renderer.render(scene, camera);
}
animate();