Spaces:
Sleeping
Sleeping
File size: 2,330 Bytes
1afe868 ca23eb9 1afe868 7994c21 1afe868 e95d66b 1bc1cd0 1afe868 1bc1cd0 7994c21 e95d66b ca23eb9 e95d66b 7994c21 ca23eb9 ec43676 20ba9a1 ec43676 7994c21 7f7b2cc ca23eb9 5438f67 ca23eb9 7f7b2cc 1bc1cd0 e95d66b 7994c21 e95d66b 1afe868 e95d66b 1bc1cd0 ca23eb9 1bc1cd0 1afe868 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 84 |
'use client';
import { RoundedBox } from '@react-three/drei';
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { Mesh } from 'three';
import { FacingDirection, Rotations } from './consts';
import { rotationController } from './rotation-controller';
// Standard Rubik's cube colors
const CUBE_COLORS = {
front: '#ff0000', // Red
back: '#ff00ff', // Purple
left: '#00ff00', // Green
right: '#0000ff', // Blue
top: '#ffff00', // Yellow
bottom: '#ffffff', // White
};
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],
left: [-0.48, 0, 0],
right: [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 = CUBE_COLORS[face as keyof typeof CUBE_COLORS];
return (
<mesh key={face} position={positions[face as FacingDirection]} rotation={Rotations[face as FacingDirection]}>
<planeGeometry args={[0.8, 0.8]} />
<meshStandardMaterial color={color} metalness={1} roughness={roughness} />
</mesh>
);
})}
</mesh>
);
});
CubePiece.displayName = 'CubePiece';
|