#937 viewer: fixed position drift during scale

This commit is contained in:
Thibault Deckers 2024-03-26 23:11:23 +01:00
parent bd9a89e5d4
commit 5db31476fe
3 changed files with 9 additions and 8 deletions

View file

@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
### Fixed ### Fixed
- crash when decoding large region - crash when decoding large region
- viewer position drift during scale
## <a id="v1.10.7"></a>[v1.10.7] - 2024-03-12 ## <a id="v1.10.7"></a>[v1.10.7] - 2024-03-12

View file

@ -220,12 +220,16 @@ class _AvesMagnifierState extends State<AvesMagnifier> with TickerProviderStateM
newScale = boundaries.clampScale(newScale); newScale = boundaries.clampScale(newScale);
} }
newScale = max(0, newScale); newScale = max(0, newScale);
// focal point is in viewport coordinates
final scaleFocalPoint = _doubleTap ? _startFocalPoint! : details.localFocalPoint; final scaleFocalPoint = _doubleTap ? _startFocalPoint! : details.localFocalPoint;
final viewportCenter = boundaries.viewportCenter;
final centerContentPosition = boundaries.viewportToContentPosition(controller, viewportCenter);
final scalePositionDelta = (scaleFocalPoint - viewportCenter) * (scale! / newScale - 1);
final panPositionDelta = scaleFocalPoint - _lastViewportFocalPosition!; final panPositionDelta = scaleFocalPoint - _lastViewportFocalPosition!;
final scalePositionDelta = boundaries.viewportToStatePosition(controller, scaleFocalPoint) * (scale! / newScale - 1);
final newPosition = boundaries.clampPosition( final newPosition = boundaries.clampPosition(
position: position + panPositionDelta + scalePositionDelta, position: boundaries.contentToStatePosition(newScale, centerContentPosition) + scalePositionDelta + panPositionDelta,
scale: newScale, scale: newScale,
); );

View file

@ -90,16 +90,12 @@ class ScaleBoundaries extends Equatable {
double get initialScale => scaleForLevel(_initialScale); double get initialScale => scaleForLevel(_initialScale);
Offset get _viewportCenter => viewportSize.center(Offset.zero); Offset get viewportCenter => viewportSize.center(Offset.zero);
Offset get _contentCenter => contentSize.center(Offset.zero); Offset get _contentCenter => contentSize.center(Offset.zero);
Offset viewportToStatePosition(AvesMagnifierController controller, Offset viewportPosition) {
return viewportPosition - _viewportCenter - controller.position;
}
Offset viewportToContentPosition(AvesMagnifierController controller, Offset viewportPosition) { Offset viewportToContentPosition(AvesMagnifierController controller, Offset viewportPosition) {
return viewportToStatePosition(controller, viewportPosition) / controller.scale! + _contentCenter; return (viewportPosition - viewportCenter - controller.position) / controller.scale! + _contentCenter;
} }
Offset contentToStatePosition(double scale, Offset contentPosition) { Offset contentToStatePosition(double scale, Offset contentPosition) {