首先是移动、旋转、放大缩小
平移旋转伸缩.gif
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class ScalePageView extends StatefulWidget {
const ScalePageView({Key? key}) : super(key: key);
@override
State<ScalePageView> createState() => _ScalePageViewState();
}
class _ScalePageViewState extends State<ScalePageView> {
double _top = 100.0;
double _left = 100.0;
double _width = 200;
double _baseWidth = 200;
double _rotation = 0.0;
double _baseRotation = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Positioned(
top: _top,
left: _left,
child: GestureDetector(
onScaleStart: (_){
_baseWidth = _width;
_baseRotation = _rotation;
},
onScaleUpdate: (ScaleUpdateDetails e){
setState((){
_left += e.focalPointDelta.dx;//水平方向偏移量
_top += e.focalPointDelta.dy; //竖直方向偏移量
_rotation = _baseRotation + e.rotation;//选转量
_width = _baseWidth * e.scale.clamp(0.8, 5); //缩小放大
});
},
//不可以同时使用onPanUpdate和onScaleUpdate,因为onScaleUpdate是onPanUpdate的父类
//同时使用的话会报错scale is a superset of pan
// onPanUpdate: (e){
//
// },
child: Transform.rotate(
angle: _rotation,
child: Container(
width: _width ,
height: _width ,
color: Colors.red,
),
),
)
)
],
),
);
}
//系统提供的InteractiveViewer,不适合项目仅供参考
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// body: Container(
// height: double.infinity,
// width: double.infinity,
// alignment: Alignment.center,
// color: Colors.red.withAlpha(33),
// child: InteractiveViewer(
// ///只能沿着坐标轴滑动,就是横着或者竖着滑动
// alignPanAxis: false,
//
// ///是否能够用手指滑动
// panEnabled: true,
//
// ///子控件可以移动的范围
// boundaryMargin: EdgeInsets.all(double.infinity),
//
// ///是否开启缩放
// scaleEnabled: true,
//
// ///放大系数
// maxScale: 2.5,
//
// ///缩小系数
// minScale: 0.3,
//
// ///是否约束
// constrained: false,
// onInteractionStart: (details){
// print("onInteractionStart----"+details.toString());
// },
// onInteractionEnd: (details){
// print("onInteractionEnd----"+details.toString());
// },
// onInteractionUpdate: (details){
// print("onInteractionUpdate----"+details.toString());
//
// },
// child: Row(
// children: [
// Container(width: 100, height: 100, color: Colors.red,),
// ],
// ),
// ),
// ),
// );
// }
}
2.画笔工具
画笔.gif
import 'package:flutter/material.dart';
class DrawingBoard extends StatefulWidget {
const DrawingBoard({Key? key}) : super(key: key);
@override
State<DrawingBoard> createState() => _DrawingBoardState();
}
class _DrawingBoardState extends State<DrawingBoard> {
final List<List<Offset>> _path = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Paint"),
actions: [
TextButton(onPressed: (){
setState((){
_path.removeLast();
});
}, child: const Text("撤销", style: TextStyle(color: Colors.black, fontSize: 16),)),
],
),
body: Listener(
onPointerDown: (PointerDownEvent pointerDownEvent){
setState((){
_path.add([pointerDownEvent.localPosition]);
});
},
onPointerMove: (PointerMoveEvent pointerMoveEvent){
setState((){
_path[_path.length-1].add(pointerMoveEvent.localPosition);
});
},
onPointerUp: (PointerUpEvent pointerUpEvent){
setState((){
_path[_path.length-1].add(pointerUpEvent.localPosition);
});
},
onPointerCancel: (PointerCancelEvent pointerCancelEvent){
setState((){
_path[_path.length-1].add(pointerCancelEvent.localPosition);
});
},
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: CustomPaint(
painter: DrawingBoardPainter(_path),
),
),
),
);
}
}
class DrawingBoardPainter extends CustomPainter {
final List<List<Offset>> path;
DrawingBoardPainter(this.path);
final Paint _paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 10;
// ..strokeJoin = StrokeJoin.round;
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
path.forEach((list) {
Path path = Path();
for(int i = 0; i < list.length; i++){
if(i == 0){
path.moveTo(list[i].dx, list[i].dy);
}else{
path.lineTo(list[i].dx, list[i].dy);
}
}
canvas.drawPath(path, _paint);
});
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
网友评论