From 0ffb331971b95023f4373502c8a01b374722a788 Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 25 Mar 2026 13:25:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=8F=E7=AA=97=E6=8B=96=E5=8A=A8?= =?UTF-8?q?=E5=90=8E=E8=87=AA=E5=8A=A8=E5=90=B8=E9=99=84=E5=88=B0=E5=B7=A6?= =?UTF-8?q?/=E5=8F=B3=E5=B1=8F=E5=B9=95=E8=BE=B9=E7=BC=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/LiveMiniPlayer.tsx | 22 +++++++++++++++------- components/MiniPlayer.tsx | 18 +++++++++++++----- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/components/LiveMiniPlayer.tsx b/components/LiveMiniPlayer.tsx index 50afa82..9be127c 100644 --- a/components/LiveMiniPlayer.tsx +++ b/components/LiveMiniPlayer.tsx @@ -49,14 +49,22 @@ export function LiveMiniPlayer() { const { width: sw, height: sh } = Dimensions.get('window'); const curX = (pan.x as any)._value; const curY = (pan.y as any)._value; - const clampedX = Math.max(-sw + MINI_W + 12, Math.min(12, curX)); + + // 吸附到左边缘或右边缘(取最近的一侧) + // container 默认 right:12,pan.x=0 为右侧,-(sw-MINI_W-24) 为左侧贴边 + const snapRight = 0; + const snapLeft = -(sw - MINI_W - 24); + const snapX = curX < snapLeft / 2 ? snapLeft : snapRight; + + // Y 轴仅做越界回弹,不吸附 const clampedY = Math.max(-sh + MINI_H + 60, Math.min(60, curY)); - if (curX !== clampedX || curY !== clampedY) { - Animated.spring(pan, { - toValue: { x: clampedX, y: clampedY }, - useNativeDriver: false, - }).start(); - } + + Animated.spring(pan, { + toValue: { x: snapX, y: clampedY }, + useNativeDriver: false, + tension: 120, + friction: 10, + }).start(); }, }), ).current; diff --git a/components/MiniPlayer.tsx b/components/MiniPlayer.tsx index 17a87b8..a1a307e 100644 --- a/components/MiniPlayer.tsx +++ b/components/MiniPlayer.tsx @@ -28,15 +28,23 @@ export function MiniPlayer() { onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }], { useNativeDriver: false }), onPanResponderRelease: () => { pan.flattenOffset(); - // Clamp to screen bounds const { width: sw, height: sh } = Dimensions.get('window'); const curX = (pan.x as any)._value; const curY = (pan.y as any)._value; - const clampedX = Math.max(-sw + MINI_W + 12, Math.min(12, curX)); + + // 吸附到左边缘或右边缘(取最近的一侧) + const snapRight = 0; + const snapLeft = -(sw - MINI_W - 24); + const snapX = curX < snapLeft / 2 ? snapLeft : snapRight; + const clampedY = Math.max(-sh + MINI_H + 60, Math.min(60, curY)); - if (curX !== clampedX || curY !== clampedY) { - Animated.spring(pan, { toValue: { x: clampedX, y: clampedY }, useNativeDriver: false }).start(); - } + + Animated.spring(pan, { + toValue: { x: snapX, y: clampedY }, + useNativeDriver: false, + tension: 120, + friction: 10, + }).start(); }, }) ).current;