Spaces:
Running
Running
add context to record all cubes
Browse files- src/components/cube-piece.tsx +8 -2
- src/components/rotator.tsx +17 -1
- src/components/rubiks-cube.tsx +6 -7
- src/contexts/cubes-context.tsx +53 -0
src/components/cube-piece.tsx
CHANGED
|
@@ -1,8 +1,10 @@
|
|
| 1 |
"use client";
|
| 2 |
|
| 3 |
import { RoundedBox } from "@react-three/drei";
|
| 4 |
-
import { useState } from "react";
|
| 5 |
import { FacingDirection, Rotations } from "./consts";
|
|
|
|
|
|
|
| 6 |
|
| 7 |
// Standard Rubik's cube colors
|
| 8 |
const CUBE_COLORS = {
|
|
@@ -23,6 +25,10 @@ export const CubePiece = ({ roughness, initialPosition }: CubePieceProps) => {
|
|
| 23 |
const [x, y, z] = initialPosition;
|
| 24 |
const [position] = useState<[number, number, number]>([x, y, z]);
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
const visibleFaces: Record<FacingDirection, boolean> = {
|
| 27 |
front: z > 0,
|
| 28 |
back: z < 0,
|
|
@@ -41,7 +47,7 @@ export const CubePiece = ({ roughness, initialPosition }: CubePieceProps) => {
|
|
| 41 |
};
|
| 42 |
|
| 43 |
return (
|
| 44 |
-
<mesh position={position}>
|
| 45 |
<RoundedBox args={[0.95, 0.95, 0.95]} radius={0.05} smoothness={4}>
|
| 46 |
<meshStandardMaterial
|
| 47 |
color="#2a2a2a"
|
|
|
|
| 1 |
"use client";
|
| 2 |
|
| 3 |
import { RoundedBox } from "@react-three/drei";
|
| 4 |
+
import { useRef, useState } from "react";
|
| 5 |
import { FacingDirection, Rotations } from "./consts";
|
| 6 |
+
import { Mesh } from "three";
|
| 7 |
+
import { useCubesContext } from "@/contexts/cubes-context";
|
| 8 |
|
| 9 |
// Standard Rubik's cube colors
|
| 10 |
const CUBE_COLORS = {
|
|
|
|
| 25 |
const [x, y, z] = initialPosition;
|
| 26 |
const [position] = useState<[number, number, number]>([x, y, z]);
|
| 27 |
|
| 28 |
+
const meshRef = useRef<Mesh | null>(null);
|
| 29 |
+
const { addCube } = useCubesContext();
|
| 30 |
+
addCube(meshRef);
|
| 31 |
+
|
| 32 |
const visibleFaces: Record<FacingDirection, boolean> = {
|
| 33 |
front: z > 0,
|
| 34 |
back: z < 0,
|
|
|
|
| 47 |
};
|
| 48 |
|
| 49 |
return (
|
| 50 |
+
<mesh position={position} ref={meshRef}>
|
| 51 |
<RoundedBox args={[0.95, 0.95, 0.95]} radius={0.05} smoothness={4}>
|
| 52 |
<meshStandardMaterial
|
| 53 |
color="#2a2a2a"
|
src/components/rotator.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import { FacingDirection } from "./consts";
|
| 2 |
import { RotationPanel } from "./rotation-panel";
|
| 3 |
|
|
@@ -6,12 +7,27 @@ type RotatorProps = {
|
|
| 6 |
};
|
| 7 |
|
| 8 |
export const Rotator = ({ facingDirection }: RotatorProps) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
return (
|
| 10 |
<>
|
| 11 |
-
<RotationPanel
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
<RotationPanel
|
| 13 |
direction="counter-clockwise"
|
| 14 |
facingDirection={facingDirection}
|
|
|
|
| 15 |
/>
|
| 16 |
</>
|
| 17 |
);
|
|
|
|
| 1 |
+
import { useCubesContext } from "@/contexts/cubes-context";
|
| 2 |
import { FacingDirection } from "./consts";
|
| 3 |
import { RotationPanel } from "./rotation-panel";
|
| 4 |
|
|
|
|
| 7 |
};
|
| 8 |
|
| 9 |
export const Rotator = ({ facingDirection }: RotatorProps) => {
|
| 10 |
+
const { getCubes } = useCubesContext();
|
| 11 |
+
|
| 12 |
+
const handleClick = (direction: "clockwise" | "counter-clockwise") => {
|
| 13 |
+
const cubes = getCubes(facingDirection);
|
| 14 |
+
cubes.forEach((cube) => {
|
| 15 |
+
console.log(cube.position);
|
| 16 |
+
});
|
| 17 |
+
console.log(cubes.length, direction);
|
| 18 |
+
};
|
| 19 |
+
|
| 20 |
return (
|
| 21 |
<>
|
| 22 |
+
<RotationPanel
|
| 23 |
+
direction="clockwise"
|
| 24 |
+
facingDirection={facingDirection}
|
| 25 |
+
onClick={(_, direction) => handleClick(direction)}
|
| 26 |
+
/>
|
| 27 |
<RotationPanel
|
| 28 |
direction="counter-clockwise"
|
| 29 |
facingDirection={facingDirection}
|
| 30 |
+
onClick={(_, direction) => handleClick(direction)}
|
| 31 |
/>
|
| 32 |
</>
|
| 33 |
);
|
src/components/rubiks-cube.tsx
CHANGED
|
@@ -1,13 +1,12 @@
|
|
| 1 |
-
import { Fragment } from "react";
|
| 2 |
import { CubePiece } from "./cube-piece";
|
| 3 |
-
import { RotationPanel } from "./rotation-panel";
|
| 4 |
import { FacingDirection } from "./consts";
|
| 5 |
import { Rotator } from "./rotator";
|
|
|
|
| 6 |
|
| 7 |
const CUBE_POSITIONS: Array<[number, number, number]> = [];
|
| 8 |
-
for (let x = -0.5; x <= 0.5; x
|
| 9 |
-
for (let y = -0.5; y <= 0.5; y
|
| 10 |
-
for (let z = -0.5; z <= 0.5; z
|
| 11 |
CUBE_POSITIONS.push([x, y, z]);
|
| 12 |
}
|
| 13 |
}
|
|
@@ -19,7 +18,7 @@ type RubiksCubeProps = {
|
|
| 19 |
|
| 20 |
export const RubiksCube = ({ roughness }: RubiksCubeProps) => {
|
| 21 |
return (
|
| 22 |
-
<
|
| 23 |
{CUBE_POSITIONS.map((position) => (
|
| 24 |
<CubePiece
|
| 25 |
key={position.join(",")}
|
|
@@ -30,6 +29,6 @@ export const RubiksCube = ({ roughness }: RubiksCubeProps) => {
|
|
| 30 |
{["front", "back", "left", "right", "top", "bottom"].map((face) => (
|
| 31 |
<Rotator key={face} facingDirection={face as FacingDirection} />
|
| 32 |
))}
|
| 33 |
-
</
|
| 34 |
);
|
| 35 |
};
|
|
|
|
|
|
|
| 1 |
import { CubePiece } from "./cube-piece";
|
|
|
|
| 2 |
import { FacingDirection } from "./consts";
|
| 3 |
import { Rotator } from "./rotator";
|
| 4 |
+
import { CubesProvider } from "@/contexts/cubes-context";
|
| 5 |
|
| 6 |
const CUBE_POSITIONS: Array<[number, number, number]> = [];
|
| 7 |
+
for (let x = -0.5; x <= 0.5; x += 1) {
|
| 8 |
+
for (let y = -0.5; y <= 0.5; y += 1) {
|
| 9 |
+
for (let z = -0.5; z <= 0.5; z += 1) {
|
| 10 |
CUBE_POSITIONS.push([x, y, z]);
|
| 11 |
}
|
| 12 |
}
|
|
|
|
| 18 |
|
| 19 |
export const RubiksCube = ({ roughness }: RubiksCubeProps) => {
|
| 20 |
return (
|
| 21 |
+
<CubesProvider>
|
| 22 |
{CUBE_POSITIONS.map((position) => (
|
| 23 |
<CubePiece
|
| 24 |
key={position.join(",")}
|
|
|
|
| 29 |
{["front", "back", "left", "right", "top", "bottom"].map((face) => (
|
| 30 |
<Rotator key={face} facingDirection={face as FacingDirection} />
|
| 31 |
))}
|
| 32 |
+
</CubesProvider>
|
| 33 |
);
|
| 34 |
};
|
src/contexts/cubes-context.tsx
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { FacingDirection } from "@/components/consts";
|
| 4 |
+
import { createContext, RefObject, useContext, useRef } from "react";
|
| 5 |
+
import { Mesh } from "three";
|
| 6 |
+
|
| 7 |
+
export type CubeMeshRef = RefObject<Mesh | null>;
|
| 8 |
+
|
| 9 |
+
type CubesContextType = {
|
| 10 |
+
addCube: (cubeMeshRef: CubeMeshRef) => void;
|
| 11 |
+
getCubes: (faceDirection: FacingDirection) => Mesh[];
|
| 12 |
+
};
|
| 13 |
+
|
| 14 |
+
const CubesContext = createContext<CubesContextType>({
|
| 15 |
+
addCube: () => {},
|
| 16 |
+
getCubes: () => [],
|
| 17 |
+
});
|
| 18 |
+
|
| 19 |
+
export const useCubesContext = () => useContext(CubesContext);
|
| 20 |
+
|
| 21 |
+
export const CubesProvider = ({ children }: { children: React.ReactNode }) => {
|
| 22 |
+
const cubes = useRef<CubeMeshRef[]>([]);
|
| 23 |
+
|
| 24 |
+
const addCube = (cubeMeshRef: CubeMeshRef) => {
|
| 25 |
+
cubes.current.push(cubeMeshRef);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
const getCubes = (faceDirection: FacingDirection) => {
|
| 29 |
+
const meshes = cubes.current
|
| 30 |
+
.map((c) => c.current)
|
| 31 |
+
.filter((m) => m !== null);
|
| 32 |
+
switch (faceDirection) {
|
| 33 |
+
case "front":
|
| 34 |
+
return meshes.filter((m) => m.position.z > 0);
|
| 35 |
+
case "back":
|
| 36 |
+
return meshes.filter((m) => m.position.z < 0);
|
| 37 |
+
case "left":
|
| 38 |
+
return meshes.filter((m) => m.position.x < 0);
|
| 39 |
+
case "right":
|
| 40 |
+
return meshes.filter((m) => m.position.x > 0);
|
| 41 |
+
case "top":
|
| 42 |
+
return meshes.filter((m) => m.position.y > 0);
|
| 43 |
+
case "bottom":
|
| 44 |
+
return meshes.filter((m) => m.position.y < 0);
|
| 45 |
+
}
|
| 46 |
+
};
|
| 47 |
+
|
| 48 |
+
return (
|
| 49 |
+
<CubesContext.Provider value={{ addCube, getCubes }}>
|
| 50 |
+
{children}
|
| 51 |
+
</CubesContext.Provider>
|
| 52 |
+
);
|
| 53 |
+
};
|