#101 pinch-to-zoom looks for neighbouring thumbnails when focal point not on thumbnail

This commit is contained in:
Thibault Deckers 2021-11-12 10:33:41 +09:00
parent deb3298b54
commit b0ba159996

View file

@ -55,14 +55,16 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
// when scaling ends and we apply the new extent, so we prevent this // when scaling ends and we apply the new extent, so we prevent this
// until we scaled and scrolled to the tile in the new grid // until we scaled and scrolled to the tile in the new grid
if (_applyingScale) return; if (_applyingScale) return;
final tileExtentController = context.read<TileExtentController>();
final scrollableContext = widget.scrollableKey.currentContext!; final scrollableContext = widget.scrollableKey.currentContext!;
final scrollableBox = scrollableContext.findRenderObject() as RenderBox; final scrollableBox = scrollableContext.findRenderObject() as RenderBox;
final result = BoxHitTestResult(); final renderMetaData = _getClosestRenderMetadata(
scrollableBox.hitTest(result, position: details.localFocalPoint); box: scrollableBox,
localFocalPoint: details.localFocalPoint,
// find `RenderObject`s at the gesture focal point spacing: tileExtentController.spacing,
U? firstOf<U>(BoxHitTestResult result) => result.path.firstWhereOrNull((el) => el.target is U)?.target as U?; );
final renderMetaData = firstOf<RenderMetaData>(result);
// abort if we cannot find an image to show on overlay // abort if we cannot find an image to show on overlay
if (renderMetaData == null) return; if (renderMetaData == null) return;
_metadata = renderMetaData.metaData; _metadata = renderMetaData.metaData;
@ -72,7 +74,6 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
// not the same as `MediaQuery.size.width`, because of screen insets/padding // not the same as `MediaQuery.size.width`, because of screen insets/padding
final gridWidth = scrollableBox.size.width; final gridWidth = scrollableBox.size.width;
final tileExtentController = context.read<TileExtentController>();
_extentMin = tileExtentController.effectiveExtentMin; _extentMin = tileExtentController.effectiveExtentMin;
_extentMax = tileExtentController.effectiveExtentMax; _extentMax = tileExtentController.effectiveExtentMax;
@ -138,6 +139,25 @@ class _GridScaleGestureDetectorState<T> extends State<GridScaleGestureDetector<T
), ),
); );
} }
RenderMetaData? _getClosestRenderMetadata({
required RenderBox box,
required Offset localFocalPoint,
required double spacing,
}) {
var position = localFocalPoint;
while (position.dx > 0 && position.dy > 0) {
final result = BoxHitTestResult();
box.hitTest(result, position: position);
// find `RenderObject`s at the gesture focal point
U? firstOf<U>(BoxHitTestResult result) => result.path.firstWhereOrNull((el) => el.target is U)?.target as U?;
final renderMetaData = firstOf<RenderMetaData>(result);
if (renderMetaData != null) return renderMetaData;
position = position.translate(-spacing, -spacing);
}
return null;
}
} }
class ScaleOverlay extends StatefulWidget { class ScaleOverlay extends StatefulWidget {