Hi everyone,
I was glad the in recent versions, the tap callbacks were included into photo view. However, I am currently trying to obtain the relative position of tap, irregardless of scale value. This means that even at different scales, when a user taps on the same point/position, it should return the same position value.
The following onTapUp callback implementation would give me the position of a point tapped. However, upon changing to another scale and tapping at the same point, a different value was returned.
onTapUp: (buildContext, tapUpDetails, photoViewControllerValue){
print("position: " + tapUpDetails.globalPosition.toString());
}
Using the code photoViewControllerValue.position.dx/photoViewControllerValue.scale gave me different values, even when tapping on the same point.
As such, I would require the help of everyone to lead me towards the right direction in getting this done.
Thank you!
@darrylong Did you solve it? I am too working on an app and need this. This comment says that this is done but I am not able to see how to use that.
After a lot of puzzling with geometry, I got it to work:
void _onTapUp(final BuildContext context, final TapUpDetails tapUpDetails, final PhotoViewControllerValue controller) {
final controllerPosition = -controller.position / controller.scale;
final size = context.findRenderObject().paintBounds.size;
final localPosition = tapUpDetails.localPosition.translate(-size.width / 2.0, -size.height / 2.0) / controller.scale;
final position = controllerPosition + localPosition;
// position now hold the tap position in image coordinates, relative to the centre of the image
}
The value of PhotoViewControllerValue.position uses inverse dimensions with respect to TapUpDetails.localPosition, hence the minus sign in the first line. It also uses the centre of the image as its zero (rather than the top-left corner), which is why we have to translate with half the widget size.
@lbel thanks for your help! It works great when the widget occupies the screen in full.
However, when the photoview widget is placed in a Column widget with multiple children, the position value is not shown correctly. Given the following:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
const SizedBox(height: 50),
Text("This is a text message!"),
Flexible(
flex: 1,
child: ClipRect(
child: Stack(
children: <Widget>[
Positioned.fill(
child: PhotoView(
imageProvider:
const AssetImage("assets/large-image.png"),
controller: controller,
enableRotation: false,
initialScale: defScale,
minScale: minScale,
maxScale: maxScale,
},
),
),
],
),
)),
],
),
I was wondering if this has to do with the '2.0' value in the following piece of code.
final localPosition = tapUpDetails.localPosition.translate(-size.width / 2.0, -size.height / 2.0) / controller.scale;
Any idea where the '2.0' value is obtained from?
Kind of 鈥撀爐he 2.0 comes from the fact that the localPosition starts in the top left corner, while the controller uses coordinates that start in the center of the widget. Hence the translation between them is half the widget size (the minus signs are because it also inverts the coordinates for some reason).
In your case, the context of onTapUp might be a context where the obtained size is different, but it's hard to tell without your full code.
Looks like the same as #239
I got to post a workaround there to make things easier (perhaps).
Comment here: https://github.com/renancaraujo/photo_view/issues/239#issuecomment-591128321
Most helpful comment
After a lot of puzzling with geometry, I got it to work:
The value of
PhotoViewControllerValue.positionuses inverse dimensions with respect toTapUpDetails.localPosition, hence the minus sign in the first line. It also uses the centre of the image as its zero (rather than the top-left corner), which is why we have to translate with half the widget size.