master
parent
c026a96bf0
commit
ef3bd3509e
|
|
@ -1,5 +1,5 @@
|
||||||
import { motion } from "motion/react";
|
import { motion } from "motion/react";
|
||||||
import { useContext, useState } from "react";
|
import { useContext } from "react";
|
||||||
import collapseMenuImg1 from "~/assets/images/map_bi/content/collapse_menu1.png";
|
import collapseMenuImg1 from "~/assets/images/map_bi/content/collapse_menu1.png";
|
||||||
import collapseMenuImg2 from "~/assets/images/map_bi/content/collapse_menu2.png";
|
import collapseMenuImg2 from "~/assets/images/map_bi/content/collapse_menu2.png";
|
||||||
import collapseMenuBg1 from "~/assets/images/map_bi/content/collapse_menu_bg1.png";
|
import collapseMenuBg1 from "~/assets/images/map_bi/content/collapse_menu_bg1.png";
|
||||||
|
|
@ -31,8 +31,6 @@ import "./index.less";
|
||||||
|
|
||||||
function Content(props) {
|
function Content(props) {
|
||||||
const { currentPort, currentBranchOffice, pureMap, bottomUtilsCurrentIndex } = useContext(Context);
|
const { currentPort, currentBranchOffice, pureMap, bottomUtilsCurrentIndex } = useContext(Context);
|
||||||
const [collapseLeft, setCollapseLeft] = useState(false);
|
|
||||||
const [collapseRight, setCollapseRight] = useState(false);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
controls: indexInfoControls,
|
controls: indexInfoControls,
|
||||||
|
|
@ -46,10 +44,10 @@ function Content(props) {
|
||||||
controls: leftControls,
|
controls: leftControls,
|
||||||
displayedContent: leftDisplayedContent,
|
displayedContent: leftDisplayedContent,
|
||||||
isVisible: isLeftVisible,
|
isVisible: isLeftVisible,
|
||||||
|
isCollapsed: isLeftCollapsed,
|
||||||
handleCollapse: handleLeftCollapse,
|
handleCollapse: handleLeftCollapse,
|
||||||
} = useContentAnimation({
|
} = useContentAnimation({
|
||||||
currentContent: { currentPort, currentBranchOffice, bottomUtilsCurrentIndex },
|
currentContent: { currentPort, currentBranchOffice, bottomUtilsCurrentIndex },
|
||||||
isCollapsed: collapseLeft,
|
|
||||||
side: "left",
|
side: "left",
|
||||||
isPureMap: pureMap,
|
isPureMap: pureMap,
|
||||||
type: "panel",
|
type: "panel",
|
||||||
|
|
@ -59,10 +57,10 @@ function Content(props) {
|
||||||
controls: rightControls,
|
controls: rightControls,
|
||||||
displayedContent: rightDisplayedContent,
|
displayedContent: rightDisplayedContent,
|
||||||
isVisible: isRightVisible,
|
isVisible: isRightVisible,
|
||||||
|
isCollapsed: isRightCollapsed,
|
||||||
handleCollapse: handleRightCollapse,
|
handleCollapse: handleRightCollapse,
|
||||||
} = useContentAnimation({
|
} = useContentAnimation({
|
||||||
currentContent: { currentBranchOffice, bottomUtilsCurrentIndex },
|
currentContent: { currentBranchOffice, bottomUtilsCurrentIndex },
|
||||||
isCollapsed: collapseRight,
|
|
||||||
side: "right",
|
side: "right",
|
||||||
isPureMap: pureMap,
|
isPureMap: pureMap,
|
||||||
type: "panel",
|
type: "panel",
|
||||||
|
|
@ -162,9 +160,9 @@ function Content(props) {
|
||||||
if (currentPort === "00003" && !currentBranchOffice) {
|
if (currentPort === "00003" && !currentBranchOffice) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`collapse_menu port left ${collapseLeft ? "active" : ""}`}
|
className={`collapse_menu port left ${isLeftCollapsed ? "active" : ""}`}
|
||||||
style={{ backgroundImage: `url(${collapseMenuBg1})` }}
|
style={{ backgroundImage: `url(${collapseMenuBg1})` }}
|
||||||
onClick={() => handleLeftCollapse(setCollapseLeft)}
|
onClick={() => handleLeftCollapse()}
|
||||||
>
|
>
|
||||||
<img src={collapseMenuImg1} alt="" />
|
<img src={collapseMenuImg1} alt="" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -178,18 +176,18 @@ function Content(props) {
|
||||||
<>
|
<>
|
||||||
{bottomUtilsCurrentType !== "camera" && (
|
{bottomUtilsCurrentType !== "camera" && (
|
||||||
<div
|
<div
|
||||||
className={`collapse_menu branch_office left ${collapseLeft ? "active" : ""}`}
|
className={`collapse_menu branch_office left ${isLeftCollapsed ? "active" : ""}`}
|
||||||
style={{ backgroundImage: `url(${collapseMenuBg2})` }}
|
style={{ backgroundImage: `url(${collapseMenuBg2})` }}
|
||||||
onClick={() => handleLeftCollapse(setCollapseLeft)}
|
onClick={() => handleLeftCollapse()}
|
||||||
>
|
>
|
||||||
<img src={collapseMenuImg2} alt="" />
|
<img src={collapseMenuImg2} alt="" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{bottomUtilsCurrentIndex === -1 && (
|
{bottomUtilsCurrentIndex === -1 && (
|
||||||
<div
|
<div
|
||||||
className={`collapse_menu branch_office right ${collapseRight ? "active" : ""}`}
|
className={`collapse_menu branch_office right ${isRightCollapsed ? "active" : ""}`}
|
||||||
style={{ backgroundImage: `url(${collapseMenuBg2})` }}
|
style={{ backgroundImage: `url(${collapseMenuBg2})` }}
|
||||||
onClick={() => handleRightCollapse(setCollapseRight)}
|
onClick={() => handleRightCollapse()}
|
||||||
>
|
>
|
||||||
<img src={collapseMenuImg2} alt="" />
|
<img src={collapseMenuImg2} alt="" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import { useEffect, useRef, useState } from "react";
|
||||||
*
|
*
|
||||||
* @param {object} params - 参数对象
|
* @param {object} params - 参数对象
|
||||||
* @param {object} params.currentContent - 当前要显示的内容状态(包含 currentPort、currentBranchOffice、bottomUtilsCurrentIndex 等)
|
* @param {object} params.currentContent - 当前要显示的内容状态(包含 currentPort、currentBranchOffice、bottomUtilsCurrentIndex 等)
|
||||||
* @param {boolean} params.isCollapsed - 当前是否处于折叠状态(仅 panel 类型)
|
|
||||||
* @param {string} params.side - 'left' 或 'right',控制动画方向(仅 panel 类型)
|
* @param {string} params.side - 'left' 或 'right',控制动画方向(仅 panel 类型)
|
||||||
* @param {boolean} params.isPureMap - 是否为纯地图模式(仅 panel 类型)
|
* @param {boolean} params.isPureMap - 是否为纯地图模式(仅 panel 类型)
|
||||||
* @param {string} params.type - 动画类型:"index" 或 "panel"(默认 "panel")
|
* @param {string} params.type - 动画类型:"index" 或 "panel"(默认 "panel")
|
||||||
|
|
@ -19,11 +18,11 @@ import { useEffect, useRef, useState } from "react";
|
||||||
* - controls: motion 动画控制器
|
* - controls: motion 动画控制器
|
||||||
* - displayedContent: 延迟显示的内容状态(仅 panel 类型)
|
* - displayedContent: 延迟显示的内容状态(仅 panel 类型)
|
||||||
* - isVisible: 元素可见性状态
|
* - isVisible: 元素可见性状态
|
||||||
|
* - isCollapsed: 折叠状态(仅 panel 类型)
|
||||||
* - handleCollapse: 处理折叠/展开的函数(仅 panel 类型)
|
* - handleCollapse: 处理折叠/展开的函数(仅 panel 类型)
|
||||||
*/
|
*/
|
||||||
export function useContentAnimation({
|
export function useContentAnimation({
|
||||||
currentContent,
|
currentContent,
|
||||||
isCollapsed = false,
|
|
||||||
side = "left",
|
side = "left",
|
||||||
isPureMap = false,
|
isPureMap = false,
|
||||||
type = "panel",
|
type = "panel",
|
||||||
|
|
@ -44,10 +43,18 @@ export function useContentAnimation({
|
||||||
// 标记是否是首次渲染(首次渲染不执行离开动画,直接进入)
|
// 标记是否是首次渲染(首次渲染不执行离开动画,直接进入)
|
||||||
const isFirstRender = useRef(true);
|
const isFirstRender = useRef(true);
|
||||||
|
|
||||||
|
// 折叠状态(仅 panel 类型使用)
|
||||||
|
// true: 面板被折叠
|
||||||
|
// false: 面板展开
|
||||||
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
||||||
|
|
||||||
// 延迟显示的内容状态(仅 panel 类型使用)
|
// 延迟显示的内容状态(仅 panel 类型使用)
|
||||||
// 作用:在内容切换时,先显示旧内容,动画完成后再更新为新内容
|
// 作用:在内容切换时,先显示旧内容,动画完成后再更新为新内容
|
||||||
const [displayedContent, setDisplayedContent] = useState(type === "index" ? {} : currentContent);
|
const [displayedContent, setDisplayedContent] = useState(type === "index" ? {} : currentContent);
|
||||||
|
|
||||||
|
// 标记是否正在手动处理折叠/展开(防止 useEffect 干预)
|
||||||
|
const isManualCollapseAnimating = useRef(false);
|
||||||
|
|
||||||
// ==================== IndexInfo 类型的缩放动画逻辑 ====================
|
// ==================== IndexInfo 类型的缩放动画逻辑 ====================
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -145,21 +152,20 @@ export function useContentAnimation({
|
||||||
|
|
||||||
// ==================== 折叠/展开处理 ====================
|
// ==================== 折叠/展开处理 ====================
|
||||||
|
|
||||||
// 标记是否正在手动处理折叠/展开(防止 useEffect 干预)
|
|
||||||
const isManualCollapseAnimating = useRef(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理折叠按钮点击事件
|
* 处理折叠按钮点击事件
|
||||||
* @param {Function} setCollapseState - setState 函数,用于更新折叠状态
|
|
||||||
*/
|
*/
|
||||||
const handleCollapse = (setCollapseState) => {
|
const handleCollapse = () => {
|
||||||
if (isCollapsed) {
|
if (isCollapsed) {
|
||||||
// ==================== 展开逻辑 ====================
|
// ==================== 展开逻辑 ====================
|
||||||
|
// 标记开始手动处理折叠/展开动画(阻止 useEffect 干预)
|
||||||
|
isManualCollapseAnimating.current = true;
|
||||||
|
|
||||||
// 1. 先同步显示内容(确保显示最新的内容)
|
// 1. 先同步显示内容(确保显示最新的内容)
|
||||||
setDisplayedContent(currentContent);
|
setDisplayedContent(currentContent);
|
||||||
|
|
||||||
// 2. 更新折叠状态
|
// 2. 更新折叠状态
|
||||||
setCollapseState(false);
|
setIsCollapsed(false);
|
||||||
|
|
||||||
// 3. 显示元素
|
// 3. 显示元素
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
|
@ -178,6 +184,9 @@ export function useContentAnimation({
|
||||||
x: 0, // 移动到正常位置
|
x: 0, // 移动到正常位置
|
||||||
opacity: 1, // 淡入
|
opacity: 1, // 淡入
|
||||||
transition: { duration: 0.5, ease: "easeOut" },
|
transition: { duration: 0.5, ease: "easeOut" },
|
||||||
|
}).then(() => {
|
||||||
|
// 动画完成后清除手动处理标记
|
||||||
|
isManualCollapseAnimating.current = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -198,7 +207,7 @@ export function useContentAnimation({
|
||||||
setIsVisible(false);
|
setIsVisible(false);
|
||||||
|
|
||||||
// 2. 更新折叠状态为 true
|
// 2. 更新折叠状态为 true
|
||||||
setCollapseState(true);
|
setIsCollapsed(true);
|
||||||
|
|
||||||
// 3. 清除手动处理标记
|
// 3. 清除手动处理标记
|
||||||
isManualCollapseAnimating.current = false;
|
isManualCollapseAnimating.current = false;
|
||||||
|
|
@ -357,6 +366,7 @@ export function useContentAnimation({
|
||||||
controls, // motion 动画控制器
|
controls, // motion 动画控制器
|
||||||
displayedContent, // 延迟显示的内容(用于动画过渡)
|
displayedContent, // 延迟显示的内容(用于动画过渡)
|
||||||
isVisible, // 元素可见性状态
|
isVisible, // 元素可见性状态
|
||||||
|
isCollapsed, // 折叠状态
|
||||||
handleCollapse, // 折叠/展开处理函数
|
handleCollapse, // 折叠/展开处理函数
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue