Spaces:
Running
Running
File size: 2,349 Bytes
1afe868 ca23eb9 1afe868 7994c21 1afe868 4c67d79 1afe868 e95d66b 7994c21 e95d66b ca23eb9 e95d66b 7994c21 ca23eb9 ec43676 20ba9a1 ec43676 7994c21 7f7b2cc ca23eb9 5438f67 ca23eb9 7f7b2cc c6ef322 7f7b2cc 1bc1cd0 e95d66b 7994c21 e95d66b 1afe868 e95d66b 1bc1cd0 ca23eb9 c6ef322 1bc1cd0 c6ef322 4c67d79 c6ef322 1bc1cd0 1afe868 1bc1cd0 e95d66b 7994c21 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
'use client';
import { RoundedBox } from '@react-three/drei';
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { Mesh } from 'three';
import { CubeColorIndices, CubeColors, FacingDirection, Rotations } from './consts';
import { rotationController } from './rotation-controller';
export type CubePieceRef = {
resetPosition: () => void;
};
type CubePieceProps = {
roughness: number;
initialPosition: [number, number, number];
};
export const CubePiece = forwardRef<CubePieceRef, CubePieceProps>(({ roughness, initialPosition }, ref) => {
const [x, y, z] = initialPosition;
const meshRef = useRef<Mesh | null>(null);
useEffect(() => {
if (meshRef.current) {
rotationController.addCube(meshRef.current);
}
}, [meshRef]);
useImperativeHandle(ref, () => ({
resetPosition: () => {
meshRef.current?.position.set(x, y, z);
meshRef.current?.rotation.set(0, 0, 0);
},
}));
const visibleFaces: Record<FacingDirection, boolean> = {
front: z > 0,
back: z < 0,
left: x < 0,
right: x > 0,
top: y > 0,
bottom: y < 0,
};
const positions: Record<FacingDirection, [number, number, number]> = {
front: [0, 0, 0.48],
back: [0, 0, -0.48],
right: [0.48, 0, 0],
left: [-0.48, 0, 0],
top: [0, 0.48, 0],
bottom: [0, -0.48, 0],
};
return (
<mesh position={[x, y, z]} ref={meshRef}>
<RoundedBox args={[0.95, 0.95, 0.95]} radius={0.05} smoothness={4}>
<meshStandardMaterial color="#2a2a2a" metalness={1} roughness={roughness} />
</RoundedBox>
{Object.entries(visibleFaces).map(([face, isVisible]) => {
if (!isVisible) return null;
const color = CubeColors[face as keyof typeof CubeColors];
return (
<mesh
key={face}
position={positions[face as FacingDirection]}
rotation={Rotations[face as FacingDirection]}
userData={{
isFace: true,
faceColor: color,
faceColorIndex: CubeColorIndices[face as FacingDirection],
}}
>
<planeGeometry args={[0.8, 0.8]} />
<meshStandardMaterial color={color} metalness={1} roughness={roughness} />
</mesh>
);
})}
</mesh>
);
});
CubePiece.displayName = 'CubePiece';
|