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

View File

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

View File

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