Add mouse scroll speed setting. Close #471

This commit is contained in:
2025-08-24 19:52:24 +08:00
parent ac13807ef4
commit d308c2ac60
4 changed files with 60 additions and 17 deletions

View File

@@ -410,7 +410,8 @@
"Clear specific reader settings for all comics": "清除所有漫画的特殊阅读设置", "Clear specific reader settings for all comics": "清除所有漫画的特殊阅读设置",
"Clear specific reader settings for this comic": "清除该漫画的特殊阅读设置", "Clear specific reader settings for this comic": "清除该漫画的特殊阅读设置",
"Enable comic specific settings": "启用此漫画特定设置", "Enable comic specific settings": "启用此漫画特定设置",
"Ignore Certificate Errors": "忽略证书错误" "Ignore Certificate Errors": "忽略证书错误",
"Mouse scroll speed": "鼠标滚动速度"
}, },
"zh_TW": { "zh_TW": {
"Home": "首頁", "Home": "首頁",
@@ -823,6 +824,7 @@
"Clear specific reader settings for all comics": "清除所有漫畫的特殊閱讀設定", "Clear specific reader settings for all comics": "清除所有漫畫的特殊閱讀設定",
"Clear specific reader settings for this comic": "清除該漫畫的特殊閱讀設定", "Clear specific reader settings for this comic": "清除該漫畫的特殊閱讀設定",
"Enable comic specific settings": "啟用此漫畫特定設定", "Enable comic specific settings": "啟用此漫畫特定設定",
"Ignore Certificate Errors": "忽略證書錯誤" "Ignore Certificate Errors": "忽略證書錯誤",
"Mouse scroll speed": "滑鼠滾動速度"
} }
} }

View File

@@ -191,6 +191,7 @@ class Settings with ChangeNotifier {
'showSystemStatusBar': false, 'showSystemStatusBar': false,
'comicSpecificSettings': <String, Map<String, dynamic>>{}, 'comicSpecificSettings': <String, Map<String, dynamic>>{},
'ignoreBadCertificate': false, 'ignoreBadCertificate': false,
'readerScrollSpeed': 1.0, // 0.5 - 3.0
}; };
operator [](String key) { operator [](String key) {

View File

@@ -638,27 +638,52 @@ class _ContinuousModeState extends State<_ContinuousMode>
cacheImages(page); cacheImages(page);
} }
double? futurePosition; double? _futurePosition;
void smoothTo(double offset) { void smoothTo(double offset) {
futurePosition ??= scrollController.offset; if (HardwareKeyboard.instance.isShiftPressed) {
if (futurePosition! > scrollController.position.maxScrollExtent &&
offset > 0) {
return;
} else if (futurePosition! < scrollController.position.minScrollExtent &&
offset < 0) {
return; return;
} }
futurePosition = futurePosition! + offset * 1.2; var currentLocation = scrollController.position.pixels;
futurePosition = futurePosition!.clamp( var old = _futurePosition;
_futurePosition ??= currentLocation;
double k = (_futurePosition! - currentLocation).abs() / 1600 + 1;
final customSpeed = appdata.settings.getReaderSetting(
context.reader.cid,
context.reader.type.sourceKey,
"readerScrollSpeed",
);
if (customSpeed is num) {
k *= customSpeed;
}
_futurePosition = _futurePosition! + offset * k;
var beforeOffset = (_futurePosition! - currentLocation).abs();
_futurePosition = _futurePosition!.clamp(
scrollController.position.minScrollExtent, scrollController.position.minScrollExtent,
scrollController.position.maxScrollExtent, scrollController.position.maxScrollExtent,
); );
scrollController.animateTo( var afterOffset = (_futurePosition! - currentLocation).abs();
futurePosition!, if (_futurePosition == old) return;
duration: const Duration(milliseconds: 200), var target = _futurePosition!;
var duration = const Duration(milliseconds: 160);
if (afterOffset < beforeOffset) {
duration = duration * (afterOffset / beforeOffset);
if (duration < Duration(milliseconds: 10)) {
duration = Duration(milliseconds: 10);
}
}
scrollController
.animateTo(
_futurePosition!,
duration: duration,
curve: Curves.linear, curve: Curves.linear,
); )
.then((_) {
var current = scrollController.position.pixels;
if (current == target && current == _futurePosition) {
_futurePosition = null;
}
});
} }
void onPointerSignal(PointerSignalEvent event) { void onPointerSignal(PointerSignalEvent event) {
@@ -787,7 +812,7 @@ class _ContinuousModeState extends State<_ContinuousMode>
disableScroll = true; disableScroll = true;
}); });
} }
futurePosition = null; _futurePosition = null;
if (_isMouseScrolling) { if (_isMouseScrolling) {
setState(() { setState(() {
_isMouseScrolling = false; _isMouseScrolling = false;
@@ -1009,7 +1034,7 @@ class _ContinuousModeState extends State<_ContinuousMode>
@override @override
void toPage(int page) { void toPage(int page) {
itemScrollController.jumpTo(index: page); itemScrollController.jumpTo(index: page);
futurePosition = null; _futurePosition = null;
} }
@override @override

View File

@@ -177,6 +177,21 @@ class _ReaderSettingsState extends State<ReaderSettings> {
comicSource: isEnabledSpecificSettings ? widget.comicSource : null, comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
), ),
), ),
SliverAnimatedVisibility(
visible: appdata.settings['readerMode']!.startsWith('continuous'),
child: _SliderSetting(
title: "Mouse scroll speed".tl,
settingsIndex: "readerScrollSpeed",
interval: 0.1,
min: 0.5,
max: 3,
onChanged: () {
widget.onChanged?.call("readerScrollSpeed");
},
comicId: isEnabledSpecificSettings ? widget.comicId : null,
comicSource: isEnabledSpecificSettings ? widget.comicSource : null,
),
),
_SwitchSetting( _SwitchSetting(
title: 'Double tap to zoom'.tl, title: 'Double tap to zoom'.tl,
settingKey: 'enableDoubleTapToZoom', settingKey: 'enableDoubleTapToZoom',