64 lines
2.1 KiB
Dart
Executable File
64 lines
2.1 KiB
Dart
Executable File
import 'package:get/get.dart';
|
|
|
|
/// 导航栏透明度管理 Mixin
|
|
/// 用于统一管理页面导航栏的透明度变化
|
|
mixin KRAppBarOpacityMixin {
|
|
/// 导航栏透明度值
|
|
final RxDouble kr_appBarOpacity = 0.0.obs;
|
|
|
|
/// 上次滚动位置
|
|
double _lastOffset = 0;
|
|
|
|
/// 上次更新时间
|
|
double _lastUpdateTime = 0;
|
|
|
|
/// 滚动阈值
|
|
static const double _scrollThreshold = 100.0;
|
|
|
|
/// 最小透明度
|
|
static const double _minOpacity = 0.0;
|
|
|
|
/// 最大透明度
|
|
static const double _maxOpacity = 1.0;
|
|
|
|
/// 滚动速度因子
|
|
static const double _scrollSpeedFactor = 0.5;
|
|
|
|
/// 更新导航栏透明度
|
|
/// [scrollPixels] 当前滚动位置
|
|
void kr_updateAppBarOpacity(double scrollPixels) {
|
|
final currentTime = DateTime.now().millisecondsSinceEpoch.toDouble();
|
|
final deltaTime = currentTime - _lastUpdateTime;
|
|
_lastUpdateTime = currentTime;
|
|
|
|
// 计算滚动速度
|
|
final scrollDelta = scrollPixels - _lastOffset;
|
|
final scrollSpeed = scrollDelta.abs() / (deltaTime > 0 ? deltaTime : 1);
|
|
_lastOffset = scrollPixels;
|
|
|
|
// 根据滚动位置计算基础透明度
|
|
double baseOpacity = 0.0;
|
|
if (scrollPixels <= 0) {
|
|
baseOpacity = _minOpacity;
|
|
} else if (scrollPixels >= _scrollThreshold) {
|
|
baseOpacity = _maxOpacity;
|
|
} else {
|
|
// 使用平滑的插值函数计算透明度
|
|
baseOpacity = (scrollPixels / _scrollThreshold).clamp(_minOpacity, _maxOpacity);
|
|
// 使用平方根函数使透明度变化更加平滑
|
|
baseOpacity = baseOpacity * baseOpacity;
|
|
}
|
|
|
|
// 根据滚动速度调整透明度
|
|
double speedFactor = (scrollSpeed * _scrollSpeedFactor).clamp(0.0, 0.5);
|
|
double targetOpacity = baseOpacity + (speedFactor * 0.2); // 减小速度影响
|
|
|
|
// 平滑过渡到目标透明度
|
|
final currentOpacity = kr_appBarOpacity.value;
|
|
final opacityDelta = targetOpacity - currentOpacity;
|
|
final smoothFactor = 0.3; // 平滑因子,值越小过渡越平滑
|
|
|
|
kr_appBarOpacity.value = (currentOpacity + opacityDelta * smoothFactor)
|
|
.clamp(_minOpacity, _maxOpacity);
|
|
}
|
|
} |