@lugg/maps 0.2.0-alpha.22 → 0.2.0-alpha.24

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 (32) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +241 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +36 -31
  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} +172 -212
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +53 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +32 -26
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +285 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +310 -421
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +178 -238
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +5 -11
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +2 -1
  19. package/lib/typescript/src/MapView.d.ts +0 -1
  20. package/lib/typescript/src/MapView.d.ts.map +1 -1
  21. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +2 -1
  22. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  23. package/package.json +3 -4
  24. package/src/MapView.tsx +8 -21
  25. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +2 -1
  26. package/ios/LuggAppleMapView.h +0 -16
  27. package/ios/LuggGoogleMapView.h +0 -13
  28. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -85
  29. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -55
  30. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  31. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  32. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -85
@@ -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() {
@@ -93,13 +91,13 @@ class PolylineAnimator {
93
91
  computeCumulativeDistances()
94
92
 
95
93
  val trailLength = animatedOptions.trailLength.coerceIn(0.01f, 1f)
96
- val endValue = if (trailLength < 1f) 1f else 2.15f
94
+ val maxProgress = if (trailLength < 1f) 1f else 2.15f
97
95
 
98
- animator = ValueAnimator.ofFloat(0f, endValue).apply {
99
- duration = animatedOptions.duration
96
+ animator = ValueAnimator.ofFloat(0f, maxProgress).apply {
97
+ duration = (animatedOptions.duration * maxProgress).toLong()
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,23 @@ 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
- }
235
+ if (reusablePoints.size < 2) return
243
236
 
244
237
  poly.points = reusablePoints
245
- if (reusableSpans.isNotEmpty()) {
238
+
239
+ if (strokeColors.size <= 1) {
240
+ poly.color = strokeColors.firstOrNull() ?: Color.BLACK
241
+ } else {
242
+ val segmentCount = reusablePoints.size - 1
243
+ val spanCount = min(segmentCount, MAX_ANIMATION_SPANS)
244
+ val segmentsPerSpan = segmentCount.toDouble() / spanCount
245
+
246
+ reusableSpans.clear()
247
+ for (i in 0 until spanCount) {
248
+ val gradientPos = (i + 0.5f) / spanCount
249
+ val color = colorAtGradientPosition(gradientPos)
250
+ reusableSpans.add(StyleSpan(StrokeStyle.colorBuilder(color).build(), segmentsPerSpan))
251
+ }
246
252
  poly.setSpans(reusableSpans)
247
253
  }
248
254
  }
@@ -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,285 @@
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 initializeProvider];
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 - Provider Initialization
128
+
129
+ - (void)initializeProvider {
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
+ [self applyProps];
148
+
149
+ CLLocationCoordinate2D coordinate =
150
+ CLLocationCoordinate2DMake(viewProps.initialCoordinate.latitude,
151
+ viewProps.initialCoordinate.longitude);
152
+
153
+ [_provider initializeMapInView:_mapWrapperView
154
+ initialCoordinate:coordinate
155
+ initialZoom:viewProps.initialZoom];
156
+
157
+ [_provider setPadding:_padding oldPadding:UIEdgeInsetsZero];
158
+
159
+ _initialized = YES;
160
+
161
+ // Flush any children that were mounted before content was created
162
+ for (UIView *subview in self.subviews) {
163
+ if ([subview isKindOfClass:[LuggMarkerView class]]) {
164
+ [_provider addMarkerView:(LuggMarkerView *)subview];
165
+ } else if ([subview isKindOfClass:[LuggPolylineView class]]) {
166
+ [_provider addPolylineView:(LuggPolylineView *)subview];
167
+ }
168
+ }
169
+ }
170
+
171
+ #pragma mark - MapProviderDelegate
172
+
173
+ - (void)mapProviderDidReady {
174
+ ReadyEvent::emit<LuggMapViewEventEmitter>(_eventEmitter);
175
+ }
176
+
177
+ - (void)mapProviderDidMoveCamera:(double)latitude
178
+ longitude:(double)longitude
179
+ zoom:(double)zoom
180
+ gesture:(BOOL)gesture {
181
+ CameraMoveEvent{latitude, longitude, zoom, static_cast<bool>(gesture)}
182
+ .emit<LuggMapViewEventEmitter>(_eventEmitter);
183
+ }
184
+
185
+ - (void)mapProviderDidIdleCamera:(double)latitude
186
+ longitude:(double)longitude
187
+ zoom:(double)zoom
188
+ gesture:(BOOL)gesture {
189
+ CameraIdleEvent{latitude, longitude, zoom, static_cast<bool>(gesture)}
190
+ .emit<LuggMapViewEventEmitter>(_eventEmitter);
191
+ }
192
+
193
+ #pragma mark - Property Setters
194
+
195
+ - (void)applyProps {
196
+ [_provider setZoomEnabled:_zoomEnabled];
197
+ [_provider setScrollEnabled:_scrollEnabled];
198
+ [_provider setRotateEnabled:_rotateEnabled];
199
+ [_provider setPitchEnabled:_pitchEnabled];
200
+ [_provider setUserLocationEnabled:_userLocationEnabled];
201
+ [_provider setTheme:_theme];
202
+ [_provider setMinZoom:_minZoom];
203
+ [_provider setMaxZoom:_maxZoom];
204
+ }
205
+
206
+ - (void)updateProps:(Props::Shared const &)props
207
+ oldProps:(Props::Shared const &)oldProps {
208
+ const auto &oldViewProps =
209
+ *std::static_pointer_cast<LuggMapViewProps const>(oldProps);
210
+ const auto &newViewProps =
211
+ *std::static_pointer_cast<LuggMapViewProps const>(props);
212
+
213
+ _providerType = newViewProps.provider;
214
+
215
+ NSString *newMapId =
216
+ [NSString stringWithUTF8String:newViewProps.mapId.c_str()];
217
+ if (newMapId.length > 0) {
218
+ _mapId = newMapId;
219
+ }
220
+
221
+ // Cache props
222
+ _zoomEnabled = newViewProps.zoomEnabled;
223
+ _scrollEnabled = newViewProps.scrollEnabled;
224
+ _rotateEnabled = newViewProps.rotateEnabled;
225
+ _pitchEnabled = newViewProps.pitchEnabled;
226
+ _userLocationEnabled = newViewProps.userLocationEnabled;
227
+ _minZoom = newViewProps.minZoom;
228
+ _maxZoom = newViewProps.maxZoom;
229
+
230
+ if (newViewProps.theme == LuggMapViewTheme::Dark) {
231
+ _theme = @"dark";
232
+ } else if (newViewProps.theme == LuggMapViewTheme::Light) {
233
+ _theme = @"light";
234
+ } else {
235
+ _theme = @"system";
236
+ }
237
+
238
+ UIEdgeInsets oldPadding = _padding;
239
+ _padding =
240
+ UIEdgeInsetsMake(newViewProps.padding.top, newViewProps.padding.left,
241
+ newViewProps.padding.bottom, newViewProps.padding.right);
242
+
243
+ if (_provider) {
244
+ [self applyProps];
245
+ [_provider setPadding:_padding oldPadding:oldPadding];
246
+ }
247
+
248
+ [super updateProps:props oldProps:oldProps];
249
+ }
250
+
251
+ #pragma mark - Commands
252
+
253
+ - (void)moveCamera:(double)latitude
254
+ longitude:(double)longitude
255
+ zoom:(double)zoom
256
+ duration:(double)duration {
257
+ [_provider moveCamera:latitude
258
+ longitude:longitude
259
+ zoom:zoom
260
+ duration:duration];
261
+ }
262
+
263
+ - (void)fitCoordinates:(NSArray *)coordinates
264
+ paddingTop:(double)paddingTop
265
+ paddingLeft:(double)paddingLeft
266
+ paddingBottom:(double)paddingBottom
267
+ paddingRight:(double)paddingRight
268
+ duration:(double)duration {
269
+ [_provider fitCoordinates:coordinates
270
+ paddingTop:paddingTop
271
+ paddingLeft:paddingLeft
272
+ paddingBottom:paddingBottom
273
+ paddingRight:paddingRight
274
+ duration:duration];
275
+ }
276
+
277
+ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
278
+ RCTLuggMapViewHandleCommand(self, commandName, args);
279
+ }
280
+
281
+ Class<RCTComponentViewProtocol> LuggMapViewCls(void) {
282
+ return LuggMapView.class;
283
+ }
284
+
285
+ @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