Flutter 可缩放小部件
Flutter Zoomable Widget
我想要构建的是一个小部件,可以使它的子小部件可缩放,类似于可缩放行为。
我想介绍的手势是
- 双指缩放
- 双击缩放
- 点击获取小部件的本地位置
这是我的插件计划:
ZoomableWidget(
child: // My custom Widget which should be zoomable.
)
这是我目前的进度:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
double _scale = 1.0;
double _previousScale;
@override
Widget build(BuildContext context) {
return ClipRect(
child: GestureDetector(
onScaleStart: (ScaleStartDetails details) {
_previousScale = _scale;
},
onScaleUpdate: (ScaleUpdateDetails details) {
setState(() {
_scale = _previousScale * details.scale;
});
},
onScaleEnd: (ScaleEndDetails details) {
_previousScale = null;
},
child: Transform(
transform: Matrix4.diagonal3(Vector3(_scale.clamp(1.0, 5.0),
_scale.clamp(1.0, 5.0), _scale.clamp(1.0, 5.0))),
alignment: FractionalOffset.center,
child: widget.child,
),
),
);
}
}
我遇到的问题是,我无法更改捏合的中心,因此即使我放大了角落,图像也只会在 (0,0) 处放大。另外,我无法访问水平拖动和垂直拖动来滚动小部件。
提前致谢。
现在一切正常,感谢@pskink 的参考。
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
Matrix4 matrix = Matrix4.identity();
@override
Widget build(BuildContext context) {
return MatrixGestureDetector(
onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
setState(() {
matrix = m;
});
},
child: Transform(
transform: matrix,
child: widget.child,
),
);
}
}
您可以使用 Zoom Widget Zoom Widget 只需要设置 canvas 尺寸和子尺寸
Zoom(
width: 1800,
height: 1800,
child: Center(
child: Text("Happy zoom!!"),
)
);
我喜欢 de resolution,你应该把它放在 pub 中打包,你甚至可以放一些自定义选项,在我的代码中,我双击以重置缩放并锁定旋转。
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
Matrix4 matrix = Matrix4.identity();
Matrix4 zerada = Matrix4.identity();
@override
Widget build(BuildContext context) {
return GestureDetector(
onDoubleTap: (){
setState(() {
matrix = zerada;
});
},
child: MatrixGestureDetector(
shouldRotate: false,
onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
setState(() {
matrix = m;
});
},
child: Transform(
transform: matrix,
child: widget.child,
),
),
);
}
}
作为 MatrixGestureDetector 的替代品,您可以使用 photo_view 包:https://pub.dev/packages/photo_view
它对屏幕限制有很好的限制,所以你不能拖动 child off-screen,点击 min/max 尺寸时的反弹效果,以及许多其他选项。
它可以像这样与自定义 child 一起使用:
PhotoView.customChild(
child: <your widget>
)
从 Flutter 1.20, InteractiveViewer 开始,小部件支持开箱即用的平移和缩放。
要使任何小部件可缩放,您只需将 child 包装为 InteractiveViewer
.
@override
Widget build(BuildContext context) {
return Center(
child: InteractiveViewer(
panEnabled: false, // Set it to false to prevent panning.
boundaryMargin: EdgeInsets.all(80),
minScale: 0.5,
maxScale: 4,
child: FlutterLogo(size: 200),
),
);
}
我想要构建的是一个小部件,可以使它的子小部件可缩放,类似于可缩放行为。
我想介绍的手势是
- 双指缩放
- 双击缩放
- 点击获取小部件的本地位置
这是我的插件计划:
ZoomableWidget(
child: // My custom Widget which should be zoomable.
)
这是我目前的进度:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
double _scale = 1.0;
double _previousScale;
@override
Widget build(BuildContext context) {
return ClipRect(
child: GestureDetector(
onScaleStart: (ScaleStartDetails details) {
_previousScale = _scale;
},
onScaleUpdate: (ScaleUpdateDetails details) {
setState(() {
_scale = _previousScale * details.scale;
});
},
onScaleEnd: (ScaleEndDetails details) {
_previousScale = null;
},
child: Transform(
transform: Matrix4.diagonal3(Vector3(_scale.clamp(1.0, 5.0),
_scale.clamp(1.0, 5.0), _scale.clamp(1.0, 5.0))),
alignment: FractionalOffset.center,
child: widget.child,
),
),
);
}
}
我遇到的问题是,我无法更改捏合的中心,因此即使我放大了角落,图像也只会在 (0,0) 处放大。另外,我无法访问水平拖动和垂直拖动来滚动小部件。
提前致谢。
现在一切正常,感谢@pskink 的参考。
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
Matrix4 matrix = Matrix4.identity();
@override
Widget build(BuildContext context) {
return MatrixGestureDetector(
onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
setState(() {
matrix = m;
});
},
child: Transform(
transform: matrix,
child: widget.child,
),
);
}
}
您可以使用 Zoom Widget Zoom Widget 只需要设置 canvas 尺寸和子尺寸
Zoom(
width: 1800,
height: 1800,
child: Center(
child: Text("Happy zoom!!"),
)
);
我喜欢 de resolution,你应该把它放在 pub 中打包,你甚至可以放一些自定义选项,在我的代码中,我双击以重置缩放并锁定旋转。
import 'package:flutter/material.dart';
import 'package:matrix_gesture_detector/matrix_gesture_detector.dart';
class ZoomableWidget extends StatefulWidget {
final Widget child;
const ZoomableWidget({Key key, this.child}) : super(key: key);
@override
_ZoomableWidgetState createState() => _ZoomableWidgetState();
}
class _ZoomableWidgetState extends State<ZoomableWidget> {
Matrix4 matrix = Matrix4.identity();
Matrix4 zerada = Matrix4.identity();
@override
Widget build(BuildContext context) {
return GestureDetector(
onDoubleTap: (){
setState(() {
matrix = zerada;
});
},
child: MatrixGestureDetector(
shouldRotate: false,
onMatrixUpdate: (Matrix4 m, Matrix4 tm, Matrix4 sm, Matrix4 rm) {
setState(() {
matrix = m;
});
},
child: Transform(
transform: matrix,
child: widget.child,
),
),
);
}
}
作为 MatrixGestureDetector 的替代品,您可以使用 photo_view 包:https://pub.dev/packages/photo_view
它对屏幕限制有很好的限制,所以你不能拖动 child off-screen,点击 min/max 尺寸时的反弹效果,以及许多其他选项。
它可以像这样与自定义 child 一起使用:
PhotoView.customChild(
child: <your widget>
)
从 Flutter 1.20, InteractiveViewer 开始,小部件支持开箱即用的平移和缩放。
要使任何小部件可缩放,您只需将 child 包装为 InteractiveViewer
.
@override
Widget build(BuildContext context) {
return Center(
child: InteractiveViewer(
panEnabled: false, // Set it to false to prevent panning.
boundaryMargin: EdgeInsets.all(80),
minScale: 0.5,
maxScale: 4,
child: FlutterLogo(size: 200),
),
);
}