Hello guys this is my code Chessboard.tsx and my app is completely no responsive i was watching
guides to fix this but nothing helped me.
import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
import Button from "@/components/landing-page/button";
const Chessboard: React.FC = () => {
const mountRef = useRef<HTMLDivElement | null>(null);
const [lastPosition, setLastPosition] = useState(5);
const [showButton, setShowButton] = useState(false);
const cameraPositions = useRef<{ position: THREE.Vector3; lookAt: THREE.Vector3 }[]>([
{
position: new THREE.Vector3(0, 8, 15), // Widok z przodu
lookAt: new THREE.Vector3(0, 0, 0),
},
{
position: new THREE.Vector3(0, 10, 0), // Widok z góry
lookAt: new THREE.Vector3(0, 0, 0),
},
{
position: new THREE.Vector3(0, 8, 10), // Powrót do widoku z przodu
lookAt: new THREE.Vector3(0, 0, 0),
},
{
position: new THREE.Vector3(-8, 3, 0), // Widok z boku
lookAt: new THREE.Vector3(0, 0, 0),
},
{
position: new THREE.Vector3(-2, 3, 0), // Przybliżenie do szachownicy
lookAt: new THREE.Vector3(0, 0, 0),
},
{
position: new THREE.Vector3(-8, 3, 0), // Widok oddalony
lookAt: new THREE.Vector3(0, 0, 0),
},
]);
const currentPositionIndex = useRef(0);
const transitioning = useRef(false);
const startTransitionTime = useRef<number | null>(null);
const animationDuration = 3000; // 3 sekundy
const startPosition = useRef(new THREE.Vector3());
const targetPosition = useRef(new THREE.Vector3());
const startRotation = useRef(0); // Startowa rotacja szachownicy
const targetRotation = useRef(0); // Docelowa rotacja szachownicy
const chessModel = useRef<THREE.Group | null>(null); // Referencja do modelu szachownicy
const renderButton = () => {
if(showButton) {
return (
<Button />
);
}
}
useEffect(() => {
if (!mountRef.current) return;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// Ustaw początkową pozycję kamery
if (cameraPositions.current[0]) {
camera.position.copy(cameraPositions.current[0].position);
camera.lookAt(cameraPositions.current[0].lookAt);
}
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
mountRef.current.appendChild(renderer.domElement);
const textureLoader = new RGBELoader();
textureLoader.load("/backgrounds/finalBackground.hdr", (texture: THREE.Texture) => {
texture.mapping = THREE.EquirectangularReflectionMapping;
const backgroundGeometry = new THREE.SphereGeometry(500, 32, 32);
const backgroundMaterial = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.BackSide
});
const backgroundMesh = new THREE.Mesh(backgroundGeometry, backgroundMaterial);
scene.add(backgroundMesh);
scene.environment = texture;
});
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.enableRotate = false;
controls.enablePan = false;
controls.enableZoom = false;
const ambientLight = new THREE.AmbientLight(0x808080, 0.7); // Jaśniejsze światło otoczenia
scene.add(ambientLight);
// Wyraźniejsze światło punktowe skierowane na szachownicę
const pointLight = new THREE.PointLight(0xffffff, 2.0, 150); // Jeszcze mocniejsze światło punktowe
pointLight.position.set(0, 20, 10); // Wyższe ustawienie nad szachownicą
pointLight.castShadow = true;
pointLight.shadow.mapSize.width = 2048; // Wyższa rozdzielczość cieni
pointLight.shadow.mapSize.height = 2048;
scene.add(pointLight);
// Jaśniejsze światło kierunkowe dla głębi
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0); // Jeszcze bardziej widoczne
directionalLight.position.set(10, 20, 15); // Wyżej i bardziej z boku dla lepszej głębi
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048; // Szczegółowe cienie
directionalLight.shadow.mapSize.height = 2048;
scene.add(directionalLight);
const loader = new GLTFLoader();
loader.load(
"/models/chess_set_1k.glb",
(gltf) => {
const model = gltf.scene;
model.scale.set(11, 11, 11);
model.traverse((node) => {
if ((node as THREE.Mesh).isMesh) {
const mesh = node as THREE.Mesh;
mesh.castShadow = true;
mesh.receiveShadow = true;
}
});
chessModel.current = model; // Zachowaj referencję do szachownicy
scene.add(model);
},
undefined,
(error) => {
console.error("Błąd ładowania modelu:", error);
}
);
const handleScroll = (event: WheelEvent) => {
if(currentPositionIndex.current === lastPosition) {
setShowButton(true);
}else{
if (transitioning.current || !cameraPositions.current.length) return;
const direction = event.deltaY > 0 ? 1 : -1;
const newIndex =
(currentPositionIndex.current + direction + cameraPositions.current.length) %
cameraPositions.current.length;
const newPosition = cameraPositions.current[newIndex];
if (!newPosition) return;
// Ustawienia pozycji kamery
startPosition.current.copy(camera.position);
targetPosition.current.copy(newPosition.position);
// Ustawienia rotacji szachownicy
startRotation.current = chessModel.current?.rotation.y || 0;
if (newIndex === 3) {
// Obrót szachownicy o 90 stopni dla widoku z boku (4)
targetRotation.current = startRotation.current + Math.PI / 2;
} else if (newIndex === 2) {
// Cofnij obrót do pierwotnej rotacji
targetRotation.current = 0;
} else {
targetRotation.current = startRotation.current; // Nie obracaj w innych przypadkach
}
currentPositionIndex.current = newIndex;
transitioning.current = true;
startTransitionTime.current = performance.now();
if (newIndex === lastPosition) {
setShowButton(true);
}
}
};
window.addEventListener("wheel", handleScroll);
const animate = () => {
requestAnimationFrame(animate);
if (transitioning.current && startTransitionTime.current !== null) {
const elapsedTime = performance.now() - startTransitionTime.current;
const progress = Math.min(elapsedTime / animationDuration, 1); // Ogranicz progress do 0-1
// Interpolacja pozycji kamery
camera.position.lerpVectors(
startPosition.current,
targetPosition.current,
progress
);
// Rotacja szachownicy
if (chessModel.current) {
chessModel.current.rotation.y =
startRotation.current +
(targetRotation.current - startRotation.current) * progress;
}
// Ustaw `lookAt` kamery
const currentLookAt = cameraPositions.current[currentPositionIndex.current]?.lookAt;
if (currentLookAt) camera.lookAt(currentLookAt);
if (progress === 1) {
transitioning.current = false; // Zakończ animację
startTransitionTime.current = null;
}
}
controls.update();
renderer.render(scene, camera);
};
animate();
return () => {
window.removeEventListener("wheel", handleScroll);
mountRef.current?.removeChild(renderer.domElement);
};
}, []);
return (
<>
<div
ref={mountRef}
style={{
zIndex: -1,
width: "100vw",
height: "100vh",
margin: 0,
padding: 0,
overflow: "hidden",
}}
/>
{renderButton()}
</>
);
};
export default Chessboard;