Commit 8cd1b793 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Fix Gallery grid demo zoom (#6531)

parent 0fe5051f
...@@ -39,11 +39,11 @@ class GridPhotoViewer extends StatefulWidget { ...@@ -39,11 +39,11 @@ class GridPhotoViewer extends StatefulWidget {
class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProviderStateMixin { class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProviderStateMixin {
AnimationController _controller; AnimationController _controller;
double _lastScale = 1.0; Animation<Offset> _flingAnimation;
Offset _offset = Offset.zero;
double _scale = 1.0; double _scale = 1.0;
Point _lastFocalPoint = Point.origin; Offset _normalizedOffset;
Point _focalPoint = Point.origin; double _previousScale;
Animation<Point> _flingAnimation;
@override @override
void initState() { void initState() {
...@@ -58,30 +58,24 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv ...@@ -58,30 +58,24 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
super.dispose(); super.dispose();
} }
// The minimum value for the focal point is 0,0. If the size of this // The maximum offset value is 0,0. If the size of this renderer's box is w,h
// renderer's box is w,h then the maximum value of the focal point is // then the minimum offset value is w - _scale * w, h - _scale * h.
// (w * _scale - w)/_scale, (h * _scale - h)/_scale. Offset _clampOffset(Offset offset) {
Point _clampFocalPoint(Point point) {
final Size size = context.size; final Size size = context.size;
final double inverseScale = (_scale - 1.0) / _scale; final Offset minOffset = new Offset(size.width, size.height) * (1.0 - _scale);
final Point bottomRight = new Point( return new Offset(offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0));
size.width * inverseScale,
size.height * inverseScale,
);
return new Point(point.x.clamp(0.0, bottomRight.x), point.y.clamp(0.0, bottomRight.y));
} }
void _handleFlingAnimation() { void _handleFlingAnimation() {
setState(() { setState(() {
_focalPoint = _flingAnimation.value; _offset = _flingAnimation.value;
_lastFocalPoint = _focalPoint;
}); });
} }
void _handleOnScaleStart(ScaleStartDetails details) { void _handleOnScaleStart(ScaleStartDetails details) {
setState(() { setState(() {
_lastScale = 1.0; _previousScale = _scale;
_lastFocalPoint = details.focalPoint; _normalizedOffset = (details.focalPoint.toOffset() - _offset) / _scale;
// The fling animation stops if an input gesture starts. // The fling animation stops if an input gesture starts.
_controller.stop(); _controller.stop();
}); });
...@@ -89,10 +83,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv ...@@ -89,10 +83,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
void _handleOnScaleUpdate(ScaleUpdateDetails details) { void _handleOnScaleUpdate(ScaleUpdateDetails details) {
setState(() { setState(() {
_scale = (_scale + (details.scale - _lastScale)).clamp(1.0, 3.0); _scale = (_previousScale * details.scale).clamp(1.0, 4.0);
_lastScale = details.scale; // Ensure that image location under the focal point stays in the same place despite scaling.
_focalPoint = _clampFocalPoint(_focalPoint + (_lastFocalPoint - details.focalPoint)); _offset = _clampOffset(details.focalPoint.toOffset() - _normalizedOffset * _scale);
_lastFocalPoint = details.focalPoint;
}); });
} }
...@@ -102,9 +95,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv ...@@ -102,9 +95,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
return; return;
final Offset direction = details.velocity.pixelsPerSecond / magnitude; final Offset direction = details.velocity.pixelsPerSecond / magnitude;
final double distance = (Point.origin & context.size).shortestSide; final double distance = (Point.origin & context.size).shortestSide;
_flingAnimation = new Tween<Point>( _flingAnimation = new Tween<Offset>(
begin: _focalPoint, begin: _offset,
end: _clampFocalPoint(_focalPoint + direction * -distance) end: _clampOffset(_offset + direction * distance)
).animate(_controller); ).animate(_controller);
_controller _controller
..value = 0.0 ..value = 0.0
...@@ -121,7 +114,7 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv ...@@ -121,7 +114,7 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
onScaleEnd: _handleOnScaleEnd, onScaleEnd: _handleOnScaleEnd,
child: new Transform( child: new Transform(
transform: new Matrix4.identity() transform: new Matrix4.identity()
..translate(_focalPoint.x * (1.0 - _scale), _focalPoint.y * (1.0 - _scale)) ..translate(_offset.dx, _offset.dy)
..scale(_scale), ..scale(_scale),
child: new ClipRect( child: new ClipRect(
child: new Image.asset(config.photo.assetName, fit: ImageFit.cover) child: new Image.asset(config.photo.assetName, fit: ImageFit.cover)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment