opt gesture

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-02-15 17:16:24 +08:00
parent 85292a3df2
commit 2c0597175d
3 changed files with 54 additions and 39 deletions

View File

@@ -117,7 +117,7 @@ class _GalleryViewerState extends State<GalleryViewer>
final gestureSettings = MediaQuery.maybeGestureSettingsOf(Get.context!); final gestureSettings = MediaQuery.maybeGestureSettingsOf(Get.context!);
_tapGestureRecognizer = ImageTapGestureRecognizer() _tapGestureRecognizer = ImageTapGestureRecognizer()
..onTap = _onTap // ..onTap = _onTap
..gestureSettings = gestureSettings; ..gestureSettings = gestureSettings;
if (PlatformUtils.isDesktop) { if (PlatformUtils.isDesktop) {
_tapGestureRecognizer.onSecondaryTapUp = _showDesktopMenu; _tapGestureRecognizer.onSecondaryTapUp = _showDesktopMenu;
@@ -127,6 +127,12 @@ class _GalleryViewerState extends State<GalleryViewer>
..onLongPress = _onLongPress ..onLongPress = _onLongPress
..gestureSettings = gestureSettings; ..gestureSettings = gestureSettings;
Future.delayed(const Duration(milliseconds: 410), () {
if (mounted) {
_tapGestureRecognizer.onTap = _onTap;
}
});
_animateController = AnimationController( _animateController = AnimationController(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
vsync: this, vsync: this,
@@ -244,6 +250,8 @@ class _GalleryViewerState extends State<GalleryViewer>
child: DecoratedBoxTransition( child: DecoratedBoxTransition(
decoration: _opacityAnimation, decoration: _opacityAnimation,
child: Stack( child: Stack(
fit: .expand,
alignment: .center,
clipBehavior: .none, clipBehavior: .none,
children: [ children: [
LayoutBuilder( LayoutBuilder(
@@ -566,28 +574,25 @@ class _GalleryViewerState extends State<GalleryViewer>
Widget child, Widget child,
ImageChunkEvent? loadingProgress, ImageChunkEvent? loadingProgress,
) { ) {
if (loadingProgress != null) { return Stack(
if (loadingProgress.cumulativeBytesLoaded != fit: .expand,
loadingProgress.expectedTotalBytes && alignment: .center,
loadingProgress.expectedTotalBytes != null) { clipBehavior: .none,
return Stack( children: [
fit: .expand, child,
alignment: .center, if (loadingProgress != null &&
clipBehavior: .none, loadingProgress.expectedTotalBytes != null &&
children: [ loadingProgress.cumulativeBytesLoaded !=
child, loadingProgress.expectedTotalBytes)
Center( Center(
child: LoadingIndicator( child: LoadingIndicator(
size: 39.4, size: 39.4,
progress: progress:
loadingProgress.cumulativeBytesLoaded / loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!, loadingProgress.expectedTotalBytes!,
),
), ),
], ),
); ],
} );
}
return child;
} }
} }

View File

@@ -17,7 +17,7 @@ class HeroDialogRoute<T> extends PageRoute<T> {
bool get opaque => false; bool get opaque => false;
@override @override
bool get barrierDismissible => true; bool get barrierDismissible => false;
@override @override
String? get barrierLabel => null; String? get barrierLabel => null;

View File

@@ -73,7 +73,7 @@ class Viewer extends StatefulWidget {
} }
class _ViewerState extends State<Viewer> with SingleTickerProviderStateMixin { class _ViewerState extends State<Viewer> with SingleTickerProviderStateMixin {
static const double _interactionEndFrictionCoefficient = 0.0001; // 0.0000135 double get _interactionEndFrictionCoefficient => 0.0001 * _scale; // 0.0000135
static const double _scaleFactor = kDefaultMouseScrollToScaleFactor; static const double _scaleFactor = kDefaultMouseScrollToScaleFactor;
_GestureType? _gestureType; _GestureType? _gestureType;
@@ -255,22 +255,31 @@ class _ViewerState extends State<Viewer> with SingleTickerProviderStateMixin {
..forward(from: 0); ..forward(from: 0);
} }
static bool _calc(Offset initialPosition, Offset lastPosition) {
final offset = lastPosition - initialPosition;
return offset.dy.abs() > offset.dx.abs();
}
void _onScaleStart(ScaleStartDetails details) { void _onScaleStart(ScaleStartDetails details) {
if (details.pointerCount == 1) { if (details.pointerCount == 1) {
if (widget.isLongPic) { if (widget.isLongPic) {
final imageHeight = _scale * _imageSize.height; final imageHeight = _scale * _imageSize.height;
final containerHeight = widget.containerSize.height; final containerHeight = widget.containerSize.height;
if (_scalePos != null && if (_scalePos != null && _calc(_scalePos!, details.focalPoint)) {
(_position.dy.equals( final bool drag;
(imageHeight - _scale * containerHeight) / 2, if (details.focalPoint.dy > _scalePos!.dy) {
1e-6, drag = _position.dy.equals(
) && (imageHeight - _scale * containerHeight) / 2,
details.focalPoint.dy > _scalePos!.dy) || 1e-6,
(_position.dy.equals(containerHeight - imageHeight, 1e-6) && );
details.focalPoint.dy < _scalePos!.dy)) { } else {
_gestureType = .drag; drag = _position.dy.equals(containerHeight - imageHeight, 1e-6);
widget.onDragStart?.call(details); }
return; if (drag) {
_gestureType = .drag;
widget.onDragStart?.call(details);
return;
}
} }
} else if (_scale == widget.minScale) { } else if (_scale == widget.minScale) {
_gestureType = .drag; _gestureType = .drag;
@@ -319,19 +328,20 @@ class _ViewerState extends State<Viewer> with SingleTickerProviderStateMixin {
if (details.velocity.pixelsPerSecond.distance < kMinFlingVelocity) { if (details.velocity.pixelsPerSecond.distance < kMinFlingVelocity) {
return; return;
} }
final drag = _interactionEndFrictionCoefficient;
final FrictionSimulation frictionSimulationX = FrictionSimulation( final FrictionSimulation frictionSimulationX = FrictionSimulation(
_interactionEndFrictionCoefficient, drag,
_position.dx, _position.dx,
details.velocity.pixelsPerSecond.dx, details.velocity.pixelsPerSecond.dx,
); );
final FrictionSimulation frictionSimulationY = FrictionSimulation( final FrictionSimulation frictionSimulationY = FrictionSimulation(
_interactionEndFrictionCoefficient, drag,
_position.dy, _position.dy,
details.velocity.pixelsPerSecond.dy, details.velocity.pixelsPerSecond.dy,
); );
final double tFinal = _getFinalTime( final double tFinal = _getFinalTime(
details.velocity.pixelsPerSecond.distance, details.velocity.pixelsPerSecond.distance,
_interactionEndFrictionCoefficient, drag,
); );
final position = _clampPosition( final position = _clampPosition(
Offset(frictionSimulationX.finalX, frictionSimulationY.finalX), Offset(frictionSimulationX.finalX, frictionSimulationY.finalX),