From 138ece6fc6212befaf6715913751cced1d3534b4 Mon Sep 17 00:00:00 2001 From: WinUser01 Date: Wed, 11 May 2022 00:29:04 +0800 Subject: [PATCH] =?UTF-8?q?hyzp=5Fybqx-Commit162=EF=BC=9A=E4=BC=98?= =?UTF-8?q?=E5=8C=96my=5Fflutter=5Fdrag=5Fscale=E6=8F=92=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8C=E5=87=BB=E5=9B=BE=E7=89=87=E6=94=BE?= =?UTF-8?q?=E5=A4=A7=E5=90=8E=EF=BC=8C=E7=82=B9=E5=87=BB=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=BD=8D=E4=BA=8E=E5=AE=B9=E5=99=A8=E4=B8=AD=E5=A4=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/core/touchable_container.dart | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/lib/my_flutter_drag_scale/lib/core/touchable_container.dart b/lib/my_flutter_drag_scale/lib/core/touchable_container.dart index 3305049..a97c870 100644 --- a/lib/my_flutter_drag_scale/lib/core/touchable_container.dart +++ b/lib/my_flutter_drag_scale/lib/core/touchable_container.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import './custom_gesture_detector.dart' as gd; @@ -51,7 +53,7 @@ class _TouchableContainerState extends State @override void initState() { super.initState(); - _controller = new AnimationController(vsync: this)..addListener(_handleFlingAnimation); + _controller = AnimationController(vsync: this)..addListener(_handleFlingAnimation); } @override @@ -65,8 +67,30 @@ class _TouchableContainerState extends State //也就是最小值是原点0,0,点从最大值到0的区间,也就是这个图可以从最大值移动到原点 Offset _clampOffset(Offset offset) { final Size size = context.size; //容器的大小 - 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)); + // print("context.size = ${context.size}"); // context.size = Size(298.0, 298.0) + final Offset minOffset = Offset(size.width, size.height) * (1.0 - _scale); + return Offset(offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0)); + // return Offset(minOffset.dx / 2, minOffset.dy / 2); + } + + // 实现双击图片放大后,点击位置位于容器中央 + Offset _clampOffset2(Offset position) { + final Size size = context.size; //容器的大小 + // print("context.size = ${context.size}"); // context.size = Size(298.0, 298.0) + RenderBox renderBox = context.findRenderObject(); + Offset offsetTopLeft = renderBox.localToGlobal(Offset.zero); + print("offsetTopLeft = $offsetTopLeft"); // offsetTopLeft = Offset(31.0, 111.0) + + double x = position.dx - offsetTopLeft.dx; + x = max(x * _scale - size.width * _scale / 4, 0); + x = min(x, size.width * _scale / 2); + + double y = position.dy - offsetTopLeft.dy; + y = max(y * _scale - size.height * _scale / 4, 0); + y = min(y, size.height * _scale / 2); + print("Offset(x, y) = ${Offset(-x, -y)}"); + + return Offset(-x, -y); } void _handleFlingAnimation() { @@ -92,7 +116,7 @@ class _TouchableContainerState extends State // Ensure that image location under the focal point stays in the same place despite scaling. _offset = _clampOffset(details.focalPoint - _normalizedOffset * _scale); }); - ScaleChangedModel model = new ScaleChangedModel(scale: _scale, offset: _offset); + ScaleChangedModel model = ScaleChangedModel(scale: _scale, offset: _offset); if (widget.scaleChangedCallback != null) widget.scaleChangedCallback(model); } @@ -102,7 +126,7 @@ class _TouchableContainerState extends State final Offset direction = details.velocity.pixelsPerSecond / magnitude; final double distance = (Offset.zero & context.size).shortestSide; _flingAnimation = - new Tween(begin: _offset, end: _clampOffset(_offset + direction * distance)) + Tween(begin: _offset, end: _clampOffset(_offset + direction * distance)) .animate(_controller); _controller ..value = 0.0 @@ -111,33 +135,41 @@ class _TouchableContainerState extends State void _onDoubleTap(gd.DoubleDetails details) { _normalizedOffset = (details.pointerEvent.position - _offset) / _scale; + print("_scale = ${_scale}, _offset = ${_offset}"); + print("position = ${details.pointerEvent.position}, _normalizedOffset = ${_normalizedOffset}"); + // _scale = 1.0, _offset = Offset(0.0, 0.0) + // position = Offset(178.0, 260.7), _normalizedOffset = Offset(178.0, 260.7) if (!widget.doubleTapStillScale && _scale != 1.0) { setState(() { _scale = 1.0; _offset = Offset.zero; }); - ScaleChangedModel model = new ScaleChangedModel(scale: _scale, offset: _offset); + ScaleChangedModel model = ScaleChangedModel(scale: _scale, offset: _offset); if (widget.scaleChangedCallback != null) widget.scaleChangedCallback(model); return; } setState(() { if (widget.doubleTapStillScale) { _scale *= (1 + 0.5); + // Ensure that image location under the focal point stays in the same place despite scaling. + // _offset = doubleDownPositon; + _offset = _clampOffset(details.pointerEvent.position - _normalizedOffset * _scale); } else { _scale *= (2); + _offset = _clampOffset2(details.pointerEvent.position); + // _offset = Offset.zero; // 对齐左上角 + print("_scale = ${_scale}, _offset = ${_offset}"); + // _scale = 2.0, _offset = Offset(-175.3, -270.0) } - // Ensure that image location under the focal point stays in the same place despite scaling. - // _offset = doubleDownPositon; - _offset = _clampOffset(details.pointerEvent.position - _normalizedOffset * _scale); }); - ScaleChangedModel model = new ScaleChangedModel(scale: _scale, offset: _offset); + ScaleChangedModel model = ScaleChangedModel(scale: _scale, offset: _offset); if (widget.scaleChangedCallback != null) widget.scaleChangedCallback(model); } @override Widget build(BuildContext context) { - return new gd.GestureDetector( + return gd.GestureDetector( // onPanDown: _onPanDown, onDoubleTap: _onDoubleTap, onScaleStart: _handleOnScaleStart, @@ -151,8 +183,8 @@ class _TouchableContainerState extends State minWidth: double.maxFinite, minHeight: double.infinity, ), - child: new Transform( - transform: new Matrix4.identity() + child: Transform( + transform: Matrix4.identity() ..translate(_offset.dx, _offset.dy) ..scale(_scale, _scale, 1.0), child: widget.child),