refactor: Enhance Point component with drag functionality and update state management in aisle store

This commit is contained in:
Jerald-Golden-B 2025-05-30 10:21:45 +05:30
parent 16e3f51448
commit e2fab37f0f
3 changed files with 101 additions and 36 deletions

View File

@ -2,11 +2,19 @@ import * as THREE from 'three';
import * as Constants from '../../../types/world/worldConstants'; import * as Constants from '../../../types/world/worldConstants';
import { useRef, useState, useEffect, useMemo } from 'react'; import { useRef, useState, useEffect, useMemo } from 'react';
import { useToolMode } from '../../../store/builder/store'; import { useToolMode } from '../../../store/builder/store';
import { DragControls } from '@react-three/drei';
import { useAisleStore } from '../../../store/builder/useAisleStore';
import { useThree } from '@react-three/fiber';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
function Point({ point, userData }: { readonly point: Point, readonly userData: any }) { function Point({ point, userData }: { readonly point: Point, readonly userData: any }) {
const materialRef = useRef<THREE.ShaderMaterial>(null); const materialRef = useRef<THREE.ShaderMaterial>(null);
const { raycaster, camera, scene, pointer } = useThree();
const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []);
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
const { toolMode } = useToolMode(); const { toolMode } = useToolMode();
const { setPosition } = useAisleStore();
const { hoveredPoint, setHoveredPoint } = useBuilderStore();
const boxScale: [number, number, number] = Constants.pointConfig.boxScale; const boxScale: [number, number, number] = Constants.pointConfig.boxScale;
const defaultInnerColor = Constants.pointConfig.defaultInnerColor; const defaultInnerColor = Constants.pointConfig.defaultInnerColor;
@ -29,31 +37,73 @@ function Point({ point, userData }: { readonly point: Point, readonly userData:
uInnerColor: { value: new THREE.Color(defaultInnerColor) }, uInnerColor: { value: new THREE.Color(defaultInnerColor) },
}), [borderColor, defaultInnerColor]); }), [borderColor, defaultInnerColor]);
const handleDrag = (point: Point) => {
if (toolMode === 'move' && isHovered) {
raycaster.setFromCamera(pointer, camera);
const intersectionPoint = new THREE.Vector3();
const position = raycaster.ray.intersectPlane(plane, intersectionPoint);
if (userData.pointType === 'Aisle') {
if (position) {
setPosition(point.uuid, [position.x, position.y, position.z]);
}
}
}
}
const handleDragEnd = (point: Point) => {
console.log('point: ', point);
}
useEffect(() => {
if (hoveredPoint && hoveredPoint.uuid !== point.uuid) {
setIsHovered(false);
}
}, [hoveredPoint])
if (!point) { if (!point) {
return null; return null;
} }
return ( return (
<DragControls
axisLock='y'
autoTransform={false}
onDrag={() => { handleDrag(point) }}
onDragEnd={() => { handleDragEnd(point) }}
>
<mesh <mesh
uuid={point.uuid} uuid={point.uuid}
position={new THREE.Vector3(...point.position)} position={new THREE.Vector3(...point.position)}
onPointerOver={() => setIsHovered(true)} onPointerOver={() => {
onPointerOut={() => setIsHovered(false)} if (!hoveredPoint) {
setHoveredPoint(point);
setIsHovered(true)
}
}}
onPointerOut={() => {
if (hoveredPoint && hoveredPoint.uuid === point.uuid) {
setHoveredPoint(null);
}
setIsHovered(false)
}}
userData={userData} userData={userData}
> >
<boxGeometry args={boxScale} /> <boxGeometry args={boxScale} />
<shaderMaterial <shaderMaterial
ref={materialRef} ref={materialRef}
uniforms={uniforms} uniforms={uniforms}
vertexShader={` vertexShader={
`
varying vec2 vUv; varying vec2 vUv;
void main() { void main() {
vUv = uv; vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
} }
`} `
fragmentShader={` }
fragmentShader={
`
varying vec2 vUv; varying vec2 vUv;
uniform vec3 uColor; uniform vec3 uColor;
uniform vec3 uInnerColor; uniform vec3 uInnerColor;
@ -61,16 +111,17 @@ function Point({ point, userData }: { readonly point: Point, readonly userData:
void main() { void main() {
// Define the size of the white square as a proportion of the face // Define the size of the white square as a proportion of the face
float borderThickness = 0.2; // Adjust this value for border thickness float borderThickness = 0.2; // Adjust this value for border thickness
if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
gl_FragColor = vec4(uInnerColor, 1.0); // Inner square gl_FragColor = vec4(uInnerColor, 1.0); // Inner square
} else { } else {
gl_FragColor = vec4(uColor, 1.0); // Border gl_FragColor = vec4(uColor, 1.0); // Border
} }
} }
`} `
}
/> />
</mesh> </mesh>
</DragControls>
); );
} }

View File

@ -63,7 +63,6 @@ export const useAisleStore = create<AisleStore>()(
const point = aisle.points.find(p => p.uuid === pointUuid); const point = aisle.points.find(p => p.uuid === pointUuid);
if (point) { if (point) {
point.position = position; point.position = position;
break;
} }
} }
}), }),
@ -73,7 +72,6 @@ export const useAisleStore = create<AisleStore>()(
const point = aisle.points.find(p => p.uuid === pointUuid); const point = aisle.points.find(p => p.uuid === pointUuid);
if (point) { if (point) {
point.layer = layer; point.layer = layer;
break;
} }
} }
}), }),

View File

@ -3,6 +3,9 @@ import { immer } from 'zustand/middleware/immer';
interface BuilderState { interface BuilderState {
// Common properties // Common properties
hoveredPoint: Point | null;
aisleType: AisleTypes; aisleType: AisleTypes;
aisleWidth: number; aisleWidth: number;
aisleColor: AisleColors; aisleColor: AisleColors;
@ -18,6 +21,9 @@ interface BuilderState {
aisleLength: number; aisleLength: number;
// Setters for common properties // Setters for common properties
setHoveredPoint: (point: Point | null) => void;
setAisleType: (type: AisleTypes) => void; setAisleType: (type: AisleTypes) => void;
setAisleWidth: (width: number) => void; setAisleWidth: (width: number) => void;
setAisleColor: (color: AisleColors) => void; setAisleColor: (color: AisleColors) => void;
@ -42,6 +48,9 @@ interface BuilderState {
export const useBuilderStore = create<BuilderState>()( export const useBuilderStore = create<BuilderState>()(
immer((set) => ({ immer((set) => ({
// Default values // Default values
hoveredPoint: null,
aisleType: 'solid-aisle', aisleType: 'solid-aisle',
aisleWidth: 0.1, aisleWidth: 0.1,
aisleColor: 'yellow', aisleColor: 'yellow',
@ -51,6 +60,13 @@ export const useBuilderStore = create<BuilderState>()(
aisleLength: 0.6, aisleLength: 0.6,
// Individual setters // Individual setters
setHoveredPoint: (point: Point | null) => {
set((state) => {
state.hoveredPoint = point;
});
},
setAisleType: (type) => { setAisleType: (type) => {
set((state) => { set((state) => {
state.aisleType = type; state.aisleType = type;