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 {
class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProviderStateMixin {
AnimationController _controller;
double _lastScale = 1.0;
Animation<Offset> _flingAnimation;
Offset _offset = Offset.zero;
double _scale = 1.0;
Point _lastFocalPoint = Point.origin;
Point _focalPoint = Point.origin;
Animation<Point> _flingAnimation;
Offset _normalizedOffset;
double _previousScale;
@override
void initState() {
......@@ -58,30 +58,24 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
super.dispose();
}
// The minimum value for the focal point is 0,0. If the size of this
// renderer's box is w,h then the maximum value of the focal point is
// (w * _scale - w)/_scale, (h * _scale - h)/_scale.
Point _clampFocalPoint(Point point) {
// The maximum offset value is 0,0. If the size of this renderer's box is w,h
// then the minimum offset value is w - _scale * w, h - _scale * h.
Offset _clampOffset(Offset offset) {
final Size size = context.size;
final double inverseScale = (_scale - 1.0) / _scale;
final Point bottomRight = new Point(
size.width * inverseScale,
size.height * inverseScale,
);
return new Point(point.x.clamp(0.0, bottomRight.x), point.y.clamp(0.0, bottomRight.y));
final Offset minOffset = new Offset(size.width, size.height) * (1.0 - _scale);
return new Offset(offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0));
}
void _handleFlingAnimation() {
setState(() {
_focalPoint = _flingAnimation.value;
_lastFocalPoint = _focalPoint;
_offset = _flingAnimation.value;
});
}
void _handleOnScaleStart(ScaleStartDetails details) {
setState(() {
_lastScale = 1.0;
_lastFocalPoint = details.focalPoint;
_previousScale = _scale;
_normalizedOffset = (details.focalPoint.toOffset() - _offset) / _scale;
// The fling animation stops if an input gesture starts.
_controller.stop();
});
......@@ -89,10 +83,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
void _handleOnScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_scale = (_scale + (details.scale - _lastScale)).clamp(1.0, 3.0);
_lastScale = details.scale;
_focalPoint = _clampFocalPoint(_focalPoint + (_lastFocalPoint - details.focalPoint));
_lastFocalPoint = details.focalPoint;
_scale = (_previousScale * details.scale).clamp(1.0, 4.0);
// Ensure that image location under the focal point stays in the same place despite scaling.
_offset = _clampOffset(details.focalPoint.toOffset() - _normalizedOffset * _scale);
});
}
......@@ -102,9 +95,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
return;
final Offset direction = details.velocity.pixelsPerSecond / magnitude;
final double distance = (Point.origin & context.size).shortestSide;
_flingAnimation = new Tween<Point>(
begin: _focalPoint,
end: _clampFocalPoint(_focalPoint + direction * -distance)
_flingAnimation = new Tween<Offset>(
begin: _offset,
end: _clampOffset(_offset + direction * distance)
).animate(_controller);
_controller
..value = 0.0
......@@ -121,7 +114,7 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
onScaleEnd: _handleOnScaleEnd,
child: new Transform(
transform: new Matrix4.identity()
..translate(_focalPoint.x * (1.0 - _scale), _focalPoint.y * (1.0 - _scale))
..translate(_offset.dx, _offset.dy)
..scale(_scale),
child: new ClipRect(
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