zone camera updation and builder zoneadatas

This commit is contained in:
2025-03-26 18:30:33 +05:30
parent 5cc3b83e43
commit 82aabc2004
18 changed files with 472 additions and 175 deletions

View File

@@ -4,6 +4,7 @@ import {
EyeIcon,
LockIcon,
} from "../../icons/RealTimeVisulationIcons";
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
// Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right";
@@ -15,6 +16,9 @@ interface ButtonsProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: {
id: string;
type: string;
@@ -29,6 +33,9 @@ interface ButtonsProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: {
id: string;
type: string;
@@ -108,7 +115,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
panelOrder: newActiveSides,
};
// Update the selectedZone state
// Delete the selectedZone state
console.log('updatedZone: ', updatedZone);
setSelectedZone(updatedZone);
} else {
@@ -120,6 +127,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
activeSides: newActiveSides,
panelOrder: newActiveSides,
};
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
let response = panelData(organization, selectedZone.zoneId, newActiveSides)
console.log('response: ', response);
// Update the selectedZone state
console.log('updatedZone: ', updatedZone);
@@ -128,70 +139,73 @@ const AddButtons: React.FC<ButtonsProps> = ({
};
return (
<div>
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
<div key={side} className={`side-button-container ${side}`}>
{/* "+" Button */}
<button
className={`side-button ${side}`}
onClick={() => handlePlusButtonClick(side)}
title={
selectedZone.activeSides.includes(side)
? `Remove all items and close ${side} panel`
: `Activate ${side} panel`
}
>
+
</button>
<>
{/* Extra Buttons */}
{selectedZone.activeSides.includes(side) && (
<div className="extra-Bs">
{/* Hide Panel */}
<div
className={`icon ${hiddenPanels.includes(side) ? "active" : ""
}`}
title={
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
}
onClick={() => toggleVisibility(side)}
>
<EyeIcon
fill={
hiddenPanels.includes(side)
? "white"
: "#1D1E21"
<div>
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
<div key={side} className={`side-button-container ${side}`}>
{/* "+" Button */}
<button
className={`side-button ${side}`}
onClick={() => handlePlusButtonClick(side)}
title={
selectedZone.activeSides.includes(side)
? `Remove all items and close ${side} panel`
: `Activate ${side} panel`
}
>
+
</button>
{/* Extra Buttons */}
{selectedZone.activeSides.includes(side) && (
<div className="extra-Bs">
{/* Hide Panel */}
<div
className={`icon ${hiddenPanels.includes(side) ? "active" : ""
}`}
title={
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
}
/>
</div>
onClick={() => toggleVisibility(side)}
>
<EyeIcon
fill={
hiddenPanels.includes(side)
? "white"
: "#1D1E21"
}
/>
</div>
{/* Clean Panel */}
<div
className="icon"
title="Clean Panel"
onClick={() => cleanPanel(side)}
>
<CleanPannel />
</div>
{/* Clean Panel */}
<div
className="icon"
title="Clean Panel"
onClick={() => cleanPanel(side)}
>
<CleanPannel />
</div>
{/* Lock/Unlock Panel */}
<div
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
}`}
title={
selectedZone.lockedPanels.includes(side)
? "Unlock Panel"
: "Lock Panel"
}
onClick={() => toggleLockPanel(side)}
>
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "#ffffff" : "#1D1E21"} />
{/* Lock/Unlock Panel */}
<div
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
}`}
title={
selectedZone.lockedPanels.includes(side)
? "Unlock Panel"
: "Lock Panel"
}
onClick={() => toggleLockPanel(side)}
>
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "#ffffff" : "#1D1E21"} />
</div>
</div>
</div>
)}
</div>
))}
</div>
)}
</div>
))}
</div>
</>
);
};

View File

@@ -11,6 +11,9 @@ interface DisplayZoneProps {
panelOrder: Side[];
lockedPanels: Side[];
widgets: Widget[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
};
};
selectedZone: {
@@ -18,6 +21,9 @@ interface DisplayZoneProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: {
id: string;
type: string;
@@ -32,6 +38,9 @@ interface DisplayZoneProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: {
id: string;
type: string;
@@ -152,16 +161,16 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
return (
<div
ref={containerRef}
className={`zoon-wrapper ${selectedZone.activeSides.includes("bottom") && "bottom"
className={`zoon-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
}`}
>
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`}
}`}
onClick={() => {
console.log('zoneName: ', zoneName);
setSelectedZone({
zoneName,
@@ -169,12 +178,15 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [],
})
zoneId: zonesData[zoneName]?.zoneId || "",
zoneViewPortTarget: zonesData[zoneName].zoneViewPortTarget || [],
zoneViewPortPosition:
zonesData[zoneName].zoneViewPortPosition || [],
});
// setSelectedZone({
// zoneName,
// ...zonesData[zoneName],
// });
console.log(selectedZone);
}}
>
{zoneName}
@@ -184,4 +196,4 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
);
};
export default DisplayZone;
export default DisplayZone;

View File

@@ -0,0 +1,59 @@
import { useState } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
const DroppedObjects = () => {
const { camera } = useThree(); // Now inside Canvas ✅
const [objects, setObjects] = useState<{ id: number; position: [number, number, number] }[]>([]);
// Function to convert drop event into 3D position
const handleDrop = (event: DragEvent) => {
event.preventDefault();
const data = event.dataTransfer?.getData("text/plain");
if (!data) return;
try {
const cardData = JSON.parse(data);
if (!cardData.className.includes("floating total-card")) {
console.log("Drop rejected: Incorrect element.");
return;
}
// Convert 2D drop position to 3D world coordinates
const x = (event.clientX / window.innerWidth) * 2 - 1;
const y = -(event.clientY / window.innerHeight) * 2 + 1;
// Raycasting to determine the drop position in 3D
const raycaster = new THREE.Raycaster();
const mouseVector = new THREE.Vector2(x, y);
raycaster.setFromCamera(mouseVector, camera);
// Intersect with a ground plane (assume y = 0)
const groundPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
const intersection = new THREE.Vector3();
raycaster.ray.intersectPlane(groundPlane, intersection);
console.log("Spawn Object at:", intersection);
// Add the dropped object to the scene state
setObjects((prev) => [...prev, { id: Date.now(), position: [intersection.x, intersection.y, intersection.z] }]);
} catch (error) {
console.error("Invalid data:", error);
}
};
return (
<group>
{/* Render dropped objects as green boxes */}
{objects.map((obj) => (
<mesh key={obj.id} position={obj.position}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="green" />
</mesh>
))}
</group>
);
};
export default DroppedObjects;

View File

@@ -20,6 +20,9 @@ interface PanelProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[];
};
setSelectedZone: React.Dispatch<
@@ -28,6 +31,9 @@ interface PanelProps {
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[];
}>
>;

View File

@@ -6,7 +6,8 @@ import { useSelectedZoneStore } from "../../../store/useZoneStore";
import DisplayZone from "./DisplayZone";
import Scene from "../../../modules/scene/scene";
import useModuleStore from "../../../store/useModuleStore";
import { getZonesApi } from "../../../services/realTimeVisulization/zoneData/getZones";
import { useZones } from "../../../store/store";
type Side = "top" | "bottom" | "left" | "right";
@@ -17,7 +18,9 @@ type FormattedZoneData = Record<
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneCentrePoint: number[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[];
}
>;
@@ -28,12 +31,6 @@ type Widget = {
panel: Side;
data: any;
};
type Zone = {
zoneId: string;
zoneName: string;
points: number[][];
layer: number;
};
const RealTimeVisulization: React.FC = () => {
const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
@@ -43,45 +40,30 @@ const RealTimeVisulization: React.FC = () => {
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const { zones } = useZones()
useEffect(() => {
async function GetZoneData() {
try {
const response: { data: Zone[] } | undefined = await getZonesApi(
"hexrfactory"
);
const data = Array.isArray(zones) ? zones : [];
console.log('data: ', data);
const formattedData = data.reduce<FormattedZoneData>((acc, zone) => {
acc[zone.zoneName] = {
activeSides: [],
panelOrder: [],
lockedPanels: [],
zoneId: zone.zoneId,
zoneViewPortTarget: zone.viewPortCenter,
zoneViewPortPosition: zone.viewPortposition,
widgets: [],
};
return acc;
}, {});
if (!response || !response.data) {
return;
}
const formattedData = response?.data?.reduce<FormattedZoneData>(
(acc, zone) => {
acc[zone.zoneName] = {
activeSides: [],
panelOrder: [],
lockedPanels: [],
zoneCentrePoint: [],
widgets: [],
};
return acc;
},
{}
);
setZonesData(formattedData);
} catch (error) { }
}
GetZoneData();
}, []);
useEffect(() => {
console.log('zonesData: ', zonesData);
}, [zonesData]);
setZonesData(formattedData);
}, [zones]);
useEffect(() => {
setZonesData((prev) => {
if (!selectedZone) return prev;
return {
...prev,
[selectedZone.zoneName]: {
@@ -89,12 +71,32 @@ const RealTimeVisulization: React.FC = () => {
activeSides: selectedZone.activeSides || [],
panelOrder: selectedZone.panelOrder || [],
lockedPanels: selectedZone.lockedPanels || [],
zoneId: selectedZone.zoneId || "",
zoneViewPortTarget: selectedZone.zoneViewPortTarget || [],
zoneViewPortPosition: selectedZone.zoneViewPortPosition || [],
widgets: selectedZone.widgets || [],
},
};
});
}, [selectedZone]);
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const canvas = document.querySelector(".scene-container");
if (canvas) {
// Extract relevant properties manually
const dragEvent = new DragEvent("drop", {
bubbles: true,
cancelable: true,
dataTransfer: event.dataTransfer, // Attach dataTransfer manually ✅
});
console.log('dragEvent: ', dragEvent);
canvas.dispatchEvent(dragEvent);
}
};
return (
<div
ref={containerRef}
@@ -113,7 +115,14 @@ const RealTimeVisulization: React.FC = () => {
width: "100%",
borderRadius: isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
onDrop={handleDrop}
>
{/* {objects.map((obj) => (
<mesh key={obj.id} position={obj.position}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="green" />
</mesh>
))} */}
<Scene />
</div>
{activeModule === "visualization" && (
@@ -124,7 +133,7 @@ const RealTimeVisulization: React.FC = () => {
setSelectedZone={setSelectedZone}
/>
{!isPlaying && (
{!isPlaying && selectedZone?.zoneName !== "" && (
<AddButtons
hiddenPanels={hiddenPanels}
setHiddenPanels={setHiddenPanels}
@@ -134,6 +143,7 @@ const RealTimeVisulization: React.FC = () => {
)}
<Panel
hiddenPanels={hiddenPanels}
selectedZone={selectedZone}
setSelectedZone={setSelectedZone}
/>

View File

@@ -0,0 +1,96 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import { useSelectedZoneStore } from "../../../store/useZoneStore";
export default function ZoneCentreTarget() {
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(null);
const sphereRef = useRef<THREE.Mesh>(null);
const { camera, controls }: any = useThree();
useEffect(() => {
if (
selectedZone.zoneViewPortTarget &&
JSON.stringify(previousZoneCentre) !== JSON.stringify(selectedZone.zoneViewPortTarget)
) {
setPreviousZoneCentre(selectedZone.zoneViewPortTarget);
}
}, [selectedZone.zoneViewPortTarget, previousZoneCentre]);
const centrePoint = useMemo(() => {
if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null;
return previousZoneCentre.map((value, index) =>
(value + selectedZone.zoneViewPortTarget[index]) / 2
);
}, [previousZoneCentre, selectedZone.zoneViewPortTarget]);
useEffect(() => {
if (selectedZone.zoneName !== "") {
if (sphereRef.current) {
sphereRef.current.position.set(selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2]);
}
if (centrePoint) {
if (centrePoint.length > 0) {
let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
const worldUp = new THREE.Vector3(0, 0, 1);
const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
const up = new THREE.Vector3().crossVectors(direction, right).normalize();
const offsetPosition = up.clone().multiplyScalar(20);
camPosition.add(offsetPosition);
const setCam = async () => {
controls.setLookAt(centrePoint[0], 100, centrePoint[2], ...centrePoint, true);
setTimeout(() => {
controls?.setLookAt(
...camPosition.toArray(),
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
}, 400)
};
setCam();
} else {
let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
const worldUp = new THREE.Vector3(0, 0, 1);
const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
const up = new THREE.Vector3().crossVectors(direction, right).normalize();
const offsetPosition = up.clone().multiplyScalar(20);
camPosition.add(offsetPosition);
const setCam = async () => {
controls?.setLookAt(
...camPosition.toArray(),
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
};
setCam();
}
}
}
}, [selectedZone.zoneViewPortTarget, camera, controls]);
return (
<> </>
);
}