Enhance sidebar animations: improve open/close transitions and add reveal effects for sidebar elements.

This commit is contained in:
Vishnu 2025-05-09 10:18:13 +05:30
parent c3b18aff78
commit 49da64140c
5 changed files with 146 additions and 105 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

@ -146,7 +146,8 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
return ( return (
<> <>
{currentPath.length > 0 && ( {currentPath.length > 0 && (
<group > // helper
<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) => (
<mesh key={index} position={point}> <mesh key={index} position={point}>

View File

@ -2,21 +2,28 @@ 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>(
null
);
const sphereRef = useRef<THREE.Mesh>(null); const sphereRef = useRef<THREE.Mesh>(null);
const { camera, controls }: any = useThree(); const { controls }: any = useThree();
const { zonePosition, setZonePosition } = usezonePosition(); const { setZonePosition } = usezonePosition();
const { zoneTarget, setZoneTarget } = usezoneTarget(); const { setZoneTarget } = usezoneTarget();
const { Edit, setEdit } = useEditPosition(); 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);
} }
@ -24,33 +31,30 @@ export default function ZoneCentreTarget() {
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]); }, [previousZoneCentre, selectedZone.zoneViewPortTarget]);
useEffect(() => { useEffect(() => {
if (selectedZone.zoneName !== "") { if (selectedZone.zoneName !== "") {
if (sphereRef.current) { if (sphereRef.current) {
sphereRef.current.position.set(selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2]); sphereRef.current.position.set(
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2]
);
} }
if (centrePoint) { if (centrePoint) {
if (centrePoint.length > 0) { 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 () => { const setCam = async () => {
controls.setLookAt(centrePoint[0], 100, centrePoint[2], ...centrePoint, true); controls.setLookAt(
centrePoint[0],
100,
centrePoint[2],
...centrePoint,
true
);
setTimeout(() => { setTimeout(() => {
controls?.setLookAt( controls?.setLookAt(
...selectedZone.zoneViewPortPosition, ...selectedZone.zoneViewPortPosition,
@ -59,11 +63,10 @@ export default function ZoneCentreTarget() {
selectedZone.zoneViewPortTarget[2], selectedZone.zoneViewPortTarget[2],
true true
); );
}, 400) }, 400);
}; };
setCam(); setCam();
} else { } else {
const setCam = async () => { const setCam = async () => {
controls?.setLookAt( controls?.setLookAt(
...selectedZone.zoneViewPortPosition, ...selectedZone.zoneViewPortPosition,
@ -77,15 +80,22 @@ export default function ZoneCentreTarget() {
} }
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedZone.zoneViewPortTarget]); }, [selectedZone.zoneViewPortTarget]);
useFrame(() => { useFrame(() => {
if (Edit) { if (Edit) {
setZonePosition([controls.getPosition().x, controls.getPosition().y, controls.getPosition().z]) setZonePosition([
setZoneTarget([controls.getTarget().x, controls.getTarget().y, controls.getTarget().z]) controls.getPosition().x,
controls.getPosition().y,
controls.getPosition().z,
]);
setZoneTarget([
controls.getTarget().x,
controls.getTarget().y,
controls.getTarget().z,
]);
} }
}) });
return ( 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(
0deg,
rgba(37, 24, 51, 0) 0%, rgba(37, 24, 51, 0) 0%,
rgba(52, 41, 61, 0.5) 100%); 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%;
}
} }