From dd486c3e50615cc06e5308809adfd48e0c19da1f Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 3 Feb 2024 13:01:03 +0800 Subject: [PATCH] Add mouse scroll to scale image --- lib/platform/media_query.dart | 2 ++ lib/platform/media_query_none.dart | 2 ++ lib/platform/media_query_web.dart | 5 +++++ lib/viewer/single.dart | 33 ++++++++++++++++++++++++++++-- 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 lib/platform/media_query.dart create mode 100644 lib/platform/media_query_none.dart create mode 100644 lib/platform/media_query_web.dart diff --git a/lib/platform/media_query.dart b/lib/platform/media_query.dart new file mode 100644 index 0000000..8be2ce6 --- /dev/null +++ b/lib/platform/media_query.dart @@ -0,0 +1,2 @@ +export './media_query_none.dart' + if (dart.library.html) './media_query_web.dart'; diff --git a/lib/platform/media_query_none.dart b/lib/platform/media_query_none.dart new file mode 100644 index 0000000..b8c6f74 --- /dev/null +++ b/lib/platform/media_query_none.dart @@ -0,0 +1,2 @@ +bool get pointerIsMouse => false; +bool get pointerIsTouch => false; diff --git a/lib/platform/media_query_web.dart b/lib/platform/media_query_web.dart new file mode 100644 index 0000000..39d7957 --- /dev/null +++ b/lib/platform/media_query_web.dart @@ -0,0 +1,5 @@ +// ignore: avoid_web_libraries_in_flutter +import 'dart:html'; + +bool get pointerIsMouse => window.matchMedia('(pointer: fine)').matches; +bool get pointerIsTouch => window.matchMedia('(pointer: coarse)').matches; diff --git a/lib/viewer/single.dart b/lib/viewer/single.dart index 551fc6e..4ab5528 100644 --- a/lib/viewer/single.dart +++ b/lib/viewer/single.dart @@ -1,6 +1,7 @@ import 'package:dio/dio.dart'; import 'package:dio_image_provider/dio_image_provider.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; @@ -14,6 +15,7 @@ import '../api/file.dart'; import '../api/gallery.dart'; import '../components/fit_text.dart'; import '../globals.dart'; +import '../platform/media_query.dart'; final _log = Logger("SinglePageViewer"); @@ -51,6 +53,7 @@ class _SinglePageViewer extends State Object? _error; bool _inited = false; bool _showMenu = false; + late PhotoViewController _photoViewController; void _updatePages() { if (_data == null) return; final displayAd = prefs.getBool("displayAd") ?? false; @@ -70,6 +73,7 @@ class _SinglePageViewer extends State _updatePages(); _files = widget.files; _back = "/gallery/${widget.gid}"; + _photoViewController = PhotoViewController(); super.initState(); } @@ -77,6 +81,7 @@ class _SinglePageViewer extends State void dispose() { _cancel?.cancel(); _pageController.dispose(); + _photoViewController.dispose(); super.dispose(); } @@ -125,6 +130,9 @@ class _SinglePageViewer extends State builder: (BuildContext context, int index) { final data = _pages![index]; final f = _files!.files[data.token]!.first; + if (_index != index) { + _photoViewController.reset(); + } return PhotoViewGalleryPageOptions( imageProvider: DioImage.string( api.getFileUrl(f.id), @@ -136,6 +144,7 @@ class _SinglePageViewer extends State transitionOnUserGestures: true, ), filterQuality: FilterQuality.high, + controller: _photoViewController, ); }, onPageChanged: (index) { @@ -184,10 +193,30 @@ class _SinglePageViewer extends State ); } + Widget _buildWithScrollSupport(BuildContext context, + {required Widget child}) { + if (kIsWeb && pointerIsTouch) { + return child; + } + return Listener( + onPointerSignal: (event) { + if (event is PointerScrollEvent && + event.kind == PointerDeviceKind.mouse) { + if (_photoViewController.scale != null) { + _photoViewController.scale = _photoViewController.scale! * + (1 - event.scrollDelta.dy / MediaQuery.of(context).size.height); + } + } + }, + child: child, + ); + } + Widget _buildViewer(BuildContext context) { return _buildWithTap(context, - child: - _buildWithKeyboardSupport(context, child: _buildGallery(context))); + child: _buildWithKeyboardSupport(context, + child: _buildWithScrollSupport(context, + child: _buildGallery(context)))); } Widget _buildTopAppBar(BuildContext context) {