Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 54aeafd

Browse files
committed
[flutter] - correct pixelratio, mapview size creation and gesture conversion
1 parent f116301 commit 54aeafd

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

lib/overlay.dart

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22
import 'dart:math';
3+
import 'dart:ui';
34

45
import 'package:flutter/services.dart';
56
import 'package:flutter/widgets.dart';
@@ -15,18 +16,28 @@ class MapboxOverlay extends StatefulWidget {
1516
State<StatefulWidget> createState() => new _MapboxOverlayState();
1617
}
1718

19+
20+
/// Manages the creation and state of the map.
21+
/// This includes:
22+
/// - maintaining the id of the used surface texture
23+
/// - maintaining the map transformation
24+
/// - handling gesture input
1825
class _MapboxOverlayState extends State<MapboxOverlay> {
1926
bool _initialized = false;
2027
int _textureId = -1;
2128
Offset _scaleStartFocal;
2229
double _zoom;
23-
Size _size;
30+
Size _size; // local coordinate system.
2431

25-
Future<Null> _createMapView(Size size, MapboxMapOptions options) async {
32+
Future<Null> _createMapView(
33+
Window window, Size size, MapboxMapOptions options) async {
2634
_size = size;
35+
2736
try {
28-
int textureId = await widget.controller
29-
.create(width: size.width, height: size.height, options: options);
37+
int textureId = await widget.controller.create(
38+
width: _size.width * window.devicePixelRatio,
39+
height: _size.height * window.devicePixelRatio,
40+
options: options);
3041

3142
if (!mounted) {
3243
return;
@@ -48,8 +59,7 @@ class _MapboxOverlayState extends State<MapboxOverlay> {
4859
}
4960

5061
if (!_initialized) {
51-
_createMapView(constraints.biggest, widget.options);
52-
62+
_createMapView(window, constraints.biggest, widget.options);
5363
_initialized = true;
5464
return new Container();
5565
} else {
@@ -67,25 +77,32 @@ class _MapboxOverlayState extends State<MapboxOverlay> {
6777
});
6878
}
6979

80+
/// Called when the user double taps the screen, results in zooming the map
7081
void _onDoubleTap() {
82+
// TODO we currently zoom on center, this needs to be the tapped offset instead
7183
widget.controller.getZoom().then((zoom) {
7284
zoom++;
73-
widget.controller.zoom(zoom, _size.width / 2, _size.height / 2, 350);
85+
widget.controller.zoom(zoom, _size.width / 2 * window.devicePixelRatio,
86+
_size.height / 2 * window.devicePixelRatio, 350);
7487
});
7588
}
7689

90+
/// Called when the user initiates a scale/pan gesture.
7791
void _onScaleStart(ScaleStartDetails details) {
78-
_scaleStartFocal = details.focalPoint;
92+
_scaleStartFocal = localToMapOffset(details.focalPoint);
7993
_zoom = 0.0;
8094
}
8195

96+
/// Called when the user scales or pans the map.
8297
void _onScaleUpdate(ScaleUpdateDetails details) {
83-
final Offset delta = details.focalPoint - _scaleStartFocal;
98+
Offset focalGesture = localToMapOffset(details.focalPoint);
99+
final Offset delta = focalGesture - _scaleStartFocal;
84100
widget.controller.moveBy(delta.dx, delta.dy, 0);
85101

86102
if (details.scale != 1.0) {
87103
RenderBox renderBox = context.findRenderObject();
88-
Offset focalPoint = renderBox.globalToLocal(details.focalPoint);
104+
Offset focalPoint =
105+
localToMapOffset(renderBox.globalToLocal(details.focalPoint));
89106

90107
double newZoom = _zoomLevel(details.scale);
91108
double _zoomBy = newZoom - _zoom;
@@ -94,15 +111,27 @@ class _MapboxOverlayState extends State<MapboxOverlay> {
94111
_zoom = newZoom;
95112
}
96113

97-
_scaleStartFocal = details.focalPoint;
114+
_scaleStartFocal = localToMapOffset(details.focalPoint);
98115
}
99116

117+
/// Called when the users stops scaling the map.
100118
void _onScaleEnd(ScaleEndDetails details) {
101119
_scaleStartFocal = null;
102120
_zoom = null;
103121
}
104122

123+
/// Calculates a zoom value from a scale gesture detector input.
105124
double _zoomLevel(double scale) {
106125
return log(scale) / log(pi / 2);
107126
}
127+
128+
/// Flutter supports 2 coordinate systems (local and global).
129+
/// You can convert between the two using box.localToGlobal/globalToLocal.
130+
/// This does not match what we expect on gl-native so we need to convert
131+
/// to the offset to match the input on the Android SDK
132+
Offset localToMapOffset(Offset offset) {
133+
// TODO replace with MatrixUtils.transformPoint
134+
return new Offset(offset.dx * window.devicePixelRatio,
135+
offset.dy * window.devicePixelRatio);
136+
}
108137
}

0 commit comments

Comments
 (0)