| | |
| | | bannerList: any[]; |
| | | /** 行程状态 */ |
| | | tripStatus: HomeTripStatus; |
| | | /** 是否展示订单状态卡片 */ |
| | | shouldShowOrderStatusCard: boolean; |
| | | }; |
| | | |
| | | /** |
| | |
| | | const pendingHeight = useRef<number | null>(null); |
| | | |
| | | /** |
| | | * 根据当前面板高度计算回中按钮透明度。 |
| | | */ |
| | | const resolveOriginOpacity = (height: number, min: number, full: number) => { |
| | | const range = full - min; |
| | | if (range <= 0 || !Number.isFinite(height)) { |
| | | return 1; |
| | | } |
| | | const fadeDistance = 100; |
| | | const moveDistance = height - min; |
| | | const factor = moveDistance / fadeDistance; |
| | | return 1 - Math.min(1, Math.max(0, factor)); |
| | | }; |
| | | |
| | | /** |
| | | * 统一重置拖拽态,避免触摸中断或前后台切换后停留在中间高度。 |
| | | */ |
| | | const resetDragState = (shouldRecalculateHeight = false) => { |
| | | isDragging.current = false; |
| | | if (dragFrame.current) { |
| | | clearTimeout(dragFrame.current); |
| | | dragFrame.current = null; |
| | | } |
| | | pendingHeight.current = null; |
| | | setBoxHeight(minHeight.current || 280); |
| | | setOriginOpacity(1); |
| | | if (shouldRecalculateHeight) { |
| | | calculateBoxHeight(); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 计算拖拽容器高度边界。 |
| | | */ |
| | | const calculateBoxHeight = () => { |
| | |
| | | |
| | | // 仅在初始化或当前高度为旧的最大高度时更新高度,避免拖拽过程中被意外重置 |
| | | setBoxHeight(prev => { |
| | | const nextHeight = (prev === 280 || prev === oldFullHeight || oldFullHeight === 0) |
| | | ? baseHeight |
| | | : prev; |
| | | setOriginOpacity(resolveOriginOpacity(nextHeight, minHeight.current, fullHeight.current)); |
| | | if (prev === 280 || prev === oldFullHeight || oldFullHeight === 0) { |
| | | return baseHeight; |
| | | } |
| | |
| | | minHeight.current = 280; |
| | | fullHeight.current = 280; |
| | | setBoxHeight(280); |
| | | setOriginOpacity(1); |
| | | } |
| | | }).exec(); |
| | | }, 500); |
| | |
| | | |
| | | useEffect(() => { |
| | | calculateBoxHeight(); |
| | | }, [deps.bannerList, deps.tripStatus]); |
| | | }, [deps.bannerList, deps.tripStatus, deps.shouldShowOrderStatusCard]); |
| | | |
| | | useEffect(() => { |
| | | const range = fullHeight.current - minHeight.current; |
| | | if (range > 0 && typeof boxHeight === 'number') { |
| | | // 更加积极的淡出策略:向上滑动 100px 即可完全淡出 |
| | | const fadeDistance = 100; |
| | | const moveDistance = boxHeight - minHeight.current; |
| | | const factor = moveDistance / fadeDistance; |
| | | const next = 1 - Math.min(1, Math.max(0, factor)); |
| | | setOriginOpacity(next); |
| | | if (typeof boxHeight === 'number') { |
| | | setOriginOpacity(resolveOriginOpacity(boxHeight, minHeight.current, fullHeight.current)); |
| | | } |
| | | }, [boxHeight]); |
| | | |
| | | useEffect(() => { |
| | | const handleAppHide = () => { |
| | | resetDragState(false); |
| | | }; |
| | | const handleAppShow = () => { |
| | | resetDragState(true); |
| | | }; |
| | | Taro.onAppHide(handleAppHide); |
| | | Taro.onAppShow(handleAppShow); |
| | | return () => { |
| | | Taro.offAppHide(handleAppHide); |
| | | Taro.offAppShow(handleAppShow); |
| | | }; |
| | | }, []); |
| | | |
| | | return { |
| | | boxHeight, |
| | |
| | | handleTouchStart, |
| | | handleTouchMove, |
| | | handleTouchEnd, |
| | | calculateBoxHeight |
| | | calculateBoxHeight, |
| | | resetDragState |
| | | }; |
| | | } |