mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
initial commit
This commit is contained in:
100
lib/components/scroll.dart
Normal file
100
lib/components/scroll.dart
Normal file
@@ -0,0 +1,100 @@
|
||||
part of 'components.dart';
|
||||
|
||||
class SmoothCustomScrollView extends StatelessWidget {
|
||||
const SmoothCustomScrollView({super.key, required this.slivers, this.controller});
|
||||
|
||||
final ScrollController? controller;
|
||||
|
||||
final List<Widget> slivers;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SmoothScrollProvider(
|
||||
controller: controller,
|
||||
builder: (context, controller, physics) {
|
||||
return CustomScrollView(
|
||||
controller: controller,
|
||||
physics: physics,
|
||||
slivers: slivers,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SmoothScrollProvider extends StatefulWidget {
|
||||
const SmoothScrollProvider({super.key, this.controller, required this.builder});
|
||||
|
||||
final ScrollController? controller;
|
||||
|
||||
final Widget Function(BuildContext, ScrollController, ScrollPhysics) builder;
|
||||
|
||||
static bool get isMouseScroll => _SmoothScrollProviderState._isMouseScroll;
|
||||
|
||||
@override
|
||||
State<SmoothScrollProvider> createState() => _SmoothScrollProviderState();
|
||||
}
|
||||
|
||||
class _SmoothScrollProviderState extends State<SmoothScrollProvider> {
|
||||
late final ScrollController _controller;
|
||||
|
||||
double? _futurePosition;
|
||||
|
||||
static bool _isMouseScroll = App.isDesktop;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controller = widget.controller ?? ScrollController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if(App.isMacOS) {
|
||||
return widget.builder(
|
||||
context,
|
||||
_controller,
|
||||
const ClampingScrollPhysics(),
|
||||
);
|
||||
}
|
||||
return Listener(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onPointerDown: (event) {
|
||||
if (_isMouseScroll) {
|
||||
setState(() {
|
||||
_isMouseScroll = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
onPointerSignal: (pointerSignal) {
|
||||
if (pointerSignal is PointerScrollEvent) {
|
||||
if (pointerSignal.kind == PointerDeviceKind.mouse &&
|
||||
!_isMouseScroll) {
|
||||
setState(() {
|
||||
_isMouseScroll = true;
|
||||
});
|
||||
}
|
||||
if (!_isMouseScroll) return;
|
||||
var currentLocation = _controller.position.pixels;
|
||||
_futurePosition ??= currentLocation;
|
||||
double k = (_futurePosition! - currentLocation).abs() / 1600 + 1;
|
||||
_futurePosition =
|
||||
_futurePosition! + pointerSignal.scrollDelta.dy * k;
|
||||
_futurePosition = _futurePosition!.clamp(
|
||||
_controller.position.minScrollExtent,
|
||||
_controller.position.maxScrollExtent);
|
||||
_controller.animateTo(_futurePosition!,
|
||||
duration: _fastAnimationDuration, curve: Curves.linear);
|
||||
}
|
||||
},
|
||||
child: widget.builder(
|
||||
context,
|
||||
_controller,
|
||||
_isMouseScroll
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: const ClampingScrollPhysics(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user