|
|
@ -11,20 +11,25 @@ class TranslationModeSelector { |
|
|
static void show(bool isDarkMode, {Offset? anchor}) { |
|
|
static void show(bool isDarkMode, {Offset? anchor}) { |
|
|
final controller = Get.find<TranslationController>(); |
|
|
final controller = Get.find<TranslationController>(); |
|
|
|
|
|
|
|
|
// 计算缩放对齐点(-1..1)。如果未提供 anchor,则从底部中间展开 |
|
|
// 总是从悬浮按钮位置展开,不依赖传入的anchor参数 |
|
|
Alignment alignment = Alignment.bottomCenter; |
|
|
final Size screenSize = MediaQuery.of(Get.context!).size; |
|
|
if (anchor != null) { |
|
|
final Offset floatingButtonPos = controller.floatingButtonPosition.value; |
|
|
final Size screenSize = MediaQuery.of(Get.context!).size; |
|
|
|
|
|
final double ax = (anchor.dx / screenSize.width) * 2 - 1; |
|
|
// 计算悬浮按钮的中心点位置(从右下角偏移转换为屏幕坐标) |
|
|
final double ay = (anchor.dy / screenSize.height) * 2 - 1; |
|
|
final double buttonSize = 56.0; // 悬浮按钮的大小 |
|
|
alignment = Alignment(ax, ay); |
|
|
final double buttonCenterX = screenSize.width - floatingButtonPos.dx - buttonSize / 2; |
|
|
} |
|
|
final double buttonCenterY = screenSize.height - floatingButtonPos.dy - buttonSize / 2; |
|
|
|
|
|
|
|
|
|
|
|
// 计算缩放对齐点(-1..1) |
|
|
|
|
|
final double ax = (buttonCenterX / screenSize.width) * 2 - 1; |
|
|
|
|
|
final double ay = (buttonCenterY / screenSize.height) * 2 - 1; |
|
|
|
|
|
final Alignment alignment = Alignment(ax, ay); |
|
|
|
|
|
|
|
|
Get.generalDialog( |
|
|
Get.generalDialog( |
|
|
barrierLabel: 'translation_mode_selector', |
|
|
barrierLabel: 'translation_mode_selector', |
|
|
barrierDismissible: true, |
|
|
barrierDismissible: true, // 允许点击背景关闭 |
|
|
barrierColor: Colors.black.withOpacity(0.35), |
|
|
barrierColor: Colors.transparent, // 设置为透明,让自定义模糊层处理点击 |
|
|
transitionDuration: const Duration(milliseconds: 250), |
|
|
transitionDuration: const Duration(milliseconds: 300), |
|
|
pageBuilder: (context, animation, secondaryAnimation) { |
|
|
pageBuilder: (context, animation, secondaryAnimation) { |
|
|
return const SizedBox.shrink(); |
|
|
return const SizedBox.shrink(); |
|
|
}, |
|
|
}, |
|
|
@ -35,17 +40,22 @@ class TranslationModeSelector { |
|
|
reverseCurve: Curves.easeInCubic); |
|
|
reverseCurve: Curves.easeInCubic); |
|
|
return Stack( |
|
|
return Stack( |
|
|
children: [ |
|
|
children: [ |
|
|
// 模糊背景 |
|
|
// 修复:将模糊背景放在可点击区域 |
|
|
Positioned.fill( |
|
|
GestureDetector( |
|
|
|
|
|
onTap: () => Get.back(), // 添加点击关闭功能 |
|
|
child: BackdropFilter( |
|
|
child: BackdropFilter( |
|
|
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), |
|
|
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), |
|
|
child: Container(color: Colors.transparent), |
|
|
child: Container( |
|
|
|
|
|
color: isDarkMode |
|
|
|
|
|
? Colors.black.withOpacity(0.55) |
|
|
|
|
|
: Colors.grey.withOpacity(0.95), // 添加半透明背景 |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
// 将缩放应用在一个全屏容器上,以便 alignment 以屏幕为参考 |
|
|
// 内容区域 |
|
|
ScaleTransition( |
|
|
ScaleTransition( |
|
|
alignment: alignment, |
|
|
alignment: alignment, |
|
|
scale: Tween<double>(begin: 0.0, end: 1.0).animate(curved), |
|
|
scale: Tween<double>(begin: 0.1, end: 1.0).animate(curved), |
|
|
child: FadeTransition( |
|
|
child: FadeTransition( |
|
|
opacity: curved, |
|
|
opacity: curved, |
|
|
child: SizedBox.expand( |
|
|
child: SizedBox.expand( |
|
|
@ -127,19 +137,19 @@ class TranslationModeSelector { |
|
|
} |
|
|
} |
|
|
: null, |
|
|
: null, |
|
|
), |
|
|
), |
|
|
SizedBox(height: 24.w), |
|
|
SizedBox(height: 64.w), |
|
|
GestureDetector( |
|
|
// GestureDetector( |
|
|
onTap: () => Get.back(), |
|
|
// onTap: () => Get.back(), |
|
|
child: Container( |
|
|
// child: Container( |
|
|
width: 42, |
|
|
// width: 42, |
|
|
height: 42, |
|
|
// height: 42, |
|
|
decoration: BoxDecoration( |
|
|
// decoration: BoxDecoration( |
|
|
color: Colors.black.withValues(alpha: 0.8), |
|
|
// color: Colors.black.withValues(alpha: 0.8), |
|
|
borderRadius: BorderRadius.circular(50), |
|
|
// borderRadius: BorderRadius.circular(50), |
|
|
), |
|
|
// ), |
|
|
child: const Icon(Icons.close, color: Colors.white), |
|
|
// child: const Icon(Icons.close, color: Colors.white), |
|
|
), |
|
|
// ), |
|
|
), |
|
|
// ), |
|
|
if (Platform.isAndroid) SizedBox(height: 20.h), |
|
|
if (Platform.isAndroid) SizedBox(height: 20.h), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
|