@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.
- package/android/src/main/java/com/luggmaps/LuggGoogleMapView.kt +2 -0
- package/android/src/main/java/com/luggmaps/LuggPolylineView.kt +9 -0
- package/android/src/main/java/com/luggmaps/LuggPolylineViewManager.kt +16 -0
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +41 -5
- package/ios/LuggAppleMapView.mm +47 -3
- package/ios/LuggGoogleMapView.mm +2 -0
- package/ios/LuggPolylineView.h +3 -0
- package/ios/LuggPolylineView.mm +18 -0
- package/ios/core/GMSPolylineAnimator.h +1 -0
- package/ios/core/GMSPolylineAnimator.m +37 -6
- package/ios/core/MKPolylineAnimator.h +2 -0
- package/ios/core/MKPolylineAnimator.m +49 -6
- package/ios/core/PolylineAnimatorBase.h +14 -0
- package/ios/core/PolylineAnimatorBase.m +33 -0
- package/ios/extensions/MKMapView+Zoom.h +2 -0
- package/ios/extensions/MKMapView+Zoom.m +14 -4
- package/lib/module/components/Polyline.js +3 -1
- package/lib/module/components/Polyline.js.map +1 -1
- package/lib/module/components/Polyline.web.js +53 -6
- package/lib/module/components/Polyline.web.js.map +1 -1
- package/lib/module/fabric/LuggPolylineViewNativeComponent.ts +8 -0
- package/lib/typescript/src/components/Polyline.d.ts +28 -0
- package/lib/typescript/src/components/Polyline.d.ts.map +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts +1 -1
- package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts +7 -0
- package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Polyline.tsx +32 -0
- package/src/components/Polyline.web.tsx +75 -8
- 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
|
-
|
|
68
|
-
|
|
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 =
|
|
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
|
|
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 (
|
|
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 {
|
package/ios/LuggAppleMapView.mm
CHANGED
|
@@ -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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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;
|
package/ios/LuggGoogleMapView.mm
CHANGED
|
@@ -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
|
|
package/ios/LuggPolylineView.h
CHANGED
|
@@ -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;
|
package/ios/LuggPolylineView.mm
CHANGED
|
@@ -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
|
}
|
|
@@ -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
|
-
|
|
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 >=
|
|
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
|
|
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 (
|
|
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 =
|
|
214
|
+
headDist = easedProgress * _totalLength;
|
|
184
215
|
} else {
|
|
185
|
-
CGFloat shrinkProgress =
|
|
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
|
-
|
|
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 >=
|
|
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
|
|
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 (
|
|
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 =
|
|
265
|
+
headDist = easedProgress * _totalLength;
|
|
223
266
|
} else {
|
|
224
|
-
CGFloat shrinkProgress =
|
|
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];
|
|
@@ -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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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;
|
|
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
|
|
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
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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","
|
|
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;
|
|
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,
|
|
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;
|
|
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
|
@@ -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
|
|
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
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
}, [
|
|
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>(
|