Enhance sidebar animations: improve open/close transitions and add reveal effects for sidebar elements.
This commit is contained in:
parent
c3b18aff78
commit
49da64140c
|
@ -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}
|
||||||
|
|
|
@ -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",
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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 <></>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue