Spaces:
Sleeping
Sleeping
File size: 4,365 Bytes
ec43676 aa1b508 f68ade5 42ffd2e e9d3f6f aa1b508 42ffd2e aa1b508 aa74807 e9d3f6f f68ade5 42ffd2e f68ade5 42ffd2e e9d3f6f f68ade5 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e aa74807 42ffd2e f68ade5 42ffd2e e9d3f6f f68ade5 ec43676 42ffd2e e9d3f6f ec43676 f68ade5 42ffd2e e9d3f6f 42ffd2e f68ade5 ec43676 aa1b508 42ffd2e aa1b508 |
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
import { useCubesContext } from "@/contexts/cubes-context";
import { FacingDirection } from "./consts";
import { RotationPanel } from "./rotation-panel";
import { Group } from "three";
import { Fragment, useRef } from "react";
import { useFrame } from "@react-three/fiber";
type RotateArgs = {
rotatingFaceDirection: FacingDirection;
rotatingDirection: "clockwise" | "counter-clockwise";
rotatingGroup: Group;
};
type RotatorProps = {
cubeSpeed: number;
};
export const Rotator = ({ cubeSpeed }: RotatorProps) => {
const { getCubes, cubeGroupRef } = useCubesContext();
const isRotating = useRef(false);
const rotateArgs = useRef<RotateArgs>({
rotatingFaceDirection: "front",
rotatingDirection: "clockwise",
rotatingGroup: new Group(),
});
useFrame((state, delta) => {
const { rotatingFaceDirection, rotatingDirection, rotatingGroup } =
rotateArgs.current;
const cubeGroup = cubeGroupRef.current;
if (!isRotating.current || !cubeGroup) return;
let sign = 0;
switch (rotatingFaceDirection) {
case "front":
sign = rotatingDirection === "clockwise" ? -1 : 1;
rotatingGroup.rotation.z += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.z) > Math.PI / 2) {
rotatingGroup.rotation.z = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
case "back":
sign = rotatingDirection === "clockwise" ? 1 : -1;
rotatingGroup.rotation.z += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.z) > Math.PI / 2) {
rotatingGroup.rotation.z = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
case "left":
sign = rotatingDirection === "clockwise" ? 1 : -1;
rotatingGroup.rotation.x += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.x) > Math.PI / 2) {
rotatingGroup.rotation.x = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
case "right":
sign = rotatingDirection === "clockwise" ? -1 : 1;
rotatingGroup.rotation.x += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.x) > Math.PI / 2) {
rotatingGroup.rotation.x = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
case "top":
sign = rotatingDirection === "clockwise" ? -1 : 1;
rotatingGroup.rotation.y += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.y) > Math.PI / 2) {
rotatingGroup.rotation.y = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
case "bottom":
sign = rotatingDirection === "clockwise" ? 1 : -1;
rotatingGroup.rotation.y += sign * delta * cubeSpeed;
if (Math.abs(rotatingGroup.rotation.y) > Math.PI / 2) {
rotatingGroup.rotation.y = (Math.PI / 2) * sign;
isRotating.current = false;
}
break;
}
if (isRotating.current) return;
const children = [...rotatingGroup.children];
children.forEach((child) => cubeGroup.attach(child));
cubeGroup.remove(rotatingGroup);
});
const handleClick = (
facingDirection: FacingDirection,
direction: "clockwise" | "counter-clockwise",
) => {
if (isRotating.current || !cubeGroupRef.current) return;
const cubes = getCubes(facingDirection);
rotateArgs.current.rotatingFaceDirection = facingDirection;
rotateArgs.current.rotatingDirection = direction;
rotateArgs.current.rotatingGroup = new Group();
cubeGroupRef.current.add(rotateArgs.current.rotatingGroup);
cubes.forEach((cube) => rotateArgs.current.rotatingGroup.attach(cube));
isRotating.current = true;
};
return (
<>
{["front", "back", "left", "right", "top", "bottom"].map(
(facingDirection) => (
<Fragment key={facingDirection}>
<RotationPanel
direction="clockwise"
facingDirection={facingDirection as FacingDirection}
onClick={handleClick}
/>
<RotationPanel
direction="counter-clockwise"
facingDirection={facingDirection as FacingDirection}
onClick={handleClick}
/>
</Fragment>
),
)}
</>
);
};
|