├── CameraSpline.jsx └── useSpline.jsx /CameraSpline.jsx: -------------------------------------------------------------------------------- 1 | export const CameraSpline = ({ jsonPath, speedFactor }) => { 2 | const { points, loading, error } = useSpline(jsonPath); 3 | const cam = useRef(); 4 | const lookAtTarget = useRef(); 5 | const [currentPoint, setCurrentPoint] = useState(0); 6 | 7 | useFrame(() => { 8 | const camera = cam.current; 9 | if (currentPoint < points.length - 1) { 10 | camera.position.lerp(points[currentPoint], speedFactor); 11 | camera.lookAt(points[currentPoint + 1]); 12 | 13 | if (camera.position.distanceTo(points[currentPoint]) < 0.1) { 14 | setCurrentPoint(currentPoint + 1); 15 | } 16 | } else { 17 | setCurrentPoint(0); 18 | } 19 | }); 20 | return ( 21 | <> 22 | 23 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /useSpline.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import * as THREE from 'three'; 3 | 4 | export const useSpline = (jsonPath) => { 5 | const [points, setPoints] = useState([]); 6 | const [loading, setLoading] = useState(true); 7 | const [error, setError] = useState(null); 8 | 9 | useEffect(() => { 10 | const loadPointsFromJson = async () => { 11 | try { 12 | const response = await fetch(jsonPath); 13 | const data = await response.json(); 14 | setPoints(data.points.map(point => new THREE.Vector3(point.x, point.y, point.z))); 15 | setLoading(false); 16 | } catch (err) { 17 | setError(err); 18 | setLoading(false); 19 | } 20 | }; 21 | 22 | loadPointsFromJson(); 23 | }, [jsonPath]); 24 | 25 | return { points, loading, error }; 26 | }; --------------------------------------------------------------------------------