hyzp_ybqx-Commit162:优化my_flutter_drag_scale插件,实现双击图片放大后,点击位置位于容器中央

master
WinUser01 4 years ago
parent 32958aeebc
commit 138ece6fc6

@ -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<TouchableContainer>
@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<TouchableContainer>
//000
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<TouchableContainer>
// 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<TouchableContainer>
final Offset direction = details.velocity.pixelsPerSecond / magnitude;
final double distance = (Offset.zero & context.size).shortestSide;
_flingAnimation =
new Tween<Offset>(begin: _offset, end: _clampOffset(_offset + direction * distance))
Tween<Offset>(begin: _offset, end: _clampOffset(_offset + direction * distance))
.animate(_controller);
_controller
..value = 0.0
@ -111,33 +135,41 @@ class _TouchableContainerState extends State<TouchableContainer>
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<TouchableContainer>
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),

Loading…
Cancel
Save