点击放大后锁定罗盘
This commit is contained in:
@ -1,9 +1,76 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class GridClipPaint extends StatelessWidget {
|
// class GridClipPaint extends StatelessWidget {
|
||||||
const GridClipPaint({Key key}) : super(key: key);
|
// const GridClipPaint(
|
||||||
|
// this.left,
|
||||||
|
// this.top,
|
||||||
|
// this.right,
|
||||||
|
// this.bottom, {
|
||||||
|
// Key key,
|
||||||
|
// }) : super(key: key);
|
||||||
|
//
|
||||||
|
// // ui.Image image;
|
||||||
|
// final double left;
|
||||||
|
// final double top;
|
||||||
|
// final double right;
|
||||||
|
// final double bottom;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// ui.Image image;
|
||||||
|
// return Container(
|
||||||
|
// color: Colors.transparent,
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// child: CustomPaint(
|
||||||
|
// // 使用CustomPaint 背景画板
|
||||||
|
// painter: ClipPainter(image),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
class GridClipPaint extends StatefulWidget {
|
||||||
|
const GridClipPaint(this.image, this.left, this.top, this.right, this.bottom,
|
||||||
|
{Key key})
|
||||||
|
: super(key: key);
|
||||||
|
final ui.Image image;
|
||||||
|
final double left;
|
||||||
|
final double top;
|
||||||
|
final double right;
|
||||||
|
final double bottom;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<GridClipPaint> createState() => _GridClipPaintState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GridClipPaintState extends State<GridClipPaint> {
|
||||||
|
ui.Image image;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() async {
|
||||||
|
// TODO: implement initState
|
||||||
|
// final appDataDirectory = await getApplicationDocumentsDirectory();
|
||||||
|
// File file = File(join(appDataDirectory.path, 'rotate_image'));
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ui.Image> imageLoader() {
|
||||||
|
ImageStream imageStream = const AssetImage("assets/images/arrow.png")
|
||||||
|
.resolve(ImageConfiguration(size: Size(700, 700)));
|
||||||
|
Completer<ui.Image> imageCompleter = Completer<ui.Image>();
|
||||||
|
|
||||||
|
void imageListener(ImageInfo info, bool synchronousCall) {
|
||||||
|
ui.Image image = info.image;
|
||||||
|
imageCompleter.complete(image);
|
||||||
|
imageStream.removeListener(ImageStreamListener(imageListener));
|
||||||
|
}
|
||||||
|
|
||||||
|
imageStream.addListener(ImageStreamListener(imageListener));
|
||||||
|
return imageCompleter.future;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -12,32 +79,37 @@ class GridClipPaint extends StatelessWidget {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
// 使用CustomPaint 背景画板
|
// 使用CustomPaint 背景画板
|
||||||
painter: ClipPainter(),
|
painter: ClipPainter(image),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClipPainter extends CustomPainter {
|
class ClipPainter extends CustomPainter {
|
||||||
ui.Image image;
|
final ui.Image image;
|
||||||
|
final double left;
|
||||||
|
final double top;
|
||||||
|
final double right;
|
||||||
|
final double bottom;
|
||||||
|
|
||||||
|
ClipPainter(this.image,
|
||||||
|
{this.left = 0.3, this.top = 0.3, this.right = 0.6, this.bottom = 0.6});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
// 创建画笔
|
// TODO: implement paint
|
||||||
final Paint paint = Paint();
|
Paint paint = Paint();
|
||||||
canvas.drawImageRect(
|
canvas.drawImageRect(
|
||||||
image,
|
image,
|
||||||
// Image(image: AssetImage("assets/images/arrow.png")),
|
Rect.fromLTRB(image.width * left, image.height * top,
|
||||||
Rect.fromLTRB(0, 0, 700 / 3, 700 / 3),
|
image.width * right, image.height * bottom),
|
||||||
Rect.fromLTWH(0, 0, 700 / 3, 700 / 3),
|
Rect.fromLTWH(0, 0, size.width, size.height),
|
||||||
paint);
|
paint);
|
||||||
// ..color = Colors.white
|
|
||||||
// ..strokeWidth = 2;
|
|
||||||
// 绘制线
|
|
||||||
// canvas.drawLine(const Offset(-400, 0), const Offset(400, 0), paintLine);
|
|
||||||
// canvas.drawLine(const Offset(0, 500), const Offset(0, -440), paintLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldRepaint(CustomPainter oldDelegate) => false;
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||||
|
// TODO: implement shouldRepaint
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io' as io;
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
import 'package:fengshui_compass/components/cross_paint.dart';
|
import 'package:fengshui_compass/components/cross_paint.dart';
|
||||||
import 'package:fengshui_compass/components/my_icon.dart';
|
import 'package:fengshui_compass/components/my_icon.dart';
|
||||||
import 'package:fengshui_compass/pages/login_page.dart';
|
import 'package:fengshui_compass/pages/login_page.dart';
|
||||||
import 'package:fengshui_compass/states/region.dart';
|
import 'package:fengshui_compass/states/region.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_serial_port_api/flutter_serial_port_api.dart';
|
import 'package:flutter_serial_port_api/flutter_serial_port_api.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:stream_transform/stream_transform.dart';
|
import 'package:stream_transform/stream_transform.dart';
|
||||||
|
|
||||||
|
import '../components/grid_clip_paint.dart';
|
||||||
import '../components/region_selector.dart';
|
import '../components/region_selector.dart';
|
||||||
import '../states/compass_image.dart';
|
import '../states/compass_image.dart';
|
||||||
import '../utils/recv_parse.dart';
|
import '../utils/recv_parse.dart';
|
||||||
@ -317,6 +322,9 @@ class _CompassState extends State<CompassPage> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double _scale = 1.0; // 放大倍数
|
||||||
|
Offset _origin = Offset(0.0, 0.0); // 放大原点
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
@ -372,24 +380,31 @@ class _CompassState extends State<CompassPage> {
|
|||||||
width: 700,
|
width: 700,
|
||||||
height: 700,
|
height: 700,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
// fit: StackFit.loose,
|
||||||
children: [
|
children: [
|
||||||
Transform.rotate(
|
ClipRect(
|
||||||
|
child: Transform.scale(
|
||||||
|
scale: _scale,
|
||||||
|
origin: _origin,
|
||||||
|
child: Transform.rotate(
|
||||||
angle: getCorrectionAngle((myaw +
|
angle: getCorrectionAngle((myaw +
|
||||||
regionProvider.declination)) *
|
regionProvider.declination)) *
|
||||||
2 *
|
2 *
|
||||||
pi /
|
pi /
|
||||||
360,
|
360,
|
||||||
|
child: ClipOval(
|
||||||
child: Image(
|
child: Image(
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 700,
|
height: 700,
|
||||||
// alignment: Alignment.lerp(a, b, t),
|
|
||||||
// image: compassImageProvider.rotateImage,
|
|
||||||
image: compassImageProvider
|
image: compassImageProvider
|
||||||
.rotateImage ??
|
.rotateImage ??
|
||||||
const AssetImage(
|
const AssetImage(
|
||||||
"assets/images/compass_rotated.png"),
|
"assets/images/compass_rotated.png"),
|
||||||
fit: BoxFit.contain),
|
fit: BoxFit.contain),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Align(
|
Align(
|
||||||
alignment: FractionalOffset(w_x, w_y),
|
alignment: FractionalOffset(w_x, w_y),
|
||||||
child: const Image(
|
child: const Image(
|
||||||
@ -403,35 +418,106 @@ class _CompassState extends State<CompassPage> {
|
|||||||
children: List.generate(
|
children: List.generate(
|
||||||
9,
|
9,
|
||||||
(index) => Container(
|
(index) => Container(
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
border: Border(
|
// border: Border(
|
||||||
bottom:
|
// bottom:
|
||||||
const BorderSide(width: 1),
|
// const BorderSide(width: 1),
|
||||||
right:
|
// right:
|
||||||
const BorderSide(width: 1),
|
// const BorderSide(width: 1),
|
||||||
left: index % 3 == 0
|
// left: index % 3 == 0
|
||||||
? const BorderSide(width: 1)
|
// ? const BorderSide(width: 1)
|
||||||
: BorderSide.none,
|
// : BorderSide.none,
|
||||||
top: index <= 2
|
// top: index <= 2
|
||||||
? const BorderSide(width: 1)
|
// ? const BorderSide(width: 1)
|
||||||
: BorderSide.none),
|
// : BorderSide.none),
|
||||||
color: const Color.fromRGBO(
|
// color: const Color.fromRGBO(
|
||||||
233, 233, 233, 0.3)),
|
// 233, 233, 233, 0.3)),
|
||||||
height: 700 / 3,
|
height: 700 / 3,
|
||||||
width: 700 / 3,
|
width: 700 / 3,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
child: Text('grid $index'),
|
// child: Text('grid $index'),
|
||||||
|
onDoubleTap: () {
|
||||||
|
setState(() {
|
||||||
|
_scale = 1.0;
|
||||||
|
});
|
||||||
|
},
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Fluttertoast.showToast(
|
if (isLock) {
|
||||||
msg: 'index: $index',
|
return;
|
||||||
backgroundColor: Colors.green,
|
}
|
||||||
textColor: Colors.white,
|
setState(() {
|
||||||
fontSize: 20.0);
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
_origin =
|
||||||
|
const Offset(-350, -350);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
_origin =
|
||||||
|
const Offset(0, -350);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_origin =
|
||||||
|
const Offset(350, -350);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_origin =
|
||||||
|
const Offset(-350, 0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
_origin = const Offset(0, 0);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
_origin =
|
||||||
|
const Offset(350, 0);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
_origin =
|
||||||
|
const Offset(-350, 350);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
_origin =
|
||||||
|
const Offset(0, 350);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
_origin =
|
||||||
|
const Offset(350, 350);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_scale = 3;
|
||||||
|
switchCompass();
|
||||||
|
// isLock = true;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
// ClipRRect(
|
||||||
|
// borderRadius: BorderRadius.circular(225.0),
|
||||||
|
// child: Image(
|
||||||
|
// width: 700,
|
||||||
|
// height: 700,
|
||||||
|
// // alignment: Alignment.lerp(a, b, t),
|
||||||
|
// // image: compassImageProvider.rotateImage,
|
||||||
|
// image: compassImageProvider
|
||||||
|
// .rotateImage ??
|
||||||
|
// const AssetImage(
|
||||||
|
// "assets/images/compass_rotated.png"),
|
||||||
|
// fit: BoxFit.contain),
|
||||||
|
// )
|
||||||
|
ClipRect(
|
||||||
|
child: Image(
|
||||||
|
width: 700,
|
||||||
|
height: 700,
|
||||||
|
color: Colors.red,
|
||||||
|
// alignment: Alignment.lerp(a, b, t),
|
||||||
|
// image: compassImageProvider.rotateImage,
|
||||||
|
image: const AssetImage(
|
||||||
|
"assets/images/compass_rotated.png"),
|
||||||
|
fit: BoxFit.contain),
|
||||||
|
clipper: MyClipper(),
|
||||||
)
|
)
|
||||||
|
// GridClipPaint(0,0,1,2)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -605,3 +691,11 @@ class _CompassState extends State<CompassPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyClipper extends CustomClipper<Rect> {
|
||||||
|
@override
|
||||||
|
Rect getClip(Size size) => Rect.fromLTWH(0.0, 0.0, 100.0, 100.0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldReclip(CustomClipper<Rect> oldClipper) => false;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user