패널들이 중앙을 바라보게 해보려고 한다. 개인적으로 이 부분이 상당히 어려웠다.
useRef 를 이용해서 패널들 하나하나를 제어해줘야 하는데, useRef 를 배열로 사용하는 방법을 몰라서 찾아봤다.
가장 먼저 useRef 를 배열로 초기화 시켜준다
const planeRefs = useRef([]);
처음 안 사실이지만 ref 는 item을 불러오는 함수였다…!
따라서 item 을 이용해서 ref에 배열로 되어있는 값에 item 을 하나하나 넣어주면 배열로 된 ref 가 생성된다!!!
{planePositions.map((arr, i) => (
<mesh ref={(item) => (planeRefs.current[i] = item)} key={i} position={[arr[0], arr[1], arr[2]]}>
<planeGeometry args={[0.3, 0.3]} />
<meshBasicMaterial map={textures[i % 5]} side={THREE.DoubleSide} />
</mesh>
))}
여기 까지가 힘들었던 부분이고, 이젠 ref 의 배열을 이용해 하나하나 중앙을 바라보게만 해주면 된다.
mesh 는 lookAt 이란 함수를 가지고 있고 이 함수를 이용해서 특정방향을 바라보게 만들 수 있다. 따라서
useEffect(() => {
const planes = planeRefs.current;
planes.forEach((plane) => {
plane.lookAt(0, 0, 0);
});
}, [planePositions]);
이렇게 하면 중앙을 바라보는 형태의 구 가 된다!
import { OrbitControls, useTexture } from "@react-three/drei";
import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import img01 from "../images/01.jpg";
import img02 from "../images/02.jpg";
import img03 from "../images/03.jpg";
import img04 from "../images/04.jpg";
import img05 from "../images/05.jpg";
export default function NewThree() {
const ref = useRef(null);
const planeRefs = useRef([]);
const texture01 = useTexture(img01);
const texture02 = useTexture(img02);
const texture03 = useTexture(img03);
const texture04 = useTexture(img04);
const texture05 = useTexture(img05);
const textures = [texture01, texture02, texture03, texture04, texture05];
const [planePositions, setPlanePositions] = useState([]);
useEffect(() => {
var tempP = Array.from(ref.current.attributes.position.array);
var newP = [];
for (let i = 0; i < tempP.length; i += 3) {
const temp = [tempP[i], tempP[i + 1], tempP[i + 2]];
newP.push(temp);
}
setPlanePositions(newP);
}, []);
useEffect(() => {
const planes = planeRefs.current;
planes.forEach((plane) => {
plane.lookAt(0, 0, 0);
});
}, [planePositions]);
return (
<>
<OrbitControls />
<points>
<sphereGeometry ref={ref} args={[1, 8, 8]} />
<meshBasicMaterial transparent />
</points>
{planePositions.map((arr, i) => (
<mesh ref={(item) => (planeRefs.current[i] = item)} key={i} position={[arr[0], arr[1], arr[2]]}>
<planeGeometry args={[0.3, 0.3]} />
<meshBasicMaterial map={textures[i % 5]} side={THREE.DoubleSide} />
</mesh>
))}
</>
);
}