@lugg/maps 0.2.0-alpha.19 → 0.2.0-alpha.20

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 (31) hide show
  1. package/android/src/main/java/com/luggmaps/LuggGoogleMapView.kt +2 -0
  2. package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +9 -0
  3. package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +16 -0
  4. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +41 -5
  5. package/ios/LuggAppleMapView.mm +47 -3
  6. package/ios/LuggGoogleMapView.mm +2 -0
  7. package/ios/LuggPolylineView.h +3 -0
  8. package/ios/LuggPolylineView.mm +18 -0
  9. package/ios/core/GMSPolylineAnimator.h +1 -0
  10. package/ios/core/GMSPolylineAnimator.m +37 -6
  11. package/ios/core/MKPolylineAnimator.h +2 -0
  12. package/ios/core/MKPolylineAnimator.m +49 -6
  13. package/ios/core/PolylineAnimatorBase.h +14 -0
  14. package/ios/core/PolylineAnimatorBase.m +33 -0
  15. package/ios/extensions/MKMapView+Zoom.h +2 -0
  16. package/ios/extensions/MKMapView+Zoom.m +14 -4
  17. package/lib/module/components/Polyline.js +3 -1
  18. package/lib/module/components/Polyline.js.map +1 -1
  19. package/lib/module/components/Polyline.web.js +53 -6
  20. package/lib/module/components/Polyline.web.js.map +1 -1
  21. package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
  22. package/lib/typescript/src/components/Polyline.d.ts +28 -0
  23. package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
  24. package/lib/typescript/src/components/Polyline.web.d.ts +1 -1
  25. package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
  26. package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
  27. package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/src/components/Polyline.tsx +32 -0
  30. package/src/components/Polyline.web.tsx +75 -8
  31. package/src/fabric/LuggPolylineViewNativeComponent.ts +8 -0
@@ -337,6 +337,7 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
337
337
  coordinates = polylineView.coordinates
338
338
  strokeColors = polylineView.strokeColors
339
339
  strokeWidth = polylineView.strokeWidth.dpToPx()
340
+ animatedOptions = polylineView.animatedOptions
340
341
  animated = polylineView.animated
341
342
  update()
342
343
  }
@@ -364,6 +365,7 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
364
365
  coordinates = polylineView.coordinates
365
366
  strokeColors = polylineView.strokeColors
366
367
  strokeWidth = polylineView.strokeWidth.dpToPx()
368
+ animatedOptions = polylineView.animatedOptions
367
369
  animated = polylineView.animated
368
370
  update()
369
371
  }
@@ -12,6 +12,8 @@ interface LuggPolylineViewDelegate {
12
12
  fun polylineViewDidUpdate(polylineView: LuggPolylineView)
13
13
  }
14
14
 
15
+ data class AnimatedOptions(val duration: Long = 2150L, val easing: String = "linear", val trailLength: Float = 1f, val delay: Long = 0L)
16
+
15
17
  class LuggPolylineView(context: Context) : ReactViewGroup(context) {
16
18
  var coordinates: List<LatLng> = emptyList()
17
19
  private set
@@ -25,6 +27,9 @@ class LuggPolylineView(context: Context) : ReactViewGroup(context) {
25
27
  var animated: Boolean = false
26
28
  private set
27
29
 
30
+ var animatedOptions: AnimatedOptions = AnimatedOptions()
31
+ private set
32
+
28
33
  var zIndex: Float = 0f
29
34
  private set
30
35
 
@@ -58,6 +63,10 @@ class LuggPolylineView(context: Context) : ReactViewGroup(context) {
58
63
  animated = value
59
64
  }
60
65
 
66
+ fun setAnimatedOptions(options: AnimatedOptions) {
67
+ animatedOptions = options
68
+ }
69
+
61
70
  fun setZIndex(value: Float) {
62
71
  zIndex = value
63
72
  }
@@ -1,6 +1,7 @@
1
1
  package com.luggmaps
2
2
 
3
3
  import com.facebook.react.bridge.ReadableArray
4
+ import com.facebook.react.bridge.ReadableMap
4
5
  import com.facebook.react.module.annotations.ReactModule
5
6
  import com.facebook.react.uimanager.ThemedReactContext
6
7
  import com.facebook.react.uimanager.ViewGroupManager
@@ -65,6 +66,21 @@ class LuggPolylineViewManager :
65
66
  view.setAnimated(value)
66
67
  }
67
68
 
69
+ @ReactProp(name = "animatedOptions")
70
+ override fun setAnimatedOptions(view: LuggPolylineView, value: ReadableMap?) {
71
+ val options = if (value != null) {
72
+ AnimatedOptions(
73
+ duration = if (value.hasKey("duration")) value.getDouble("duration").toLong() else 2150L,
74
+ easing = if (value.hasKey("easing")) value.getString("easing") ?: "linear" else "linear",
75
+ trailLength = if (value.hasKey("trailLength")) value.getDouble("trailLength").toFloat() else 1f,
76
+ delay = if (value.hasKey("delay")) value.getDouble("delay").toLong() else 0L
77
+ )
78
+ } else {
79
+ AnimatedOptions()
80
+ }
81
+ view.setAnimatedOptions(options)
82
+ }
83
+
68
84
  @ReactProp(name = "zIndex", defaultFloat = 0f)
69
85
  override fun setZIndex(view: LuggPolylineView, value: Float) {
70
86
  super.setZIndex(view, value)
@@ -1,5 +1,6 @@
1
1
  package com.luggmaps.core
2
2
 
3
+ import android.animation.TimeInterpolator
3
4
  import android.animation.ValueAnimator
4
5
  import android.graphics.Color
5
6
  import android.location.Location
@@ -8,6 +9,7 @@ import com.google.android.gms.maps.model.LatLng
8
9
  import com.google.android.gms.maps.model.Polyline
9
10
  import com.google.android.gms.maps.model.StrokeStyle
10
11
  import com.google.android.gms.maps.model.StyleSpan
12
+ import com.luggmaps.AnimatedOptions
11
13
  import kotlin.math.floor
12
14
  import kotlin.math.min
13
15
 
@@ -22,6 +24,14 @@ class PolylineAnimator {
22
24
  }
23
25
  var strokeColors: List<Int> = listOf(Color.BLACK)
24
26
  var strokeWidth: Float = 1f
27
+ var animatedOptions: AnimatedOptions = AnimatedOptions()
28
+ set(value) {
29
+ if (field == value) return
30
+ field = value
31
+ if (animated) {
32
+ restartAnimation()
33
+ }
34
+ }
25
35
 
26
36
  var animated: Boolean = false
27
37
  set(value) {
@@ -44,6 +54,24 @@ class PolylineAnimator {
44
54
  private val reusablePoints = ArrayList<LatLng>()
45
55
  private val reusableSpans = ArrayList<StyleSpan>()
46
56
 
57
+ private fun restartAnimation() {
58
+ stopAnimation()
59
+ startAnimation()
60
+ }
61
+
62
+ private fun getInterpolator(): TimeInterpolator =
63
+ 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()
73
+ }
74
+
47
75
  fun update() {
48
76
  if (animated) return
49
77
 
@@ -64,10 +92,14 @@ class PolylineAnimator {
64
92
 
65
93
  computeCumulativeDistances()
66
94
 
67
- animator = ValueAnimator.ofFloat(0f, 2.15f).apply {
68
- duration = 2150
95
+ val trailLength = animatedOptions.trailLength.coerceIn(0.01f, 1f)
96
+ val endValue = if (trailLength < 1f) 1f else 2.15f
97
+
98
+ animator = ValueAnimator.ofFloat(0f, endValue).apply {
99
+ duration = animatedOptions.duration
100
+ startDelay = animatedOptions.delay
69
101
  repeatCount = ValueAnimator.INFINITE
70
- interpolator = LinearInterpolator()
102
+ interpolator = getInterpolator()
71
103
  addUpdateListener { animation ->
72
104
  animationProgress = animation.animatedValue as Float
73
105
  updateAnimatedPolyline()
@@ -158,12 +190,16 @@ class PolylineAnimator {
158
190
  return
159
191
  }
160
192
 
161
- val progress = min(animationProgress, 2f)
193
+ val trailLength = animatedOptions.trailLength.coerceIn(0.01f, 1f)
194
+ val progress = min(animationProgress, if (trailLength < 1f) 1f else 2f)
162
195
 
163
196
  val headDist: Float
164
197
  val tailDist: Float
165
198
 
166
- if (progress <= 1f) {
199
+ if (trailLength < 1f) {
200
+ headDist = progress * totalLength
201
+ tailDist = maxOf(0f, headDist - totalLength * trailLength)
202
+ } else if (progress <= 1f) {
167
203
  tailDist = 0f
168
204
  headDist = progress * totalLength
169
205
  } else {
@@ -235,6 +235,8 @@ using namespace luggmaps::events;
235
235
 
236
236
  - (void)updateProps:(Props::Shared const &)props
237
237
  oldProps:(Props::Shared const &)oldProps {
238
+ const auto &oldViewProps =
239
+ *std::static_pointer_cast<LuggAppleMapViewProps const>(oldProps);
238
240
  const auto &newViewProps =
239
241
  *std::static_pointer_cast<LuggAppleMapViewProps const>(props);
240
242
 
@@ -244,9 +246,49 @@ using namespace luggmaps::events;
244
246
  _mapView.rotateEnabled = newViewProps.rotateEnabled;
245
247
  _mapView.pitchEnabled = newViewProps.pitchEnabled;
246
248
  _mapView.showsUserLocation = newViewProps.userLocationEnabled;
247
- _mapView.layoutMargins = UIEdgeInsetsMake(
248
- newViewProps.padding.top, newViewProps.padding.left,
249
- newViewProps.padding.bottom, newViewProps.padding.right);
249
+
250
+ // Check if padding changed
251
+ BOOL paddingChanged =
252
+ oldViewProps.padding.top != newViewProps.padding.top ||
253
+ oldViewProps.padding.left != newViewProps.padding.left ||
254
+ oldViewProps.padding.bottom != newViewProps.padding.bottom ||
255
+ oldViewProps.padding.right != newViewProps.padding.right;
256
+
257
+ if (paddingChanged) {
258
+ // Calculate the offset difference to keep visual center stable
259
+ CGFloat oldOffsetX =
260
+ (oldViewProps.padding.left - oldViewProps.padding.right) / 2.0;
261
+ CGFloat oldOffsetY =
262
+ (oldViewProps.padding.top - oldViewProps.padding.bottom) / 2.0;
263
+ CGFloat newOffsetX =
264
+ (newViewProps.padding.left - newViewProps.padding.right) / 2.0;
265
+ CGFloat newOffsetY =
266
+ (newViewProps.padding.top - newViewProps.padding.bottom) / 2.0;
267
+
268
+ CGFloat deltaX = newOffsetX - oldOffsetX;
269
+ CGFloat deltaY = newOffsetY - oldOffsetY;
270
+
271
+ // Apply new padding first
272
+ _mapView.layoutMargins = UIEdgeInsetsMake(
273
+ newViewProps.padding.top, newViewProps.padding.left,
274
+ newViewProps.padding.bottom, newViewProps.padding.right);
275
+
276
+ // Convert pixel offset to coordinate offset
277
+ if (deltaX != 0 || deltaY != 0) {
278
+ CLLocationCoordinate2D currentCenter = _mapView.centerCoordinate;
279
+ CGPoint centerPoint = [_mapView convertCoordinate:currentCenter
280
+ toPointToView:_mapView];
281
+ CGPoint newPoint =
282
+ CGPointMake(centerPoint.x - deltaX, centerPoint.y - deltaY);
283
+ CLLocationCoordinate2D newCenter = [_mapView convertPoint:newPoint
284
+ toCoordinateFromView:_mapView];
285
+ [_mapView setCenterCoordinate:newCenter animated:NO];
286
+ }
287
+ } else {
288
+ _mapView.layoutMargins = UIEdgeInsetsMake(
289
+ newViewProps.padding.top, newViewProps.padding.left,
290
+ newViewProps.padding.bottom, newViewProps.padding.right);
291
+ }
250
292
 
251
293
  _minZoom = newViewProps.minZoom;
252
294
  _maxZoom = newViewProps.maxZoom;
@@ -379,6 +421,7 @@ using namespace luggmaps::events;
379
421
  renderer.strokeColor = polylineView.strokeColors.firstObject;
380
422
  renderer.strokeColors =
381
423
  polylineView.strokeColors.count > 1 ? polylineView.strokeColors : nil;
424
+ renderer.animatedOptions = polylineView.animatedOptions;
382
425
  renderer.animated = polylineView.animated;
383
426
  return;
384
427
  }
@@ -548,6 +591,7 @@ using namespace luggmaps::events;
548
591
  if (colors.count > 1) {
549
592
  renderer.strokeColors = colors;
550
593
  }
594
+ renderer.animatedOptions = polylineView.animatedOptions;
551
595
  renderer.animated = polylineView.animated;
552
596
  polylineView.renderer = renderer;
553
597
  return renderer;
@@ -339,6 +339,7 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
339
339
  if (animator) {
340
340
  animator.coordinates = polylineView.coordinates;
341
341
  animator.strokeColors = polylineView.strokeColors;
342
+ animator.animatedOptions = polylineView.animatedOptions;
342
343
  animator.animated = polylineView.animated;
343
344
  [animator update];
344
345
  }
@@ -370,6 +371,7 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
370
371
  animator.polyline = polyline;
371
372
  animator.coordinates = polylineView.coordinates;
372
373
  animator.strokeColors = polylineView.strokeColors;
374
+ animator.animatedOptions = polylineView.animatedOptions;
373
375
  animator.animated = polylineView.animated;
374
376
  [animator update];
375
377
 
@@ -1,3 +1,4 @@
1
+ #import "core/PolylineAnimatorBase.h"
1
2
  #import <CoreLocation/CoreLocation.h>
2
3
  #import <React/RCTViewComponentView.h>
3
4
  #import <UIKit/UIKit.h>
@@ -16,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
16
17
  @property(nonatomic, readonly) NSArray<CLLocation *> *coordinates;
17
18
  @property(nonatomic, readonly) NSArray<UIColor *> *strokeColors;
18
19
  @property(nonatomic, readonly) BOOL animated;
20
+ @property(nonatomic, readonly, nullable)
21
+ PolylineAnimatedOptions *animatedOptions;
19
22
  @property(nonatomic, readonly) CGFloat strokeWidth;
20
23
  @property(nonatomic, readonly) NSInteger zIndex;
21
24
  @property(nonatomic, weak, nullable) id<LuggPolylineViewDelegate> delegate;
@@ -17,6 +17,7 @@ using namespace facebook::react;
17
17
  NSArray<CLLocation *> *_coordinates;
18
18
  NSArray<UIColor *> *_strokeColors;
19
19
  BOOL _animated;
20
+ PolylineAnimatedOptions *_animatedOptions;
20
21
  CGFloat _strokeWidth;
21
22
  NSInteger _zIndex;
22
23
  }
@@ -72,6 +73,19 @@ using namespace facebook::react;
72
73
  }
73
74
 
74
75
  _animated = newViewProps.animated;
76
+
77
+ const auto &opts = newViewProps.animatedOptions;
78
+ PolylineAnimatedOptions *options = [[PolylineAnimatedOptions alloc] init];
79
+ options.duration = opts.duration > 0 ? opts.duration : 2150;
80
+ options.trailLength = (opts.trailLength > 0 && opts.trailLength <= 1.0)
81
+ ? opts.trailLength
82
+ : 1.0;
83
+ options.delay = opts.delay;
84
+ options.easing = !opts.easing.empty()
85
+ ? [NSString stringWithUTF8String:opts.easing.c_str()]
86
+ : @"linear";
87
+ _animatedOptions = options;
88
+
75
89
  _strokeWidth = newViewProps.strokeWidth > 0 ? newViewProps.strokeWidth : 1.0;
76
90
  _zIndex = newViewProps.zIndex.value_or(0);
77
91
  }
@@ -98,6 +112,10 @@ using namespace facebook::react;
98
112
  return _animated;
99
113
  }
100
114
 
115
+ - (PolylineAnimatedOptions *)animatedOptions {
116
+ return _animatedOptions;
117
+ }
118
+
101
119
  - (CGFloat)strokeWidth {
102
120
  return _strokeWidth;
103
121
  }
@@ -5,6 +5,7 @@
5
5
 
6
6
  @property(nonatomic, weak) GMSPolyline *polyline;
7
7
  @property(nonatomic, assign) BOOL animated;
8
+ @property(nonatomic, strong) PolylineAnimatedOptions *animatedOptions;
8
9
 
9
10
  - (void)update;
10
11
  - (void)pause;
@@ -30,10 +30,13 @@
30
30
  CADisplayLink *_displayLink;
31
31
  GMSDisplayLinkProxy *_displayLinkProxy;
32
32
  CGFloat _animationProgress;
33
+ CGFloat _delayRemaining;
33
34
  NSArray<NSNumber *> *_cumulativeDistances;
34
35
  CGFloat _totalLength;
35
36
  }
36
37
 
38
+ @synthesize animatedOptions = _animatedOptions;
39
+
37
40
  - (void)dealloc {
38
41
  [self stopAnimation];
39
42
  }
@@ -59,12 +62,21 @@
59
62
  }
60
63
  }
61
64
 
65
+ - (void)setAnimatedOptions:(PolylineAnimatedOptions *)animatedOptions {
66
+ _animatedOptions = animatedOptions ?: [PolylineAnimatedOptions defaultOptions];
67
+ if (_animated && _displayLink) {
68
+ [self stopAnimation];
69
+ [self startAnimation];
70
+ }
71
+ }
72
+
62
73
  - (void)startAnimation {
63
74
  if (_displayLink) {
64
75
  return;
65
76
  }
66
77
  [self computeCumulativeDistances];
67
78
  _animationProgress = 0;
79
+ _delayRemaining = self.animatedOptions.delay / 1000.0;
68
80
  _displayLinkProxy = [[GMSDisplayLinkProxy alloc] initWithTarget:self selector:@selector(animationTick:)];
69
81
  _displayLink = [CADisplayLink displayLinkWithTarget:_displayLinkProxy selector:@selector(tick:)];
70
82
  [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
@@ -101,11 +113,23 @@
101
113
  }
102
114
 
103
115
  - (void)animationTick:(CADisplayLink *)displayLink {
104
- CGFloat speed = displayLink.duration / 1.0;
116
+ if (_delayRemaining > 0) {
117
+ _delayRemaining -= displayLink.duration;
118
+ return;
119
+ }
120
+
121
+ CGFloat duration = self.animatedOptions.duration / 1000.0;
122
+ if (duration <= 0) duration = 2.15;
123
+
124
+ CGFloat trailLength = MAX(0.01, MIN(1.0, self.animatedOptions.trailLength));
125
+ CGFloat maxProgress = (trailLength < 1.0) ? 1.0 : 2.15;
126
+
127
+ CGFloat speed = displayLink.duration / duration;
105
128
  _animationProgress += speed;
106
129
 
107
- if (_animationProgress >= 2.15) {
130
+ if (_animationProgress >= maxProgress) {
108
131
  _animationProgress = 0;
132
+ _delayRemaining = self.animatedOptions.delay / 1000.0;
109
133
  }
110
134
 
111
135
  [self updateAnimatedPolyline];
@@ -175,14 +199,21 @@
175
199
  return;
176
200
  }
177
201
 
178
- CGFloat progress = MIN(_animationProgress, 2.0);
202
+ CGFloat trailLength = MAX(0.01, MIN(1.0, self.animatedOptions.trailLength));
203
+ CGFloat maxProgress = (trailLength < 1.0) ? 1.0 : 2.0;
204
+ CGFloat progress = MIN(_animationProgress, maxProgress);
205
+ CGFloat easedProgress = [self applyEasing:progress / maxProgress] * maxProgress;
206
+
179
207
  CGFloat headDist, tailDist;
180
208
 
181
- if (progress <= 1.0) {
209
+ if (trailLength < 1.0) {
210
+ headDist = easedProgress * _totalLength;
211
+ tailDist = MAX(0, headDist - _totalLength * trailLength);
212
+ } else if (easedProgress <= 1.0) {
182
213
  tailDist = 0;
183
- headDist = progress * _totalLength;
214
+ headDist = easedProgress * _totalLength;
184
215
  } else {
185
- CGFloat shrinkProgress = progress - 1.0;
216
+ CGFloat shrinkProgress = easedProgress - 1.0;
186
217
  tailDist = shrinkProgress * _totalLength;
187
218
  headDist = _totalLength;
188
219
  }
@@ -1,3 +1,4 @@
1
+ #import "PolylineAnimatorBase.h"
1
2
  #import <MapKit/MapKit.h>
2
3
 
3
4
  @interface MKPolylineAnimator : MKOverlayPathRenderer
@@ -6,6 +7,7 @@
6
7
 
7
8
  @property(nonatomic, strong) NSArray<UIColor *> *strokeColors;
8
9
  @property(nonatomic, assign) BOOL animated;
10
+ @property(nonatomic, strong) PolylineAnimatedOptions *animatedOptions;
9
11
 
10
12
  - (void)updatePolyline:(MKPolyline *)polyline;
11
13
  - (void)pause;
@@ -31,6 +31,7 @@
31
31
  CADisplayLink *_displayLink;
32
32
  MKDisplayLinkProxy *_displayLinkProxy;
33
33
  CGFloat _animationProgress;
34
+ CGFloat _delayRemaining;
34
35
  NSArray<NSNumber *> *_cumulativeDistances;
35
36
  CGFloat _totalLength;
36
37
  CGColorSpaceRef _colorSpace;
@@ -41,12 +42,21 @@
41
42
  if (self) {
42
43
  _polyline = polyline;
43
44
  _animationProgress = 0;
45
+ _animatedOptions = [PolylineAnimatedOptions defaultOptions];
44
46
  _colorSpace = CGColorSpaceCreateDeviceRGB();
45
47
  [self createPath];
46
48
  }
47
49
  return self;
48
50
  }
49
51
 
52
+ - (void)setAnimatedOptions:(PolylineAnimatedOptions *)animatedOptions {
53
+ _animatedOptions = animatedOptions ?: [PolylineAnimatedOptions defaultOptions];
54
+ if (_animated && _displayLink) {
55
+ [self stopAnimation];
56
+ [self startAnimation];
57
+ }
58
+ }
59
+
50
60
  - (void)dealloc {
51
61
  [self stopAnimation];
52
62
  if (_colorSpace) {
@@ -74,6 +84,7 @@
74
84
  }
75
85
  [self computeCumulativeDistances];
76
86
  _animationProgress = 0;
87
+ _delayRemaining = _animatedOptions.delay / 1000.0;
77
88
  _displayLinkProxy = [[MKDisplayLinkProxy alloc] initWithTarget:self selector:@selector(animationTick:)];
78
89
  _displayLink = [CADisplayLink displayLinkWithTarget:_displayLinkProxy selector:@selector(tick:)];
79
90
  [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
@@ -125,12 +136,37 @@
125
136
  return MIN(left, _cumulativeDistances.count - 2);
126
137
  }
127
138
 
139
+ - (CGFloat)applyEasing:(CGFloat)t {
140
+ NSString *easing = _animatedOptions.easing ?: @"linear";
141
+
142
+ if ([easing isEqualToString:@"easeIn"]) {
143
+ return t * t;
144
+ } else if ([easing isEqualToString:@"easeOut"]) {
145
+ return t * (2 - t);
146
+ } else if ([easing isEqualToString:@"easeInOut"]) {
147
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
148
+ }
149
+ return t;
150
+ }
151
+
128
152
  - (void)animationTick:(CADisplayLink *)displayLink {
129
- CGFloat speed = displayLink.duration / 1.0;
153
+ if (_delayRemaining > 0) {
154
+ _delayRemaining -= displayLink.duration;
155
+ return;
156
+ }
157
+
158
+ CGFloat duration = _animatedOptions.duration / 1000.0;
159
+ if (duration <= 0) duration = 2.15;
160
+
161
+ CGFloat trailLength = MAX(0.01, MIN(1.0, _animatedOptions.trailLength));
162
+ CGFloat maxProgress = (trailLength < 1.0) ? 1.0 : 2.15;
163
+
164
+ CGFloat speed = displayLink.duration / duration;
130
165
  _animationProgress += speed;
131
166
 
132
- if (_animationProgress >= 2.15) {
167
+ if (_animationProgress >= maxProgress) {
133
168
  _animationProgress = 0;
169
+ _delayRemaining = _animatedOptions.delay / 1000.0;
134
170
  }
135
171
 
136
172
  MKMapRect bounds = _polyline.boundingMapRect;
@@ -214,14 +250,21 @@
214
250
 
215
251
  // Snake animation: grow from start, then shrink from start
216
252
  if (_animated && _polyline.pointCount > 1 && _totalLength > 0) {
217
- CGFloat progress = MIN(_animationProgress, 2.0);
253
+ CGFloat trailLength = MAX(0.01, MIN(1.0, _animatedOptions.trailLength));
254
+ CGFloat maxProgress = (trailLength < 1.0) ? 1.0 : 2.0;
255
+ CGFloat progress = MIN(_animationProgress, maxProgress);
256
+ CGFloat easedProgress = [self applyEasing:progress / maxProgress] * maxProgress;
257
+
218
258
  CGFloat headDist, tailDist;
219
259
 
220
- if (progress <= 1.0) {
260
+ if (trailLength < 1.0) {
261
+ headDist = easedProgress * _totalLength;
262
+ tailDist = MAX(0, headDist - _totalLength * trailLength);
263
+ } else if (easedProgress <= 1.0) {
221
264
  tailDist = 0;
222
- headDist = progress * _totalLength;
265
+ headDist = easedProgress * _totalLength;
223
266
  } else {
224
- CGFloat shrinkProgress = progress - 1.0;
267
+ CGFloat shrinkProgress = easedProgress - 1.0;
225
268
  tailDist = shrinkProgress * _totalLength;
226
269
  headDist = _totalLength;
227
270
  }
@@ -2,11 +2,23 @@
2
2
  #import <Foundation/Foundation.h>
3
3
  #import <UIKit/UIKit.h>
4
4
 
5
+ @interface PolylineAnimatedOptions : NSObject
6
+
7
+ @property(nonatomic, assign) NSTimeInterval duration;
8
+ @property(nonatomic, copy) NSString *easing;
9
+ @property(nonatomic, assign) CGFloat trailLength;
10
+ @property(nonatomic, assign) NSTimeInterval delay;
11
+
12
+ + (instancetype)defaultOptions;
13
+
14
+ @end
15
+
5
16
  @protocol PolylineAnimator <NSObject>
6
17
 
7
18
  @property(nonatomic, strong) NSArray<CLLocation *> *coordinates;
8
19
  @property(nonatomic, strong) NSArray<UIColor *> *strokeColors;
9
20
  @property(nonatomic, assign) BOOL animated;
21
+ @property(nonatomic, strong) PolylineAnimatedOptions *animatedOptions;
10
22
 
11
23
  - (void)update;
12
24
 
@@ -16,7 +28,9 @@
16
28
 
17
29
  @property(nonatomic, strong) NSArray<CLLocation *> *coordinates;
18
30
  @property(nonatomic, strong) NSArray<UIColor *> *strokeColors;
31
+ @property(nonatomic, strong) PolylineAnimatedOptions *animatedOptions;
19
32
 
20
33
  - (UIColor *)colorAtGradientPosition:(CGFloat)position;
34
+ - (CGFloat)applyEasing:(CGFloat)t;
21
35
 
22
36
  @end
@@ -1,7 +1,40 @@
1
1
  #import "PolylineAnimatorBase.h"
2
2
 
3
+ @implementation PolylineAnimatedOptions
4
+
5
+ + (instancetype)defaultOptions {
6
+ PolylineAnimatedOptions *options = [[PolylineAnimatedOptions alloc] init];
7
+ options.duration = 2.15;
8
+ options.easing = @"linear";
9
+ options.trailLength = 1.0;
10
+ options.delay = 0;
11
+ return options;
12
+ }
13
+
14
+ @end
15
+
3
16
  @implementation PolylineAnimatorBase
4
17
 
18
+ - (instancetype)init {
19
+ if (self = [super init]) {
20
+ _animatedOptions = [PolylineAnimatedOptions defaultOptions];
21
+ }
22
+ return self;
23
+ }
24
+
25
+ - (CGFloat)applyEasing:(CGFloat)t {
26
+ NSString *easing = self.animatedOptions.easing ?: @"linear";
27
+
28
+ if ([easing isEqualToString:@"easeIn"]) {
29
+ return t * t;
30
+ } else if ([easing isEqualToString:@"easeOut"]) {
31
+ return t * (2 - t);
32
+ } else if ([easing isEqualToString:@"easeInOut"]) {
33
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
34
+ }
35
+ return t;
36
+ }
37
+
5
38
  - (UIColor *)colorAtGradientPosition:(CGFloat)position {
6
39
  if (!_strokeColors || _strokeColors.count == 0) {
7
40
  return [UIColor blackColor];
@@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
12
12
  (CLLocationCoordinate2D)centerCoordinate
13
13
  zoomLevel:(double)zoomLevel;
14
14
 
15
+ /// Returns the zoom level based on the full map region, not affected by
16
+ /// layoutMargins
15
17
  - (double)zoomLevel;
16
18
 
17
19
  @end
@@ -19,12 +19,21 @@
19
19
 
20
20
  #pragma mark - Public Methods
21
21
 
22
+ // Constant for altitude/zoom conversion (meters at zoom level 0)
23
+ static const double kAltitudeAtZoomZero = 220000000.0;
24
+
22
25
  - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
23
26
  zoomLevel:(double)zoomLevel
24
27
  animated:(BOOL)animated
25
28
  {
26
- MKCoordinateRegion region = [self regionForCenterCoordinate:centerCoordinate zoomLevel:zoomLevel];
27
- [self setRegion:region animated:animated];
29
+ // Use camera API directly to avoid region/margin interaction
30
+ CLLocationDistance altitude = kAltitudeAtZoomZero / pow(2, zoomLevel);
31
+ MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:centerCoordinate
32
+ fromEyeCoordinate:centerCoordinate
33
+ eyeAltitude:altitude];
34
+ camera.pitch = self.camera.pitch;
35
+ camera.heading = self.camera.heading;
36
+ [self setCamera:camera animated:animated];
28
37
  }
29
38
 
30
39
  - (MKCoordinateRegion)regionForCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
@@ -37,8 +46,9 @@
37
46
 
38
47
  - (double)zoomLevel
39
48
  {
40
- MKCoordinateRegion region = self.region;
41
- double zoomLevel = log2(360.0 / region.span.latitudeDelta) + 0.5;
49
+ // Use camera altitude which isn't affected by layoutMargins
50
+ CLLocationDistance altitude = self.camera.altitude;
51
+ double zoomLevel = log2(kAltitudeAtZoomZero / altitude);
42
52
  return zoomLevel;
43
53
  }
44
54
 
@@ -11,6 +11,7 @@ export class Polyline extends React.Component {
11
11
  strokeColors,
12
12
  strokeWidth,
13
13
  animated = false,
14
+ animatedOptions,
14
15
  zIndex
15
16
  } = this.props;
16
17
  return /*#__PURE__*/_jsx(LuggPolylineViewNativeComponent, {
@@ -20,7 +21,8 @@ export class Polyline extends React.Component {
20
21
  coordinates: coordinates,
21
22
  strokeColors: strokeColors,
22
23
  strokeWidth: strokeWidth,
23
- animated: animated
24
+ animated: animated,
25
+ animatedOptions: animatedOptions
24
26
  });
25
27
  }
26
28
  }
@@ -1 +1 @@
1
- {"version":3,"names":["React","StyleSheet","LuggPolylineViewNativeComponent","jsx","_jsx","Polyline","Component","render","coordinates","strokeColors","strokeWidth","animated","zIndex","props","style","styles","polyline","create","position","pointerEvents"],"sourceRoot":"../../../src","sources":["components/Polyline.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SAASC,UAAU,QAAQ,cAAc;AACzC,OAAOC,+BAA+B,MAAM,2CAA2C;AAAC,SAAAC,GAAA,IAAAC,IAAA;AA0BxF,OAAO,MAAMC,QAAQ,SAASL,KAAK,CAACM,SAAS,CAAgB;EAC3DC,MAAMA,CAAA,EAAG;IACP,MAAM;MACJC,WAAW;MACXC,YAAY;MACZC,WAAW;MACXC,QAAQ,GAAG,KAAK;MAChBC;IACF,CAAC,GAAG,IAAI,CAACC,KAAK;IAEd,oBACET,IAAA,CAACF,+BAA+B;MAC9BY,KAAK,EAAE,CAAC;QAAEF;MAAO,CAAC,EAAEG,MAAM,CAACC,QAAQ,CAAE;MACrCR,WAAW,EAAEA,WAAY;MACzBC,YAAY,EAAEA,YAAa;MAC3BC,WAAW,EAAEA,WAAY;MACzBC,QAAQ,EAAEA;IAAS,CACpB,CAAC;EAEN;AACF;AAEA,MAAMI,MAAM,GAAGd,UAAU,CAACgB,MAAM,CAAC;EAC/BD,QAAQ,EAAE;IACRE,QAAQ,EAAE,UAAU;IACpBC,aAAa,EAAE;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["React","StyleSheet","LuggPolylineViewNativeComponent","jsx","_jsx","Polyline","Component","render","coordinates","strokeColors","strokeWidth","animated","animatedOptions","zIndex","props","style","styles","polyline","create","position","pointerEvents"],"sourceRoot":"../../../src","sources":["components/Polyline.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SAASC,UAAU,QAAQ,cAAc;AACzC,OAAOC,+BAA+B,MAAM,2CAA2C;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAwDxF,OAAO,MAAMC,QAAQ,SAASL,KAAK,CAACM,SAAS,CAAgB;EAC3DC,MAAMA,CAAA,EAAG;IACP,MAAM;MACJC,WAAW;MACXC,YAAY;MACZC,WAAW;MACXC,QAAQ,GAAG,KAAK;MAChBC,eAAe;MACfC;IACF,CAAC,GAAG,IAAI,CAACC,KAAK;IAEd,oBACEV,IAAA,CAACF,+BAA+B;MAC9Ba,KAAK,EAAE,CAAC;QAAEF;MAAO,CAAC,EAAEG,MAAM,CAACC,QAAQ,CAAE;MACrCT,WAAW,EAAEA,WAAY;MACzBC,YAAY,EAAEA,YAAa;MAC3BC,WAAW,EAAEA,WAAY;MACzBC,QAAQ,EAAEA,QAAS;MACnBC,eAAe,EAAEA;IAAgB,CAClC,CAAC;EAEN;AACF;AAEA,MAAMI,MAAM,GAAGf,UAAU,CAACiB,MAAM,CAAC;EAC/BD,QAAQ,EAAE;IACRE,QAAQ,EAAE,UAAU;IACpBC,aAAa,EAAE;EACjB;AACF,CAAC,CAAC","ignoreList":[]}
@@ -2,7 +2,19 @@
2
2
 
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { useMapContext } from "../MapProvider.web.js";
5
- const ANIMATION_DURATION = 1500;
5
+ const DEFAULT_DURATION = 2150;
6
+ function applyEasing(t, easing = 'linear') {
7
+ switch (easing) {
8
+ case 'easeIn':
9
+ return t * t;
10
+ case 'easeOut':
11
+ return t * (2 - t);
12
+ case 'easeInOut':
13
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
14
+ default:
15
+ return t;
16
+ }
17
+ }
6
18
  function interpolateColor(color1, color2, t) {
7
19
  const hex = c => parseInt(c, 16);
8
20
  const r1 = hex(color1.slice(1, 3));
@@ -30,6 +42,7 @@ export function Polyline({
30
42
  strokeColors,
31
43
  strokeWidth = 1,
32
44
  animated,
45
+ animatedOptions,
33
46
  zIndex
34
47
  }) {
35
48
  const resolvedZIndex = zIndex ?? (animated ? 1 : 0);
@@ -129,16 +142,50 @@ export function Polyline({
129
142
  updatePath(fullPath);
130
143
  return;
131
144
  }
145
+ const duration = animatedOptions?.duration ?? DEFAULT_DURATION;
146
+ const easing = animatedOptions?.easing ?? 'linear';
147
+ const trailLength = Math.max(0.01, Math.min(1, animatedOptions?.trailLength ?? 1));
148
+ const delay = animatedOptions?.delay ?? 0;
132
149
  const totalPoints = fullPath.length;
133
- const cycleDuration = ANIMATION_DURATION * 2;
150
+ const useTrailMode = trailLength < 1;
151
+ const cycleDuration = useTrailMode ? duration : duration * 2;
152
+ let startTime = null;
153
+ let delayRemaining = delay;
134
154
  const animate = time => {
135
155
  if (isPausedRef.current) {
156
+ startTime = null;
136
157
  animationRef.current = requestAnimationFrame(animate);
137
158
  return;
138
159
  }
139
- const progress = time % cycleDuration / ANIMATION_DURATION;
140
- const startIdx = progress <= 1 ? 0 : (progress - 1) * totalPoints;
141
- const endIdx = progress <= 1 ? progress * totalPoints : totalPoints;
160
+ if (startTime === null) {
161
+ startTime = time;
162
+ }
163
+ const elapsed = time - startTime;
164
+ if (delayRemaining > 0) {
165
+ if (elapsed < delayRemaining) {
166
+ animationRef.current = requestAnimationFrame(animate);
167
+ return;
168
+ }
169
+ startTime = time - (elapsed - delayRemaining);
170
+ delayRemaining = 0;
171
+ }
172
+ const rawProgress = (time - startTime) % cycleDuration / duration;
173
+ const maxProgress = useTrailMode ? 1 : 2;
174
+ const clampedProgress = Math.min(rawProgress, maxProgress);
175
+ const easedProgress = applyEasing(clampedProgress / maxProgress, easing) * maxProgress;
176
+ let startIdx;
177
+ let endIdx;
178
+ if (useTrailMode) {
179
+ endIdx = easedProgress * totalPoints;
180
+ startIdx = Math.max(0, endIdx - trailLength * totalPoints);
181
+ } else {
182
+ startIdx = easedProgress <= 1 ? 0 : (easedProgress - 1) * totalPoints;
183
+ endIdx = easedProgress <= 1 ? easedProgress * totalPoints : totalPoints;
184
+ }
185
+ if (rawProgress >= maxProgress) {
186
+ delayRemaining = delay;
187
+ startTime = time;
188
+ }
142
189
  const partialPath = [];
143
190
  const startFloor = Math.floor(startIdx);
144
191
  const endFloor = Math.floor(endIdx);
@@ -176,7 +223,7 @@ export function Polyline({
176
223
  };
177
224
  animationRef.current = requestAnimationFrame(animate);
178
225
  return () => cancelAnimationFrame(animationRef.current);
179
- }, [coordinates, animated, hasGradient, updatePath, mapReady]);
226
+ }, [coordinates, animated, animatedOptions, hasGradient, updatePath, mapReady]);
180
227
  return null;
181
228
  }
182
229
  //# sourceMappingURL=Polyline.web.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","useMapContext","ANIMATION_DURATION","interpolateColor","color1","color2","t","hex","c","parseInt","r1","slice","g1","b1","r2","g2","b2","r","Math","round","g","b","toString","padStart","getGradientColor","colors","position","length","scaledPos","index","floor","Polyline","coordinates","strokeColors","strokeWidth","animated","zIndex","resolvedZIndex","map","isDragging","polylinesRef","animationRef","isPausedRef","hasGradient","propsRef","mapReady","setMapReady","current","updatePath","path","currentMap","currentColors","currentStrokeWidth","currentHasGradient","currentZIndex","neededSegments","existing","i","segmentPath","color","segment","setPath","setOptions","strokeColor","push","google","maps","strokeWeight","strokeOpacity","setMap","polylines","cancelAnimationFrame","forEach","p","fullPath","lat","latitude","lng","longitude","totalPoints","cycleDuration","animate","time","requestAnimationFrame","progress","startIdx","endIdx","partialPath","startFloor","endFloor","frac","from","to","min"],"sourceRoot":"../../../src","sources":["components/Polyline.web.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useCallback","useEffect","useMemo","useRef","useState","useMapContext","DEFAULT_DURATION","applyEasing","t","easing","interpolateColor","color1","color2","hex","c","parseInt","r1","slice","g1","b1","r2","g2","b2","r","Math","round","g","b","toString","padStart","getGradientColor","colors","position","length","scaledPos","index","floor","Polyline","coordinates","strokeColors","strokeWidth","animated","animatedOptions","zIndex","resolvedZIndex","map","isDragging","polylinesRef","animationRef","isPausedRef","hasGradient","propsRef","mapReady","setMapReady","current","updatePath","path","currentMap","currentColors","currentStrokeWidth","currentHasGradient","currentZIndex","neededSegments","existing","i","segmentPath","color","segment","setPath","setOptions","strokeColor","push","google","maps","strokeWeight","strokeOpacity","setMap","polylines","cancelAnimationFrame","forEach","p","fullPath","lat","latitude","lng","longitude","duration","trailLength","max","min","delay","totalPoints","useTrailMode","cycleDuration","startTime","delayRemaining","animate","time","requestAnimationFrame","elapsed","rawProgress","maxProgress","clampedProgress","easedProgress","startIdx","endIdx","partialPath","startFloor","endFloor","frac","from","to"],"sourceRoot":"../../../src","sources":["components/Polyline.web.tsx"],"mappings":"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","ignoreList":[]}
@@ -7,11 +7,19 @@ export interface Coordinate {
7
7
  longitude: Double;
8
8
  }
9
9
 
10
+ export interface AnimatedOptions {
11
+ duration?: Double;
12
+ easing?: string;
13
+ trailLength?: Double;
14
+ delay?: Double;
15
+ }
16
+
10
17
  export interface NativeProps extends ViewProps {
11
18
  coordinates: ReadonlyArray<Coordinate>;
12
19
  strokeColors?: ReadonlyArray<ColorValue>;
13
20
  strokeWidth?: Double;
14
21
  animated?: boolean;
22
+ animatedOptions?: AnimatedOptions;
15
23
  }
16
24
 
17
25
  export default codegenNativeComponent<NativeProps>(
@@ -1,6 +1,30 @@
1
1
  import React from 'react';
2
2
  import type { ColorValue } from 'react-native';
3
3
  import type { Coordinate } from '../types';
4
+ export type PolylineEasing = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
5
+ export interface PolylineAnimatedOptions {
6
+ /**
7
+ * Animation duration in milliseconds
8
+ * @default 2150
9
+ */
10
+ duration?: number;
11
+ /**
12
+ * Easing function for the animation
13
+ * @default 'linear'
14
+ */
15
+ easing?: PolylineEasing;
16
+ /**
17
+ * Portion of the line visible as trail (0-1)
18
+ * 1.0 = full snake effect, 0.2 = short worm
19
+ * @default 1.0
20
+ */
21
+ trailLength?: number;
22
+ /**
23
+ * Delay before animation starts in milliseconds
24
+ * @default 0
25
+ */
26
+ delay?: number;
27
+ }
4
28
  export interface PolylineProps {
5
29
  /**
6
30
  * Array of coordinates forming the polyline
@@ -18,6 +42,10 @@ export interface PolylineProps {
18
42
  * Animate the polyline with a snake effect
19
43
  */
20
44
  animated?: boolean;
45
+ /**
46
+ * Animation configuration options
47
+ */
48
+ animatedOptions?: PolylineAnimatedOptions;
21
49
  /**
22
50
  * Z-index for layering polylines
23
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Polyline.d.ts","sourceRoot":"","sources":["../../../../src/components/Polyline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;IAC5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,QAAS,SAAQ,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC;IAC1D,MAAM;CAmBP"}
1
+ {"version":3,"file":"Polyline.d.ts","sourceRoot":"","sources":["../../../../src/components/Polyline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AAE3E,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;IAC5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,QAAS,SAAQ,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC;IAC1D,MAAM;CAqBP"}
@@ -1,3 +1,3 @@
1
1
  import type { PolylineProps } from './Polyline';
2
- export declare function Polyline({ coordinates, strokeColors, strokeWidth, animated, zIndex, }: PolylineProps): null;
2
+ export declare function Polyline({ coordinates, strokeColors, strokeWidth, animated, animatedOptions, zIndex, }: PolylineProps): null;
3
3
  //# sourceMappingURL=Polyline.web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Polyline.web.d.ts","sourceRoot":"","sources":["../../../../src/components/Polyline.web.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkChD,wBAAgB,QAAQ,CAAC,EACvB,WAAW,EACX,YAAY,EACZ,WAAe,EACf,QAAQ,EACR,MAAM,GACP,EAAE,aAAa,QAiLf"}
1
+ {"version":3,"file":"Polyline.web.d.ts","sourceRoot":"","sources":["../../../../src/components/Polyline.web.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,YAAY,CAAC;AA+ChE,wBAAgB,QAAQ,CAAC,EACvB,WAAW,EACX,YAAY,EACZ,WAAe,EACf,QAAQ,EACR,eAAe,EACf,MAAM,GACP,EAAE,aAAa,QAsOf"}
@@ -4,11 +4,18 @@ export interface Coordinate {
4
4
  latitude: Double;
5
5
  longitude: Double;
6
6
  }
7
+ export interface AnimatedOptions {
8
+ duration?: Double;
9
+ easing?: string;
10
+ trailLength?: Double;
11
+ delay?: Double;
12
+ }
7
13
  export interface NativeProps extends ViewProps {
8
14
  coordinates: ReadonlyArray<Coordinate>;
9
15
  strokeColors?: ReadonlyArray<ColorValue>;
10
16
  strokeWidth?: Double;
11
17
  animated?: boolean;
18
+ animatedOptions?: AnimatedOptions;
12
19
  }
13
20
  declare const _default: HostComponent<NativeProps>;
14
21
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"LuggPolylineViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/fabric/LuggPolylineViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;wBAII,aAAa,CAAC,WAAW,CAAC;AAF/B,wBAEgC"}
1
+ {"version":3,"file":"LuggPolylineViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/fabric/LuggPolylineViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;wBAII,aAAa,CAAC,WAAW,CAAC;AAF/B,wBAEgC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lugg/maps",
3
- "version": "0.2.0-alpha.19",
3
+ "version": "0.2.0-alpha.20",
4
4
  "description": "Universal maps for React Native.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -4,6 +4,32 @@ import { StyleSheet } from 'react-native';
4
4
  import LuggPolylineViewNativeComponent from '../fabric/LuggPolylineViewNativeComponent';
5
5
  import type { Coordinate } from '../types';
6
6
 
7
+ export type PolylineEasing = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut';
8
+
9
+ export interface PolylineAnimatedOptions {
10
+ /**
11
+ * Animation duration in milliseconds
12
+ * @default 2150
13
+ */
14
+ duration?: number;
15
+ /**
16
+ * Easing function for the animation
17
+ * @default 'linear'
18
+ */
19
+ easing?: PolylineEasing;
20
+ /**
21
+ * Portion of the line visible as trail (0-1)
22
+ * 1.0 = full snake effect, 0.2 = short worm
23
+ * @default 1.0
24
+ */
25
+ trailLength?: number;
26
+ /**
27
+ * Delay before animation starts in milliseconds
28
+ * @default 0
29
+ */
30
+ delay?: number;
31
+ }
32
+
7
33
  export interface PolylineProps {
8
34
  /**
9
35
  * Array of coordinates forming the polyline
@@ -21,6 +47,10 @@ export interface PolylineProps {
21
47
  * Animate the polyline with a snake effect
22
48
  */
23
49
  animated?: boolean;
50
+ /**
51
+ * Animation configuration options
52
+ */
53
+ animatedOptions?: PolylineAnimatedOptions;
24
54
  /**
25
55
  * Z-index for layering polylines
26
56
  */
@@ -34,6 +64,7 @@ export class Polyline extends React.Component<PolylineProps> {
34
64
  strokeColors,
35
65
  strokeWidth,
36
66
  animated = false,
67
+ animatedOptions,
37
68
  zIndex,
38
69
  } = this.props;
39
70
 
@@ -44,6 +75,7 @@ export class Polyline extends React.Component<PolylineProps> {
44
75
  strokeColors={strokeColors}
45
76
  strokeWidth={strokeWidth}
46
77
  animated={animated}
78
+ animatedOptions={animatedOptions}
47
79
  />
48
80
  );
49
81
  }
@@ -1,8 +1,21 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useMapContext } from '../MapProvider.web';
3
- import type { PolylineProps } from './Polyline';
4
-
5
- const ANIMATION_DURATION = 1500;
3
+ import type { PolylineProps, PolylineEasing } from './Polyline';
4
+
5
+ const DEFAULT_DURATION = 2150;
6
+
7
+ function applyEasing(t: number, easing: PolylineEasing = 'linear'): number {
8
+ switch (easing) {
9
+ case 'easeIn':
10
+ return t * t;
11
+ case 'easeOut':
12
+ return t * (2 - t);
13
+ case 'easeInOut':
14
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
15
+ default:
16
+ return t;
17
+ }
18
+ }
6
19
 
7
20
  function interpolateColor(color1: string, color2: string, t: number): string {
8
21
  const hex = (c: string) => parseInt(c, 16);
@@ -39,6 +52,7 @@ export function Polyline({
39
52
  strokeColors,
40
53
  strokeWidth = 1,
41
54
  animated,
55
+ animatedOptions,
42
56
  zIndex,
43
57
  }: PolylineProps) {
44
58
  const resolvedZIndex = zIndex ?? (animated ? 1 : 0);
@@ -153,18 +167,64 @@ export function Polyline({
153
167
  return;
154
168
  }
155
169
 
170
+ const duration = animatedOptions?.duration ?? DEFAULT_DURATION;
171
+ const easing = animatedOptions?.easing ?? 'linear';
172
+ const trailLength = Math.max(
173
+ 0.01,
174
+ Math.min(1, animatedOptions?.trailLength ?? 1)
175
+ );
176
+ const delay = animatedOptions?.delay ?? 0;
177
+
156
178
  const totalPoints = fullPath.length;
157
- const cycleDuration = ANIMATION_DURATION * 2;
179
+ const useTrailMode = trailLength < 1;
180
+ const cycleDuration = useTrailMode ? duration : duration * 2;
181
+
182
+ let startTime: number | null = null;
183
+ let delayRemaining = delay;
158
184
 
159
185
  const animate = (time: number) => {
160
186
  if (isPausedRef.current) {
187
+ startTime = null;
161
188
  animationRef.current = requestAnimationFrame(animate);
162
189
  return;
163
190
  }
164
191
 
165
- const progress = (time % cycleDuration) / ANIMATION_DURATION;
166
- const startIdx = progress <= 1 ? 0 : (progress - 1) * totalPoints;
167
- const endIdx = progress <= 1 ? progress * totalPoints : totalPoints;
192
+ if (startTime === null) {
193
+ startTime = time;
194
+ }
195
+
196
+ const elapsed = time - startTime;
197
+
198
+ if (delayRemaining > 0) {
199
+ if (elapsed < delayRemaining) {
200
+ animationRef.current = requestAnimationFrame(animate);
201
+ return;
202
+ }
203
+ startTime = time - (elapsed - delayRemaining);
204
+ delayRemaining = 0;
205
+ }
206
+
207
+ const rawProgress = ((time - startTime) % cycleDuration) / duration;
208
+ const maxProgress = useTrailMode ? 1 : 2;
209
+ const clampedProgress = Math.min(rawProgress, maxProgress);
210
+ const easedProgress =
211
+ applyEasing(clampedProgress / maxProgress, easing) * maxProgress;
212
+
213
+ let startIdx: number;
214
+ let endIdx: number;
215
+
216
+ if (useTrailMode) {
217
+ endIdx = easedProgress * totalPoints;
218
+ startIdx = Math.max(0, endIdx - trailLength * totalPoints);
219
+ } else {
220
+ startIdx = easedProgress <= 1 ? 0 : (easedProgress - 1) * totalPoints;
221
+ endIdx = easedProgress <= 1 ? easedProgress * totalPoints : totalPoints;
222
+ }
223
+
224
+ if (rawProgress >= maxProgress) {
225
+ delayRemaining = delay;
226
+ startTime = time;
227
+ }
168
228
 
169
229
  const partialPath: google.maps.LatLngLiteral[] = [];
170
230
  const startFloor = Math.floor(startIdx);
@@ -214,7 +274,14 @@ export function Polyline({
214
274
  animationRef.current = requestAnimationFrame(animate);
215
275
 
216
276
  return () => cancelAnimationFrame(animationRef.current);
217
- }, [coordinates, animated, hasGradient, updatePath, mapReady]);
277
+ }, [
278
+ coordinates,
279
+ animated,
280
+ animatedOptions,
281
+ hasGradient,
282
+ updatePath,
283
+ mapReady,
284
+ ]);
218
285
 
219
286
  return null;
220
287
  }
@@ -7,11 +7,19 @@ export interface Coordinate {
7
7
  longitude: Double;
8
8
  }
9
9
 
10
+ export interface AnimatedOptions {
11
+ duration?: Double;
12
+ easing?: string;
13
+ trailLength?: Double;
14
+ delay?: Double;
15
+ }
16
+
10
17
  export interface NativeProps extends ViewProps {
11
18
  coordinates: ReadonlyArray<Coordinate>;
12
19
  strokeColors?: ReadonlyArray<ColorValue>;
13
20
  strokeWidth?: Double;
14
21
  animated?: boolean;
22
+ animatedOptions?: AnimatedOptions;
15
23
  }
16
24
 
17
25
  export default codegenNativeComponent<NativeProps>(