Merge remote-tracking branch 'origin/v2-ui' into v2

This commit is contained in:
Jerald-Golden-B 2025-05-09 16:56:29 +05:30
commit 111b835f78
8 changed files with 197 additions and 119 deletions

View File

@ -123,6 +123,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
</div> </div>
)} )}
<button <button
title="collapse-btn"
className="collapse-icon option" className="collapse-icon option"
style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }} style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}
onClick={handleToggle} onClick={handleToggle}

View File

@ -12,6 +12,7 @@ import CollabUserIcon from "./collabUserIcon";
import useModuleStore from "../../../store/useModuleStore"; import useModuleStore from "../../../store/useModuleStore";
import { getAvatarColor } from "../functions/getAvatarColor"; import { getAvatarColor } from "../functions/getAvatarColor";
import { useSelectedUserStore } from "../../../store/useCollabStore"; import { useSelectedUserStore } from "../../../store/useCollabStore";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
const CamModelsGroup = () => { const CamModelsGroup = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -21,6 +22,7 @@ const CamModelsGroup = () => {
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { selectedUser, setSelectedUser } = useSelectedUserStore(); const { selectedUser, setSelectedUser } = useSelectedUserStore();
const { isPlaying } = usePlayButtonStore();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
const loader = new GLTFLoader(); const loader = new GLTFLoader();
@ -244,7 +246,8 @@ const CamModelsGroup = () => {
object={cam} object={cam}
visible={ visible={
selectedUser?.name !== cam.userData.userName && selectedUser?.name !== cam.userData.userName &&
activeModule !== "visualization" activeModule !== "visualization" &&
!isPlaying
} }
> >
<Html <Html
@ -258,7 +261,9 @@ const CamModelsGroup = () => {
fontFamily: "Arial, sans-serif", fontFamily: "Arial, sans-serif",
display: `${activeModule !== "visualization" ? "" : "none"}`, display: `${activeModule !== "visualization" ? "" : "none"}`,
opacity: `${ opacity: `${
selectedUser?.name !== cam.userData.userName ? 1 : 0 selectedUser?.name !== cam.userData.userName && !isPlaying
? 1
: 0
}`, }`,
transition: "opacity .2s ease", transition: "opacity .2s ease",
}} }}

View File

@ -1,17 +1,20 @@
import React from 'react' import React from "react";
import MachineInstance from './machineInstance/machineInstance' import MachineInstance from "./machineInstance/machineInstance";
import { useMachineStore } from '../../../../store/simulation/useMachineStore'; import { useMachineStore } from "../../../../store/simulation/useMachineStore";
import MachineContentUi from "../../ui3d/MachineContentUi";
function MachineInstances() { function MachineInstances() {
const { machines } = useMachineStore(); const { machines } = useMachineStore();
return ( return (
<> <>
{machines.map((machine: MachineStatus) => ( {machines.map((machine: MachineStatus) => (
<MachineInstance key={machine.modelUuid} machineDetail={machine} /> <React.Fragment key={machine.modelUuid}>
))} <MachineInstance machineDetail={machine} />
<MachineContentUi machine={machine} />
</> </React.Fragment>
) ))}
</>
);
} }
export default MachineInstances export default MachineInstances;

View File

@ -0,0 +1,34 @@
import { Html } from "@react-three/drei";
import React from "react";
import AssetDetailsCard from "../../../components/ui/simulation/AssetDetailsCard";
import { Vector3 } from "three";
type MachineContentUiProps = {
machine: MachineStatus;
};
const MachineContentUi: React.FC<MachineContentUiProps> = ({ machine }) => {
return (
<Html
// data
position={
new Vector3(
machine.position[0],
machine.point.position[1],
machine.position[2]
)
}
// class none
// other
zIndexRange={[1, 0]}
prepend
sprite
center
distanceFactor={20}
>
<AssetDetailsCard name={machine.modelName} status={machine.state} />
</Html>
);
};
export default MachineContentUi;

View File

@ -3,11 +3,11 @@ import React from "react";
import AssetDetailsCard from "../../../components/ui/simulation/AssetDetailsCard"; import AssetDetailsCard from "../../../components/ui/simulation/AssetDetailsCard";
import { Vector3 } from "three"; import { Vector3 } from "three";
type VehicleContentUiProps = { type RoboticArmContentUiProps = {
roboticArm: ArmBotStatus; roboticArm: ArmBotStatus;
}; };
const RoboticArmContentUi: React.FC<VehicleContentUiProps> = ({ roboticArm }) => { const RoboticArmContentUi: React.FC<RoboticArmContentUiProps> = ({ roboticArm }) => {
return ( return (
<Html <Html
// data // data

View File

@ -146,6 +146,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
return ( return (
<> <>
{currentPath.length > 0 && ( {currentPath.length > 0 && (
// helper
<group visible={false}> <group visible={false}>
<Line points={currentPath} color="blue" lineWidth={3} /> <Line points={currentPath} color="blue" lineWidth={3} />
{currentPath.map((point, index) => ( {currentPath.map((point, index) => (

View File

@ -2,90 +2,100 @@ import { useEffect, useMemo, useRef, useState } from "react";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import * as THREE from "three"; import * as THREE from "three";
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore"; import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
import { useEditPosition, usezonePosition, usezoneTarget } from "../../../store/store"; import {
useEditPosition,
usezonePosition,
usezoneTarget,
} from "../../../store/store";
export default function ZoneCentreTarget() { export default function ZoneCentreTarget() {
const { selectedZone, setSelectedZone } = useSelectedZoneStore(); const { selectedZone } = useSelectedZoneStore();
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(null); const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(
const sphereRef = useRef<THREE.Mesh>(null); null
const { camera, controls }: any = useThree(); );
const { zonePosition, setZonePosition } = usezonePosition(); const sphereRef = useRef<THREE.Mesh>(null);
const { zoneTarget, setZoneTarget } = usezoneTarget(); const { controls }: any = useThree();
const { Edit, setEdit } = useEditPosition(); const { setZonePosition } = usezonePosition();
const { setZoneTarget } = usezoneTarget();
const { Edit } = useEditPosition();
useEffect(() => { useEffect(() => {
if ( if (
selectedZone.zoneViewPortTarget && selectedZone.zoneViewPortTarget &&
JSON.stringify(previousZoneCentre) !== JSON.stringify(selectedZone.zoneViewPortTarget) JSON.stringify(previousZoneCentre) !==
) { JSON.stringify(selectedZone.zoneViewPortTarget)
setPreviousZoneCentre(selectedZone.zoneViewPortTarget); ) {
} setPreviousZoneCentre(selectedZone.zoneViewPortTarget);
}, [selectedZone.zoneViewPortTarget, previousZoneCentre]); }
}, [selectedZone.zoneViewPortTarget, previousZoneCentre]);
const centrePoint = useMemo(() => { const centrePoint = useMemo(() => {
if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null; if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null;
return previousZoneCentre.map((value, index) => return previousZoneCentre.map(
(value + selectedZone.zoneViewPortTarget[index]) / 2 (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(
...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
}, 400)
};
setCam();
} else {
const setCam = async () => {
controls?.setLookAt(
...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
};
setCam();
}
}
}
}, [selectedZone.zoneViewPortTarget]);
useFrame(() => {
if (Edit) {
setZonePosition([controls.getPosition().x, controls.getPosition().y, controls.getPosition().z])
setZoneTarget([controls.getTarget().x, controls.getTarget().y, controls.getTarget().z])
}
})
return (
<> </>
); );
}, [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) {
const setCam = async () => {
controls.setLookAt(
centrePoint[0],
100,
centrePoint[2],
...centrePoint,
true
);
setTimeout(() => {
controls?.setLookAt(
...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
}, 400);
};
setCam();
} else {
const setCam = async () => {
controls?.setLookAt(
...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
};
setCam();
}
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedZone.zoneViewPortTarget]);
useFrame(() => {
if (Edit) {
setZonePosition([
controls.getPosition().x,
controls.getPosition().y,
controls.getPosition().z,
]);
setZoneTarget([
controls.getTarget().x,
controls.getTarget().y,
controls.getTarget().z,
]);
}
});
return <></>;
} }

View File

@ -1437,9 +1437,11 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
font-size: var(--font-size-regular); font-size: var(--font-size-regular);
background: linear-gradient(0deg, background: linear-gradient(
rgba(37, 24, 51, 0) 0%, 0deg,
rgba(52, 41, 61, 0.5) 100%); rgba(37, 24, 51, 0) 0%,
rgba(52, 41, 61, 0.5) 100%
);
pointer-events: none; pointer-events: none;
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
opacity: 0; opacity: 0;
@ -1480,26 +1482,48 @@
.sidebar-left-wrapper, .sidebar-left-wrapper,
.sidebar-right-wrapper { .sidebar-right-wrapper {
height: calc(54vh + 150px);
transition: height 0.2s ease-in-out; transition: height 0.2s ease-in-out;
.sidebar-left-container {
height: 100%;
.sidebar-left-content-container{
max-height: 80%;
.widget-left-sideBar{
height: 80%;
.widget2D.widgets-wrapper{
min-height: 50vh;
height: 60%;
}
}
}
}
} }
.sidebar-left-wrapper.closed, .sidebar-left-wrapper.closed,
.sidebar-right-wrapper.closed { .sidebar-right-wrapper.closed {
height: 52px; animation: closeSidebar 0.2s linear forwards;
} }
.sidebar-left-wrapper.open,
.sidebar-right-wrapper.open {
height: fit-content;
animation: openSidebar 0.2s linear;
.sidebar-right-container,
.sidebar-left-container {
opacity: 0;
animation: revealSmooth 0.3s 0.1s linear forwards;
}
}
@keyframes revealSmooth {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes closeSidebar{
from{
height: 60%;
}
to{
height: 52px;
}
}
@keyframes openSidebar{
from{
height: 52px;
}
to{
height: 60%;
}
}