动态鼠标滚动
一个可滚动小部件的包装器,可在所有平台上实现平滑的鼠标滚动。
功能
- 根据用户滚动速度进行平滑滚动动画。
- 使用 universal_io 检测平台是移动端还是桌面端。
- 自动检测是否使用了错误的ScrollPhysics,并使用 provider 进行更新。
- 如果您使用多个滚动小部件,请在应用程序周围包装一个ParentListener,以确保所有小部件都使用相同的物理效果。
- 完全调整滚动事件的距离和持续时间。
问题
Flutter 不为指针事件进行平滑滚动动画,导致用户体验不佳。一个名为 web_smooth_scroll 的包试图通过完全禁用默认滚动(现在移动端无法拖动)并监听指针事件来动画滚动控制器来解决此问题,该控制器只能以一种速度移动。
解决方案
为了仍然允许移动端的默认滚动,我检测用户的平台并自动更新,如果检测错误的话。为了以用户的滚动速度进行动画滚动,我首先计算SPS(每秒滚动次数)并将该值代入一个方程。当用户滚动得更快时,每个滚动动画的距离会增加,持续时间会减少。
当用户滚动速度非常快时(60+ SPS),会触发一个甩动滚动事件。此动画的距离和持续时间将远大于非甩动动画。在甩动动画激活期间,同一方向的滚动事件将被忽略,相反方向的滚动事件将取消(停止)滚动动画。
基本用法
- 提供子项会自动将其包装为 slivers。
DynMouseScroll(children: List<Widget>)
- 提供 slivers 作为小部件不会包装它们。
DynMouseScroll(slivers: List<Widget>)
- 或者,如果您想完全控制您的子小部件,请使用 builder。
DynMouseScroll(
builder: (context, controller, physics) => MyScrollableWidget(
controller: controller,
physics: physics))
- 要链接多个 DynMouseScroll 控件的 ScrollPhysics,请将它们包装在单个 ParentListener 中,并将 hasParentListener 设置为 true。
ParentListener(
child: Row(children: [
DynMouseScroll(hasParentListener: true, children: ...),
DynMouseScroll(hasParentListener: true, children: ...),
]))
调整
普通滚动事件和甩动滚动事件都有各自的距离和持续时间方程值。每个方程都有最小/最大 SPS 值。默认情况下,这些值为
- 普通滚动事件:1 -> 60
- 甩动滚动事件:60 -> 200
距离/持续时间的上限和下限
每个方程还有一个 Y 值的下限和上限,可以是距离或持续时间。'下限'值对应于最小SPS X值(左侧),如果设置为大于'上限'则为负斜率。例如,因为我希望持续时间随着速度的增加而减少,所以我将设置lowerValue > upperValue。
- SPS 1 (下限) = 距离:80, 持续时间:120
- SPS 59 (普通上限) = 距离:200, 持续时间:80
- SPS 60 (甩动下限) = 距离:400, 持续时间:500
- SPS 60+ (增加距离, 减少持续时间) = 距离:400+, 持续时间:500-
附加信息
距离和持续时间值如何计算
double val(double x) => Tween<double>(begin: lowerValue, end: upperValue)
.transform(curve.transform(x / maxSPS));
