R3F에서 애니메이션을 적용하기 위해 @react-spring/three를 활용했다.
const props = useSpring({
to: {
position: [position.x, isHover ? position.y + 1 : position.y, position.z],
rotation: [
0,
THREE.MathUtils.degToRad(
(isClicked ? 180 : 0) + (isHover ? adjustRotation(rotationY, 5) : rotationY)
),
THREE.MathUtils.degToRad(
(isClicked ? -1 : 1) * (isHover
? adjustRotation(rotationZ, rotationZ > 0 ? -5 : 5)
: rotationZ)
),
]
},
config: { mass: 5, tension: 400, friction: 100 },
});
position이나 rotation의 값을 useSpring 내에 to라는 객체의 속성으로 넘겨주면 애니메이션을 자동으로 적용해준다.
다만, useSpring()을 사용할 때 rotation 속성에서 문제가 있었다.
rotation의 경우 기본적으로 각각 x,y,z축에 대한 값을 배열로 받는rotation = {[x, y, z]}의 형태였다. 그리고 useSpring은 각각의 속성에 대해서 SpringValue<[number, number, number]>과 같이 SpringValue라는 type으로 wrapping되어 나오는데, props로 잘 적용되는 position과 달리 rotation은 type 오류가 발생해서 적용되지 않는 것이었다.
결론적으로는 rotation으로 묶어서 전달하지 않고 각각의 x,y,z로 분리해서 전달하니 잘 해결되었는데,
interface SpringProps {
position: [number, number, number];
rotation: [number, number, number];
}
기존의 타입을,
interface SpringProps {
position: [number, number, number];
"rotation-x": number;
"rotation-y": number;
"rotation-z": number;
}
아래와 같은 형태로 변경해서 적용하니 type 에러가 해결되었다. 다만 position과 rotation 모두 x,y,z 축에 대한 값은 받는 THREE.Vector3 type을 받는 것으로 알고 있는데 왜 rotation에 대해서만 오류가 발생했는지는 모르겠다.