@lugg/maps 0.2.0-alpha.2 → 0.2.0-alpha.4
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 +0 -1
- package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +83 -43
- package/ios/LuggAppleMapView.mm +0 -1
- package/ios/LuggGoogleMapView.mm +0 -1
- package/ios/core/GMSPolylineAnimator.m +78 -36
- package/ios/core/MKPolylineAnimator.m +60 -32
- package/package.json +3 -2
|
@@ -311,7 +311,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
|
|
|
311
311
|
.position(position)
|
|
312
312
|
.title(markerView.title)
|
|
313
313
|
.snippet(markerView.description)
|
|
314
|
-
.collisionBehavior(CollisionBehavior.REQUIRED)
|
|
315
314
|
|
|
316
315
|
Log.d(TAG, "adding marker: ${markerView.name} customview: ${markerView.hasCustomView}")
|
|
317
316
|
if (markerView.hasCustomView) {
|
|
@@ -2,13 +2,13 @@ package com.luggmaps.core
|
|
|
2
2
|
|
|
3
3
|
import android.animation.ValueAnimator
|
|
4
4
|
import android.graphics.Color
|
|
5
|
+
import android.location.Location
|
|
5
6
|
import android.view.animation.LinearInterpolator
|
|
6
7
|
import com.google.android.gms.maps.model.LatLng
|
|
7
8
|
import com.google.android.gms.maps.model.Polyline
|
|
8
9
|
import com.google.android.gms.maps.model.StrokeStyle
|
|
9
10
|
import com.google.android.gms.maps.model.StyleSpan
|
|
10
11
|
import kotlin.math.floor
|
|
11
|
-
import kotlin.math.max
|
|
12
12
|
import kotlin.math.min
|
|
13
13
|
|
|
14
14
|
class PolylineAnimator {
|
|
@@ -31,6 +31,8 @@ class PolylineAnimator {
|
|
|
31
31
|
|
|
32
32
|
private var animator: ValueAnimator? = null
|
|
33
33
|
private var animationProgress: Float = 0f
|
|
34
|
+
private var cumulativeDistances: FloatArray = floatArrayOf()
|
|
35
|
+
private var totalLength: Float = 0f
|
|
34
36
|
|
|
35
37
|
fun update() {
|
|
36
38
|
if (animated) return
|
|
@@ -50,8 +52,10 @@ class PolylineAnimator {
|
|
|
50
52
|
private fun startAnimation() {
|
|
51
53
|
if (animator != null) return
|
|
52
54
|
|
|
55
|
+
computeCumulativeDistances()
|
|
56
|
+
|
|
53
57
|
animator = ValueAnimator.ofFloat(0f, 2.15f).apply {
|
|
54
|
-
duration =
|
|
58
|
+
duration = 2150
|
|
55
59
|
repeatCount = ValueAnimator.INFINITE
|
|
56
60
|
interpolator = LinearInterpolator()
|
|
57
61
|
addUpdateListener { animation ->
|
|
@@ -62,6 +66,58 @@ class PolylineAnimator {
|
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
|
|
69
|
+
private fun computeCumulativeDistances() {
|
|
70
|
+
if (coordinates.size < 2) {
|
|
71
|
+
cumulativeDistances = floatArrayOf(0f)
|
|
72
|
+
totalLength = 0f
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
val distances = FloatArray(coordinates.size)
|
|
77
|
+
distances[0] = 0f
|
|
78
|
+
var total = 0f
|
|
79
|
+
|
|
80
|
+
for (i in 1 until coordinates.size) {
|
|
81
|
+
val prev = coordinates[i - 1]
|
|
82
|
+
val curr = coordinates[i]
|
|
83
|
+
val results = FloatArray(1)
|
|
84
|
+
Location.distanceBetween(prev.latitude, prev.longitude, curr.latitude, curr.longitude, results)
|
|
85
|
+
total += results[0]
|
|
86
|
+
distances[i] = total
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
cumulativeDistances = distances
|
|
90
|
+
totalLength = total
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private fun indexForDistance(distance: Float): Int {
|
|
94
|
+
for (i in 1 until cumulativeDistances.size) {
|
|
95
|
+
if (cumulativeDistances[i] >= distance) {
|
|
96
|
+
return i - 1
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return (cumulativeDistances.size - 2).coerceAtLeast(0)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private fun coordinateAtDistance(distance: Float): LatLng {
|
|
103
|
+
if (distance <= 0f) return coordinates.first()
|
|
104
|
+
if (distance >= totalLength) return coordinates.last()
|
|
105
|
+
|
|
106
|
+
val idx = indexForDistance(distance)
|
|
107
|
+
val segStart = cumulativeDistances[idx]
|
|
108
|
+
val segEnd = cumulativeDistances[idx + 1]
|
|
109
|
+
val segLength = segEnd - segStart
|
|
110
|
+
|
|
111
|
+
val t = if (segLength > 0) (distance - segStart) / segLength else 0f
|
|
112
|
+
val c1 = coordinates[idx]
|
|
113
|
+
val c2 = coordinates[idx + 1]
|
|
114
|
+
|
|
115
|
+
return LatLng(
|
|
116
|
+
c1.latitude + (c2.latitude - c1.latitude) * t,
|
|
117
|
+
c1.longitude + (c2.longitude - c1.longitude) * t
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
65
121
|
private fun stopAnimation() {
|
|
66
122
|
animator?.cancel()
|
|
67
123
|
animator = null
|
|
@@ -69,71 +125,55 @@ class PolylineAnimator {
|
|
|
69
125
|
|
|
70
126
|
private fun updateAnimatedPolyline() {
|
|
71
127
|
val poly = polyline ?: return
|
|
72
|
-
if (coordinates.size < 2) {
|
|
128
|
+
if (coordinates.size < 2 || totalLength <= 0f) {
|
|
73
129
|
poly.points = coordinates
|
|
74
130
|
return
|
|
75
131
|
}
|
|
76
132
|
|
|
77
|
-
val segmentCount = coordinates.size - 1
|
|
78
133
|
val progress = min(animationProgress, 2f)
|
|
79
134
|
|
|
80
|
-
val
|
|
81
|
-
val
|
|
135
|
+
val headDist: Float
|
|
136
|
+
val tailDist: Float
|
|
82
137
|
|
|
83
138
|
if (progress <= 1f) {
|
|
84
|
-
|
|
85
|
-
|
|
139
|
+
tailDist = 0f
|
|
140
|
+
headDist = progress * totalLength
|
|
86
141
|
} else {
|
|
87
142
|
val shrinkProgress = progress - 1f
|
|
88
|
-
|
|
89
|
-
|
|
143
|
+
tailDist = shrinkProgress * totalLength
|
|
144
|
+
headDist = totalLength
|
|
90
145
|
}
|
|
91
146
|
|
|
92
|
-
if (
|
|
147
|
+
if (headDist <= tailDist) {
|
|
93
148
|
poly.setSpans(emptyList())
|
|
94
149
|
poly.points = listOf(coordinates.firstOrNull() ?: LatLng(0.0, 0.0))
|
|
95
150
|
return
|
|
96
151
|
}
|
|
97
152
|
|
|
98
|
-
val
|
|
99
|
-
val
|
|
100
|
-
val
|
|
153
|
+
val visibleLength = headDist - tailDist
|
|
154
|
+
val startIndex = indexForDistance(tailDist)
|
|
155
|
+
val endIndex = indexForDistance(headDist)
|
|
101
156
|
|
|
102
157
|
val points = mutableListOf<LatLng>()
|
|
103
158
|
val spans = mutableListOf<StyleSpan>()
|
|
104
159
|
|
|
105
|
-
|
|
106
|
-
var coord = coordinates[i]
|
|
107
|
-
|
|
108
|
-
// Interpolate tail
|
|
109
|
-
if (i == startIndex && tailPos > startIndex.toFloat() && i + 1 < coordinates.size) {
|
|
110
|
-
val t = tailPos - startIndex
|
|
111
|
-
val next = coordinates[i + 1]
|
|
112
|
-
coord = LatLng(
|
|
113
|
-
coord.latitude + (next.latitude - coord.latitude) * t,
|
|
114
|
-
coord.longitude + (next.longitude - coord.longitude) * t
|
|
115
|
-
)
|
|
116
|
-
}
|
|
160
|
+
points.add(coordinateAtDistance(tailDist))
|
|
117
161
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
val prev = coordinates[i - 1]
|
|
122
|
-
coord = LatLng(
|
|
123
|
-
prev.latitude + (coordinates[i].latitude - prev.latitude) * t,
|
|
124
|
-
prev.longitude + (coordinates[i].longitude - prev.longitude) * t
|
|
125
|
-
)
|
|
126
|
-
}
|
|
162
|
+
for (i in (startIndex + 1)..endIndex) {
|
|
163
|
+
points.add(coordinates[i])
|
|
164
|
+
}
|
|
127
165
|
|
|
128
|
-
|
|
166
|
+
val endCoord = coordinateAtDistance(headDist)
|
|
167
|
+
val lastAdded = points.lastOrNull()
|
|
168
|
+
if (lastAdded == null || endCoord.latitude != lastAdded.latitude || endCoord.longitude != lastAdded.longitude) {
|
|
169
|
+
points.add(endCoord)
|
|
170
|
+
}
|
|
129
171
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
spans.add(StyleSpan(StrokeStyle.colorBuilder(color).build()))
|
|
136
|
-
}
|
|
172
|
+
for (i in 0 until (points.size - 1)) {
|
|
173
|
+
val segMidDist = tailDist + visibleLength * (i + 0.5f) / (points.size - 1)
|
|
174
|
+
val gradientPos = (segMidDist - tailDist) / visibleLength
|
|
175
|
+
val color = colorAtGradientPosition(gradientPos)
|
|
176
|
+
spans.add(StyleSpan(StrokeStyle.colorBuilder(color).build()))
|
|
137
177
|
}
|
|
138
178
|
|
|
139
179
|
poly.points = points
|
package/ios/LuggAppleMapView.mm
CHANGED
|
@@ -442,7 +442,6 @@ using namespace luggmaps::events;
|
|
|
442
442
|
reuseIdentifier:nil];
|
|
443
443
|
annotationView.canShowCallout = YES;
|
|
444
444
|
annotationView.displayPriority = MKFeatureDisplayPriorityRequired;
|
|
445
|
-
annotationView.collisionMode = MKAnnotationViewCollisionModeNone;
|
|
446
445
|
|
|
447
446
|
UIView *iconView = markerView.iconView;
|
|
448
447
|
[iconView removeFromSuperview];
|
package/ios/LuggGoogleMapView.mm
CHANGED
|
@@ -277,7 +277,6 @@ static NSString *const kDemoMapId = @"DEMO_MAP_ID";
|
|
|
277
277
|
marker.position = markerView.coordinate;
|
|
278
278
|
marker.title = markerView.title;
|
|
279
279
|
marker.snippet = markerView.markerDescription;
|
|
280
|
-
marker.collisionBehavior = GMSCollisionBehaviorRequired;
|
|
281
280
|
|
|
282
281
|
if (markerView.hasCustomView) {
|
|
283
282
|
marker.iconView = iconView;
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
@implementation GMSPolylineAnimator {
|
|
5
5
|
CADisplayLink *_displayLink;
|
|
6
6
|
CGFloat _animationProgress;
|
|
7
|
+
NSArray<NSNumber *> *_cumulativeDistances;
|
|
8
|
+
CGFloat _totalLength;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
- (void)dealloc {
|
|
@@ -28,18 +30,35 @@
|
|
|
28
30
|
if (_displayLink) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
33
|
+
[self computeCumulativeDistances];
|
|
31
34
|
_animationProgress = 0;
|
|
32
35
|
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animationTick:)];
|
|
33
36
|
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
- (void)computeCumulativeDistances {
|
|
40
|
+
NSMutableArray<NSNumber *> *distances = [NSMutableArray array];
|
|
41
|
+
CGFloat total = 0;
|
|
42
|
+
[distances addObject:@(0)];
|
|
43
|
+
|
|
44
|
+
for (NSUInteger i = 1; i < self.coordinates.count; i++) {
|
|
45
|
+
CLLocation *prev = self.coordinates[i - 1];
|
|
46
|
+
CLLocation *curr = self.coordinates[i];
|
|
47
|
+
total += [prev distanceFromLocation:curr];
|
|
48
|
+
[distances addObject:@(total)];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_cumulativeDistances = [distances copy];
|
|
52
|
+
_totalLength = total;
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
- (void)stopAnimation {
|
|
37
56
|
[_displayLink invalidate];
|
|
38
57
|
_displayLink = nil;
|
|
39
58
|
}
|
|
40
59
|
|
|
41
60
|
- (void)animationTick:(CADisplayLink *)displayLink {
|
|
42
|
-
CGFloat speed = displayLink.duration / 1.
|
|
61
|
+
CGFloat speed = displayLink.duration / 1.0;
|
|
43
62
|
_animationProgress += speed;
|
|
44
63
|
|
|
45
64
|
if (_animationProgress >= 2.15) {
|
|
@@ -71,63 +90,86 @@
|
|
|
71
90
|
}
|
|
72
91
|
}
|
|
73
92
|
|
|
93
|
+
- (NSUInteger)indexForDistance:(CGFloat)distance {
|
|
94
|
+
for (NSUInteger i = 1; i < _cumulativeDistances.count; i++) {
|
|
95
|
+
if (_cumulativeDistances[i].doubleValue >= distance) {
|
|
96
|
+
return i - 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return _cumulativeDistances.count - 2;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
- (CLLocationCoordinate2D)coordinateAtDistance:(CGFloat)distance {
|
|
103
|
+
if (distance <= 0) {
|
|
104
|
+
return self.coordinates.firstObject.coordinate;
|
|
105
|
+
}
|
|
106
|
+
if (distance >= _totalLength) {
|
|
107
|
+
return self.coordinates.lastObject.coordinate;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
NSUInteger idx = [self indexForDistance:distance];
|
|
111
|
+
CGFloat segStart = _cumulativeDistances[idx].doubleValue;
|
|
112
|
+
CGFloat segEnd = _cumulativeDistances[idx + 1].doubleValue;
|
|
113
|
+
CGFloat segLength = segEnd - segStart;
|
|
114
|
+
|
|
115
|
+
CGFloat t = (segLength > 0) ? (distance - segStart) / segLength : 0;
|
|
116
|
+
CLLocationCoordinate2D c1 = self.coordinates[idx].coordinate;
|
|
117
|
+
CLLocationCoordinate2D c2 = self.coordinates[idx + 1].coordinate;
|
|
118
|
+
|
|
119
|
+
return CLLocationCoordinate2DMake(c1.latitude + (c2.latitude - c1.latitude) * t,
|
|
120
|
+
c1.longitude + (c2.longitude - c1.longitude) * t);
|
|
121
|
+
}
|
|
122
|
+
|
|
74
123
|
- (void)updateAnimatedPolyline {
|
|
75
|
-
if (!_polyline || self.coordinates.count < 2) {
|
|
124
|
+
if (!_polyline || self.coordinates.count < 2 || _totalLength <= 0) {
|
|
76
125
|
return;
|
|
77
126
|
}
|
|
78
127
|
|
|
79
|
-
NSUInteger segmentCount = self.coordinates.count - 1;
|
|
80
128
|
CGFloat progress = MIN(_animationProgress, 2.0);
|
|
81
|
-
CGFloat
|
|
129
|
+
CGFloat headDist, tailDist;
|
|
82
130
|
|
|
83
131
|
if (progress <= 1.0) {
|
|
84
|
-
|
|
85
|
-
|
|
132
|
+
tailDist = 0;
|
|
133
|
+
headDist = progress * _totalLength;
|
|
86
134
|
} else {
|
|
87
135
|
CGFloat shrinkProgress = progress - 1.0;
|
|
88
|
-
|
|
89
|
-
|
|
136
|
+
tailDist = shrinkProgress * _totalLength;
|
|
137
|
+
headDist = _totalLength;
|
|
90
138
|
}
|
|
91
139
|
|
|
92
|
-
if (
|
|
140
|
+
if (headDist <= tailDist) {
|
|
93
141
|
_polyline.path = [GMSMutablePath path];
|
|
94
142
|
return;
|
|
95
143
|
}
|
|
96
144
|
|
|
97
|
-
|
|
98
|
-
NSUInteger
|
|
99
|
-
|
|
145
|
+
CGFloat visibleLength = headDist - tailDist;
|
|
146
|
+
NSUInteger startIndex = [self indexForDistance:tailDist];
|
|
147
|
+
NSUInteger endIndex = [self indexForDistance:headDist];
|
|
100
148
|
|
|
101
149
|
GMSMutablePath *path = [GMSMutablePath path];
|
|
102
150
|
NSMutableArray<GMSStyleSpan *> *spans = [NSMutableArray array];
|
|
103
151
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (i == startIndex && tailPos > (CGFloat)startIndex) {
|
|
108
|
-
CGFloat t = tailPos - (CGFloat)startIndex;
|
|
109
|
-
CLLocationCoordinate2D nextCoord = self.coordinates[i + 1].coordinate;
|
|
110
|
-
coord.latitude = coord.latitude + (nextCoord.latitude - coord.latitude) * t;
|
|
111
|
-
coord.longitude = coord.longitude + (nextCoord.longitude - coord.longitude) * t;
|
|
112
|
-
}
|
|
152
|
+
CLLocationCoordinate2D startCoord = [self coordinateAtDistance:tailDist];
|
|
153
|
+
[path addCoordinate:startCoord];
|
|
113
154
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
coord.latitude = prevCoord.latitude + (coord.latitude - prevCoord.latitude) * t;
|
|
118
|
-
coord.longitude = prevCoord.longitude + (coord.longitude - prevCoord.longitude) * t;
|
|
119
|
-
}
|
|
155
|
+
for (NSUInteger i = startIndex + 1; i <= endIndex; i++) {
|
|
156
|
+
[path addCoordinate:self.coordinates[i].coordinate];
|
|
157
|
+
}
|
|
120
158
|
|
|
121
|
-
|
|
159
|
+
CLLocationCoordinate2D endCoord = [self coordinateAtDistance:headDist];
|
|
160
|
+
CLLocationCoordinate2D lastAdded =
|
|
161
|
+
(endIndex < self.coordinates.count) ? self.coordinates[endIndex].coordinate : endCoord;
|
|
162
|
+
if (endCoord.latitude != lastAdded.latitude || endCoord.longitude != lastAdded.longitude) {
|
|
163
|
+
[path addCoordinate:endCoord];
|
|
164
|
+
}
|
|
122
165
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
166
|
+
NSUInteger pathCount = path.count;
|
|
167
|
+
for (NSUInteger i = 0; i < pathCount - 1; i++) {
|
|
168
|
+
CGFloat segMidDist = tailDist + visibleLength * ((CGFloat)i + 0.5) / (CGFloat)(pathCount - 1);
|
|
169
|
+
CGFloat gradientPos = (segMidDist - tailDist) / visibleLength;
|
|
170
|
+
UIColor *color = [self colorAtGradientPosition:gradientPos];
|
|
171
|
+
GMSStrokeStyle *style = [GMSStrokeStyle solidColor:color];
|
|
172
|
+
[spans addObject:[GMSStyleSpan spanWithStyle:style]];
|
|
131
173
|
}
|
|
132
174
|
|
|
133
175
|
_polyline.path = path;
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
@implementation MKPolylineAnimator {
|
|
5
5
|
MKPolyline *_polyline;
|
|
6
6
|
CADisplayLink *_displayLink;
|
|
7
|
-
CGFloat _animationProgress;
|
|
7
|
+
CGFloat _animationProgress;
|
|
8
|
+
NSArray<NSNumber *> *_cumulativeDistances;
|
|
9
|
+
CGFloat _totalLength;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
- (id)initWithPolyline:(MKPolyline *)polyline {
|
|
@@ -38,23 +40,47 @@
|
|
|
38
40
|
if (_displayLink) {
|
|
39
41
|
return;
|
|
40
42
|
}
|
|
43
|
+
[self computeCumulativeDistances];
|
|
41
44
|
_animationProgress = 0;
|
|
42
45
|
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animationTick:)];
|
|
43
46
|
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
- (void)computeCumulativeDistances {
|
|
50
|
+
NSMutableArray<NSNumber *> *distances = [NSMutableArray array];
|
|
51
|
+
CGFloat total = 0;
|
|
52
|
+
[distances addObject:@(0)];
|
|
53
|
+
|
|
54
|
+
for (NSUInteger i = 1; i < _polyline.pointCount; i++) {
|
|
55
|
+
MKMapPoint p1 = _polyline.points[i - 1];
|
|
56
|
+
MKMapPoint p2 = _polyline.points[i];
|
|
57
|
+
total += MKMetersBetweenMapPoints(p1, p2);
|
|
58
|
+
[distances addObject:@(total)];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_cumulativeDistances = [distances copy];
|
|
62
|
+
_totalLength = total;
|
|
63
|
+
}
|
|
64
|
+
|
|
46
65
|
- (void)stopAnimation {
|
|
47
66
|
[_displayLink invalidate];
|
|
48
67
|
_displayLink = nil;
|
|
49
68
|
}
|
|
50
69
|
|
|
70
|
+
- (NSUInteger)indexForDistance:(CGFloat)distance {
|
|
71
|
+
for (NSUInteger i = 1; i < _cumulativeDistances.count; i++) {
|
|
72
|
+
if (_cumulativeDistances[i].doubleValue >= distance) {
|
|
73
|
+
return i - 1;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return _cumulativeDistances.count - 2;
|
|
77
|
+
}
|
|
78
|
+
|
|
51
79
|
- (void)animationTick:(CADisplayLink *)displayLink {
|
|
52
|
-
|
|
53
|
-
CGFloat speed = displayLink.duration / 1.75;
|
|
80
|
+
CGFloat speed = displayLink.duration / 1.0;
|
|
54
81
|
_animationProgress += speed;
|
|
55
82
|
|
|
56
|
-
|
|
57
|
-
if (_animationProgress >= 2.15) { // 2.0 + 0.15 pause (~300ms at this speed)
|
|
83
|
+
if (_animationProgress >= 2.15) {
|
|
58
84
|
_animationProgress = 0;
|
|
59
85
|
}
|
|
60
86
|
|
|
@@ -135,62 +161,64 @@
|
|
|
135
161
|
}
|
|
136
162
|
|
|
137
163
|
// Snake animation: grow from start, then shrink from start
|
|
138
|
-
if (_animated && _polyline.pointCount > 1) {
|
|
164
|
+
if (_animated && _polyline.pointCount > 1 && _totalLength > 0) {
|
|
139
165
|
CGFloat progress = MIN(_animationProgress, 2.0);
|
|
140
|
-
CGFloat
|
|
166
|
+
CGFloat headDist, tailDist;
|
|
141
167
|
|
|
142
168
|
if (progress <= 1.0) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
headPos = progress * segmentCount;
|
|
169
|
+
tailDist = 0;
|
|
170
|
+
headDist = progress * _totalLength;
|
|
146
171
|
} else {
|
|
147
|
-
// Phase 2: shrink from start
|
|
148
172
|
CGFloat shrinkProgress = progress - 1.0;
|
|
149
|
-
|
|
150
|
-
|
|
173
|
+
tailDist = shrinkProgress * _totalLength;
|
|
174
|
+
headDist = _totalLength;
|
|
151
175
|
}
|
|
152
176
|
|
|
153
|
-
if (
|
|
177
|
+
if (headDist <= tailDist) {
|
|
154
178
|
return;
|
|
155
179
|
}
|
|
156
180
|
|
|
157
|
-
|
|
158
|
-
NSUInteger
|
|
159
|
-
|
|
181
|
+
CGFloat visibleLength = headDist - tailDist;
|
|
182
|
+
NSUInteger startIndex = [self indexForDistance:tailDist];
|
|
183
|
+
NSUInteger endIndex = [self indexForDistance:headDist];
|
|
184
|
+
|
|
185
|
+
for (NSUInteger i = startIndex; i <= endIndex && i < segmentCount; i++) {
|
|
186
|
+
CGFloat segStartDist = _cumulativeDistances[i].doubleValue;
|
|
187
|
+
CGFloat segEndDist = _cumulativeDistances[i + 1].doubleValue;
|
|
188
|
+
|
|
189
|
+
if (segEndDist <= tailDist || segStartDist >= headDist) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
160
192
|
|
|
161
|
-
for (NSUInteger i = startIndex; i < endIndex && i < segmentCount; i++) {
|
|
162
193
|
CGPoint segStart = [self pointForMapPoint:_polyline.points[i]];
|
|
163
194
|
CGPoint segEnd = [self pointForMapPoint:_polyline.points[i + 1]];
|
|
164
195
|
|
|
165
196
|
CGPoint drawStart = segStart;
|
|
166
197
|
CGPoint drawEnd = segEnd;
|
|
167
|
-
CGFloat
|
|
168
|
-
CGFloat
|
|
198
|
+
CGFloat drawStartDist = segStartDist;
|
|
199
|
+
CGFloat drawEndDist = segEndDist;
|
|
200
|
+
CGFloat segLength = segEndDist - segStartDist;
|
|
169
201
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
CGFloat t = tailPos - segStartPos;
|
|
202
|
+
if (segStartDist < tailDist && segLength > 0) {
|
|
203
|
+
CGFloat t = (tailDist - segStartDist) / segLength;
|
|
173
204
|
drawStart.x = segStart.x + (segEnd.x - segStart.x) * t;
|
|
174
205
|
drawStart.y = segStart.y + (segEnd.y - segStart.y) * t;
|
|
175
|
-
|
|
206
|
+
drawStartDist = tailDist;
|
|
176
207
|
}
|
|
177
208
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
CGFloat t = headPos - (CGFloat)i;
|
|
209
|
+
if (segEndDist > headDist && segLength > 0) {
|
|
210
|
+
CGFloat t = (headDist - segStartDist) / segLength;
|
|
181
211
|
drawEnd.x = segStart.x + (segEnd.x - segStart.x) * t;
|
|
182
212
|
drawEnd.y = segStart.y + (segEnd.y - segStart.y) * t;
|
|
183
|
-
|
|
213
|
+
drawEndDist = headDist;
|
|
184
214
|
}
|
|
185
215
|
|
|
186
|
-
|
|
187
|
-
CGFloat
|
|
188
|
-
CGFloat gradientEnd = (segEndPos - tailPos) / visibleLength;
|
|
216
|
+
CGFloat gradientStart = (drawStartDist - tailDist) / visibleLength;
|
|
217
|
+
CGFloat gradientEnd = (drawEndDist - tailDist) / visibleLength;
|
|
189
218
|
|
|
190
219
|
UIColor *startColor = [self colorAtGradientPosition:gradientStart];
|
|
191
220
|
UIColor *endColor = [self colorAtGradientPosition:gradientEnd];
|
|
192
221
|
|
|
193
|
-
// Draw gradient line segment
|
|
194
222
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
195
223
|
NSArray *colors = @[(__bridge id)startColor.CGColor, (__bridge id)endColor.CGColor];
|
|
196
224
|
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, NULL);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lugg/maps",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.4",
|
|
4
4
|
"description": "Universal maps for React Native.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"types": "./lib/typescript/src/index.d.ts",
|
|
11
11
|
"default": "./lib/module/index.js"
|
|
12
12
|
},
|
|
13
|
-
"./package.json": "./package.json"
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
"./app.plugin.js": "./app.plugin.js"
|
|
14
15
|
},
|
|
15
16
|
"files": [
|
|
16
17
|
"src",
|