@lugg/maps 0.2.0-alpha.21 → 0.2.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +201 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +39 -29
  4. package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
  5. package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +174 -189
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +51 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +28 -24
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +303 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +317 -410
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +179 -218
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +9 -12
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/MapView.web.js +4 -1
  19. package/lib/module/MapView.web.js.map +1 -1
  20. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  21. package/lib/typescript/src/MapView.d.ts +0 -1
  22. package/lib/typescript/src/MapView.d.ts.map +1 -1
  23. package/lib/typescript/src/MapView.types.d.ts +6 -1
  24. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  25. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  26. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +4 -2
  27. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  28. package/lib/typescript/src/index.d.ts +1 -1
  29. package/lib/typescript/src/index.d.ts.map +1 -1
  30. package/lib/typescript/src/types.d.ts +4 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -1
  32. package/package.json +5 -3
  33. package/src/MapView.tsx +11 -21
  34. package/src/MapView.types.ts +6 -1
  35. package/src/MapView.web.tsx +10 -0
  36. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  37. package/src/index.ts +1 -0
  38. package/src/types.ts +5 -0
  39. package/ios/LuggAppleMapView.h +0 -16
  40. package/ios/LuggGoogleMapView.h +0 -13
  41. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
  42. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
  43. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  44. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  45. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
@@ -1,6 +1,5 @@
1
1
  package com.luggmaps.core
2
2
 
3
- import android.animation.TimeInterpolator
4
3
  import android.animation.ValueAnimator
5
4
  import android.graphics.Color
6
5
  import android.location.Location
@@ -14,6 +13,10 @@ import kotlin.math.floor
14
13
  import kotlin.math.min
15
14
 
16
15
  class PolylineAnimator {
16
+ companion object {
17
+ private const val MAX_ANIMATION_SPANS = 16
18
+ }
19
+
17
20
  var polyline: Polyline? = null
18
21
  var coordinates: List<LatLng> = emptyList()
19
22
  set(value) {
@@ -59,17 +62,12 @@ class PolylineAnimator {
59
62
  startAnimation()
60
63
  }
61
64
 
62
- private fun getInterpolator(): TimeInterpolator =
65
+ private fun applyEasing(t: Float): Float =
63
66
  when (animatedOptions.easing) {
64
- "easeIn" -> TimeInterpolator { t -> t * t }
65
-
66
- "easeOut" -> TimeInterpolator { t -> t * (2 - t) }
67
-
68
- "easeInOut" -> TimeInterpolator { t ->
69
- if (t < 0.5f) 2 * t * t else -1 + (4 - 2 * t) * t
70
- }
71
-
72
- else -> LinearInterpolator()
67
+ "easeIn" -> t * t
68
+ "easeOut" -> t * (2 - t)
69
+ "easeInOut" -> if (t < 0.5f) 2 * t * t else -1 + (4 - 2 * t) * t
70
+ else -> t
73
71
  }
74
72
 
75
73
  fun update() {
@@ -99,7 +97,7 @@ class PolylineAnimator {
99
97
  duration = animatedOptions.duration
100
98
  startDelay = animatedOptions.delay
101
99
  repeatCount = ValueAnimator.INFINITE
102
- interpolator = getInterpolator()
100
+ interpolator = LinearInterpolator()
103
101
  addUpdateListener { animation ->
104
102
  animationProgress = animation.animatedValue as Float
105
103
  updateAnimatedPolyline()
@@ -191,7 +189,9 @@ class PolylineAnimator {
191
189
  }
192
190
 
193
191
  val trailLength = animatedOptions.trailLength.coerceIn(0.01f, 1f)
194
- val progress = min(animationProgress, if (trailLength < 1f) 1f else 2f)
192
+ val maxProgress = if (trailLength < 1f) 1f else 2f
193
+ val rawProgress = min(animationProgress, maxProgress)
194
+ val progress = applyEasing(rawProgress / maxProgress) * maxProgress
195
195
 
196
196
  val headDist: Float
197
197
  val tailDist: Float
@@ -209,8 +209,8 @@ class PolylineAnimator {
209
209
  }
210
210
 
211
211
  if (headDist <= tailDist) {
212
- poly.setSpans(emptyList())
213
212
  poly.points = listOf(coordinates.firstOrNull() ?: LatLng(0.0, 0.0))
213
+ poly.color = strokeColors.firstOrNull() ?: Color.BLACK
214
214
  return
215
215
  }
216
216
 
@@ -219,7 +219,6 @@ class PolylineAnimator {
219
219
  val endIndex = indexForDistance(headDist)
220
220
 
221
221
  reusablePoints.clear()
222
- reusableSpans.clear()
223
222
 
224
223
  reusablePoints.add(coordinateAtDistance(tailDist))
225
224
 
@@ -233,16 +232,21 @@ class PolylineAnimator {
233
232
  reusablePoints.add(endCoord)
234
233
  }
235
234
 
236
- val pointCount = reusablePoints.size
237
- for (i in 0 until (pointCount - 1)) {
238
- val segMidDist = tailDist + visibleLength * (i + 0.5f) / (pointCount - 1)
239
- val gradientPos = (segMidDist - tailDist) / visibleLength
240
- val color = colorAtGradientPosition(gradientPos)
241
- reusableSpans.add(StyleSpan(StrokeStyle.colorBuilder(color).build()))
242
- }
243
-
244
235
  poly.points = reusablePoints
245
- if (reusableSpans.isNotEmpty()) {
236
+
237
+ if (strokeColors.size <= 1) {
238
+ poly.color = strokeColors.firstOrNull() ?: Color.BLACK
239
+ } else {
240
+ val segmentCount = reusablePoints.size - 1
241
+ val spanCount = min(segmentCount, MAX_ANIMATION_SPANS)
242
+ val segmentsPerSpan = segmentCount.toDouble() / spanCount
243
+
244
+ reusableSpans.clear()
245
+ for (i in 0 until spanCount) {
246
+ val gradientPos = (i + 0.5f) / spanCount
247
+ val color = colorAtGradientPosition(gradientPos)
248
+ reusableSpans.add(StyleSpan(StrokeStyle.colorBuilder(color).build(), segmentsPerSpan))
249
+ }
246
250
  poly.setSpans(reusableSpans)
247
251
  }
248
252
  }
@@ -0,0 +1,9 @@
1
+ #import <React/RCTViewComponentView.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @interface LuggMapView : RCTViewComponentView
7
+ @end
8
+
9
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,303 @@
1
+ #import "LuggMapView.h"
2
+ #import "LuggMapWrapperView.h"
3
+ #import "LuggMarkerView.h"
4
+ #import "LuggPolylineView.h"
5
+ #import "core/AppleMapProvider.h"
6
+ #import "core/GoogleMapProvider.h"
7
+ #import "core/MapProviderDelegate.h"
8
+ #import "events/CameraIdleEvent.h"
9
+ #import "events/CameraMoveEvent.h"
10
+ #import "events/ReadyEvent.h"
11
+
12
+ #import <react/renderer/components/RNMapsSpec/ComponentDescriptors.h>
13
+ #import <react/renderer/components/RNMapsSpec/EventEmitters.h>
14
+ #import <react/renderer/components/RNMapsSpec/Props.h>
15
+ #import <react/renderer/components/RNMapsSpec/RCTComponentViewHelpers.h>
16
+
17
+ #import "RCTFabricComponentsPlugins.h"
18
+
19
+ using namespace facebook::react;
20
+ using namespace luggmaps::events;
21
+
22
+ @interface LuggMapView () <RCTLuggMapViewViewProtocol, MapProviderDelegate>
23
+ @end
24
+
25
+ @implementation LuggMapView {
26
+ id<MapProvider> _provider;
27
+ LuggMapWrapperView *_mapWrapperView;
28
+ LuggMapViewProvider _providerType;
29
+ NSString *_mapId;
30
+ BOOL _initialized;
31
+ // Cached props to apply after content creation
32
+ BOOL _zoomEnabled;
33
+ BOOL _scrollEnabled;
34
+ BOOL _rotateEnabled;
35
+ BOOL _pitchEnabled;
36
+ BOOL _userLocationEnabled;
37
+ NSString *_theme;
38
+ double _minZoom;
39
+ double _maxZoom;
40
+ UIEdgeInsets _padding;
41
+ }
42
+
43
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
44
+ return concreteComponentDescriptorProvider<LuggMapViewComponentDescriptor>();
45
+ }
46
+
47
+ - (instancetype)initWithFrame:(CGRect)frame {
48
+ if (self = [super initWithFrame:frame]) {
49
+ static const auto defaultProps = std::make_shared<const LuggMapViewProps>();
50
+ _props = defaultProps;
51
+
52
+ _initialized = NO;
53
+ _mapId = @"";
54
+ _providerType = LuggMapViewProvider::Google;
55
+ _zoomEnabled = YES;
56
+ _scrollEnabled = YES;
57
+ _rotateEnabled = YES;
58
+ _pitchEnabled = YES;
59
+ _userLocationEnabled = NO;
60
+ _theme = @"system";
61
+ _padding = UIEdgeInsetsZero;
62
+ }
63
+ return self;
64
+ }
65
+
66
+ #pragma mark - View Lifecycle
67
+
68
+ - (void)mountChildComponentView:
69
+ (UIView<RCTComponentViewProtocol> *)childComponentView
70
+ index:(NSInteger)index {
71
+ [super mountChildComponentView:childComponentView index:index];
72
+
73
+ if ([childComponentView isKindOfClass:[LuggMapWrapperView class]]) {
74
+ _mapWrapperView = (LuggMapWrapperView *)childComponentView;
75
+ } else if ([childComponentView isKindOfClass:[LuggMarkerView class]]) {
76
+ LuggMarkerView *markerView = (LuggMarkerView *)childComponentView;
77
+ if (_provider) {
78
+ [_provider addMarkerView:markerView];
79
+ }
80
+ } else if ([childComponentView isKindOfClass:[LuggPolylineView class]]) {
81
+ LuggPolylineView *polylineView = (LuggPolylineView *)childComponentView;
82
+ if (_provider) {
83
+ [_provider addPolylineView:polylineView];
84
+ }
85
+ }
86
+ }
87
+
88
+ - (void)unmountChildComponentView:
89
+ (UIView<RCTComponentViewProtocol> *)childComponentView
90
+ index:(NSInteger)index {
91
+ if ([childComponentView isKindOfClass:[LuggMarkerView class]]) {
92
+ LuggMarkerView *markerView = (LuggMarkerView *)childComponentView;
93
+ if (_provider) {
94
+ [_provider removeMarkerView:markerView];
95
+ }
96
+ } else if ([childComponentView isKindOfClass:[LuggPolylineView class]]) {
97
+ LuggPolylineView *polylineView = (LuggPolylineView *)childComponentView;
98
+ if (_provider) {
99
+ [_provider removePolylineView:polylineView];
100
+ }
101
+ }
102
+
103
+ [super unmountChildComponentView:childComponentView index:index];
104
+ }
105
+
106
+ - (void)didMoveToWindow {
107
+ [super didMoveToWindow];
108
+ if (self.window) {
109
+ if (!_provider && _mapWrapperView) {
110
+ [self initializeContent];
111
+ }
112
+ [_provider resumeAnimations];
113
+ } else {
114
+ [_provider pauseAnimations];
115
+ }
116
+ }
117
+
118
+ - (void)prepareForRecycle {
119
+ [super prepareForRecycle];
120
+
121
+ [_provider destroy];
122
+ _provider = nil;
123
+ _mapWrapperView = nil;
124
+ _initialized = NO;
125
+ }
126
+
127
+ #pragma mark - Content Initialization
128
+
129
+ - (void)initializeContent {
130
+ if (_provider || !_mapWrapperView)
131
+ return;
132
+
133
+ const auto &viewProps =
134
+ *std::static_pointer_cast<LuggMapViewProps const>(_props);
135
+
136
+ if (_providerType == LuggMapViewProvider::Apple) {
137
+ _provider = [[AppleMapProvider alloc] init];
138
+ } else {
139
+ GoogleMapProvider *google = [[GoogleMapProvider alloc] init];
140
+ google.mapId = _mapId;
141
+ _provider = google;
142
+ }
143
+
144
+ _provider.delegate = self;
145
+
146
+ // Apply cached props before initialization
147
+ [_provider setZoomEnabled:_zoomEnabled];
148
+ [_provider setScrollEnabled:_scrollEnabled];
149
+ [_provider setRotateEnabled:_rotateEnabled];
150
+ [_provider setPitchEnabled:_pitchEnabled];
151
+ [_provider setUserLocationEnabled:_userLocationEnabled];
152
+ [_provider setTheme:_theme];
153
+ [_provider setMinZoom:_minZoom];
154
+ [_provider setMaxZoom:_maxZoom];
155
+
156
+ CLLocationCoordinate2D coordinate =
157
+ CLLocationCoordinate2DMake(viewProps.initialCoordinate.latitude,
158
+ viewProps.initialCoordinate.longitude);
159
+
160
+ [_provider initializeMapInView:_mapWrapperView
161
+ initialCoordinate:coordinate
162
+ initialZoom:viewProps.initialZoom];
163
+
164
+ [_provider setPadding:_padding oldPadding:UIEdgeInsetsZero];
165
+
166
+ _initialized = YES;
167
+
168
+ // Flush any children that were mounted before content was created
169
+ for (UIView *subview in self.subviews) {
170
+ if ([subview isKindOfClass:[LuggMarkerView class]]) {
171
+ [_provider addMarkerView:(LuggMarkerView *)subview];
172
+ } else if ([subview isKindOfClass:[LuggPolylineView class]]) {
173
+ [_provider addPolylineView:(LuggPolylineView *)subview];
174
+ }
175
+ }
176
+ }
177
+
178
+ #pragma mark - MapProviderDelegate
179
+
180
+ - (void)mapProviderDidReady {
181
+ ReadyEvent::emit<LuggMapViewEventEmitter>(_eventEmitter);
182
+ }
183
+
184
+ - (void)mapProviderDidMoveCamera:(double)latitude
185
+ longitude:(double)longitude
186
+ zoom:(double)zoom
187
+ gesture:(BOOL)gesture {
188
+ CameraMoveEvent{latitude, longitude, zoom, static_cast<bool>(gesture)}
189
+ .emit<LuggMapViewEventEmitter>(_eventEmitter);
190
+ }
191
+
192
+ - (void)mapProviderDidIdleCamera:(double)latitude
193
+ longitude:(double)longitude
194
+ zoom:(double)zoom
195
+ gesture:(BOOL)gesture {
196
+ CameraIdleEvent{latitude, longitude, zoom, static_cast<bool>(gesture)}
197
+ .emit<LuggMapViewEventEmitter>(_eventEmitter);
198
+ }
199
+
200
+ #pragma mark - Property Setters
201
+
202
+ - (void)updateProps:(Props::Shared const &)props
203
+ oldProps:(Props::Shared const &)oldProps {
204
+ const auto &oldViewProps =
205
+ *std::static_pointer_cast<LuggMapViewProps const>(oldProps);
206
+ const auto &newViewProps =
207
+ *std::static_pointer_cast<LuggMapViewProps const>(props);
208
+
209
+ // Capture provider and mapId before content is created
210
+ _providerType = newViewProps.provider;
211
+
212
+ NSString *newMapId =
213
+ [NSString stringWithUTF8String:newViewProps.mapId.c_str()];
214
+ if (newMapId.length > 0) {
215
+ _mapId = newMapId;
216
+ }
217
+
218
+ // Cache and forward props
219
+ _zoomEnabled = newViewProps.zoomEnabled;
220
+ _scrollEnabled = newViewProps.scrollEnabled;
221
+ _rotateEnabled = newViewProps.rotateEnabled;
222
+ _pitchEnabled = newViewProps.pitchEnabled;
223
+ _userLocationEnabled = newViewProps.userLocationEnabled;
224
+
225
+ UIEdgeInsets oldPadding = _padding;
226
+ _padding =
227
+ UIEdgeInsetsMake(newViewProps.padding.top, newViewProps.padding.left,
228
+ newViewProps.padding.bottom, newViewProps.padding.right);
229
+
230
+ if (_provider) {
231
+ [_provider setZoomEnabled:_zoomEnabled];
232
+ [_provider setScrollEnabled:_scrollEnabled];
233
+ [_provider setRotateEnabled:_rotateEnabled];
234
+ [_provider setPitchEnabled:_pitchEnabled];
235
+ [_provider setUserLocationEnabled:_userLocationEnabled];
236
+
237
+ if (oldViewProps.theme != newViewProps.theme) {
238
+ NSString *theme;
239
+ if (newViewProps.theme == LuggMapViewTheme::Dark) {
240
+ theme = @"dark";
241
+ } else if (newViewProps.theme == LuggMapViewTheme::Light) {
242
+ theme = @"light";
243
+ } else {
244
+ theme = @"system";
245
+ }
246
+ _theme = theme;
247
+ [_provider setTheme:_theme];
248
+ }
249
+
250
+ [_provider setMinZoom:newViewProps.minZoom];
251
+ [_provider setMaxZoom:newViewProps.maxZoom];
252
+ [_provider setPadding:_padding oldPadding:oldPadding];
253
+ } else {
254
+ // Cache theme for later
255
+ if (newViewProps.theme == LuggMapViewTheme::Dark) {
256
+ _theme = @"dark";
257
+ } else if (newViewProps.theme == LuggMapViewTheme::Light) {
258
+ _theme = @"light";
259
+ } else {
260
+ _theme = @"system";
261
+ }
262
+ _minZoom = newViewProps.minZoom;
263
+ _maxZoom = newViewProps.maxZoom;
264
+ }
265
+
266
+ [super updateProps:props oldProps:oldProps];
267
+ }
268
+
269
+ #pragma mark - Commands
270
+
271
+ - (void)moveCamera:(double)latitude
272
+ longitude:(double)longitude
273
+ zoom:(double)zoom
274
+ duration:(double)duration {
275
+ [_provider moveCamera:latitude
276
+ longitude:longitude
277
+ zoom:zoom
278
+ duration:duration];
279
+ }
280
+
281
+ - (void)fitCoordinates:(NSArray *)coordinates
282
+ paddingTop:(double)paddingTop
283
+ paddingLeft:(double)paddingLeft
284
+ paddingBottom:(double)paddingBottom
285
+ paddingRight:(double)paddingRight
286
+ duration:(double)duration {
287
+ [_provider fitCoordinates:coordinates
288
+ paddingTop:paddingTop
289
+ paddingLeft:paddingLeft
290
+ paddingBottom:paddingBottom
291
+ paddingRight:paddingRight
292
+ duration:duration];
293
+ }
294
+
295
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
296
+ RCTLuggMapViewHandleCommand(self, commandName, args);
297
+ }
298
+
299
+ Class<RCTComponentViewProtocol> LuggMapViewCls(void) {
300
+ return LuggMapView.class;
301
+ }
302
+
303
+ @end
@@ -0,0 +1,15 @@
1
+ #import "MapProviderDelegate.h"
2
+ #import <MapKit/MapKit.h>
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @interface LuggAppleMapViewContent : MKMapView
7
+ @end
8
+
9
+ @interface AppleMapProvider : NSObject <MapProvider, MKMapViewDelegate>
10
+
11
+ @property(nonatomic, readonly, nullable) MKMapView *mapView;
12
+
13
+ @end
14
+
15
+ NS_ASSUME_NONNULL_END