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>
)}
<button
title="collapse-btn"
className="collapse-icon option"
style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}
onClick={handleToggle}

View File

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

View File

@ -146,7 +146,8 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
return (
<>
{currentPath.length > 0 && (
<group >
// helper
<group visible={false}>
<Line points={currentPath} color="blue" lineWidth={3} />
{currentPath.map((point, index) => (
<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 * as THREE from "three";
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
import { useEditPosition, usezonePosition, usezoneTarget } from "../../../store/store";
import {
useEditPosition,
usezonePosition,
usezoneTarget,
} from "../../../store/store";
export default function ZoneCentreTarget() {
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(null);
const { selectedZone } = useSelectedZoneStore();
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(
null
);
const sphereRef = useRef<THREE.Mesh>(null);
const { camera, controls }: any = useThree();
const { zonePosition, setZonePosition } = usezonePosition();
const { zoneTarget, setZoneTarget } = usezoneTarget();
const { Edit, setEdit } = useEditPosition();
const { controls }: any = useThree();
const { setZonePosition } = usezonePosition();
const { setZoneTarget } = usezoneTarget();
const { Edit } = useEditPosition();
useEffect(() => {
if (
selectedZone.zoneViewPortTarget &&
JSON.stringify(previousZoneCentre) !== JSON.stringify(selectedZone.zoneViewPortTarget)
JSON.stringify(previousZoneCentre) !==
JSON.stringify(selectedZone.zoneViewPortTarget)
) {
setPreviousZoneCentre(selectedZone.zoneViewPortTarget);
}
@ -24,33 +31,30 @@ export default function ZoneCentreTarget() {
const centrePoint = useMemo(() => {
if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null;
return previousZoneCentre.map((value, index) =>
(value + selectedZone.zoneViewPortTarget[index]) / 2
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]);
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);
controls.setLookAt(
centrePoint[0],
100,
centrePoint[2],
...centrePoint,
true
);
setTimeout(() => {
controls?.setLookAt(
...selectedZone.zoneViewPortPosition,
@ -59,11 +63,10 @@ export default function ZoneCentreTarget() {
selectedZone.zoneViewPortTarget[2],
true
);
}, 400)
}, 400);
};
setCam();
} else {
const setCam = async () => {
controls?.setLookAt(
...selectedZone.zoneViewPortPosition,
@ -77,15 +80,22 @@ export default function ZoneCentreTarget() {
}
}
}
// 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])
setZonePosition([
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%;
height: 100%;
font-size: var(--font-size-regular);
background: linear-gradient(0deg,
background: linear-gradient(
0deg,
rgba(37, 24, 51, 0) 0%,
rgba(52, 41, 61, 0.5) 100%);
rgba(52, 41, 61, 0.5) 100%
);
pointer-events: none;
backdrop-filter: blur(8px);
opacity: 0;
@ -1480,26 +1482,48 @@
.sidebar-left-wrapper,
.sidebar-right-wrapper {
height: calc(54vh + 150px);
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-right-wrapper.closed {
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%;
}
}