【发布时间】:2020-01-02 20:37:08
【问题描述】:
几天以来,我试图在图像缩放(放大/缩小)时在图像上保留一个绘制的圆圈(使用CustomPainter)。要渲染图像并启用缩放手势,我使用photo_view。只要没有缩放,我就可以根据视口的变化移动圆圈。所有值(比例、偏移)都由 PhotoViewController 作为流提供,如下所示:
main.dart
import 'package:backtrack/markerPainter.dart';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'dart:math' as math;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Offset position;
Offset startPosition;
Offset scaleChange;
Offset offsetToCenter;
double initialScale;
Offset forPoint;
PhotoViewScaleStateController controller;
PhotoViewController controller2;
double lastscale;
@override
void initState() {
super.initState();
controller = PhotoViewScaleStateController();
controller2 = PhotoViewController();
controller2.outputStateStream.listen((onData) {
// print("position change: " + onData.position.toString());
// print("scale change: " + onData.scale.toString());
if (position != null) {
setState(() {
final scaleToUser = initialScale + (initialScale - onData.scale);
//Change to the unscaled point inverted to reflect the opposite movement of the user
final newOffset = (offsetToCenter - onData.position) * -1;
print("new offset: " + newOffset.toString());
if (onData.scale != lastscale) {
if (onData.scale > initialScale) {
//zoom in
var zoomeChnage = initialScale-onData.scale;
scaleChange = startPosition * zoomeChnage;
print("new scaleChange: " + scaleChange.toString());
} else {
//zoom out
}
lastscale = onData.scale;
}
forPoint = newOffset-scaleChange;
print("new forPoint: " + forPoint.toString());
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: _buildMap(context));
}
Widget _buildMap(BuildContext context) {
return Container(
child: CustomPaint(
foregroundPainter: MyPainter(position, forPoint),
child: PhotoView(
imageProvider: AssetImage("asset/map.JPG"),
onTapUp: (a, b, c) {
setState(() {
position = b.localPosition;
offsetToCenter = c.position;
forPoint = Offset.zero;
initialScale = c.scale;
print("localPosition: " + b.localPosition.toString());
print("offsetToCenter: " + offsetToCenter.toString());
print("initialScale: " + initialScale.toString());
});
},
scaleStateController: controller,
controller: controller2,
),
),
);
}
}
以防万一,下面是在图像顶部呈现圆圈的小部件。 markerPainter.dart
class MyPainter extends CustomPainter {
final Offset position;
final Offset centerOffset;
final Paint line;
MyPainter(this.position, this.centerOffset)
: line = new Paint()
..color = Colors.pink
..style = PaintingStyle.fill
..strokeWidth = 5;
@override
void paint(Canvas canvas, Size size) {
if (position == null) {
return;
}
canvas.drawCircle(position + centerOffset, 5, line);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
我确实尝试了很多,但似乎我的大脑无法解决它,非常欢迎任何帮助。
【问题讨论】:
-
能否请您说明您的问题是什么以及您要达到的目标。
-
@JoãoSoares 我的问题是即使用户放大/缩小,也要将绘制的圆圈保持在同一位置。我的目标是允许用户在图像中标记点(例如在地图上放置标记)。
-
我现在明白了。听起来确实很棘手。我会试一试,但我不能做出任何承诺。