@rnmapbox/maps 10.1.15 → 10.1.16

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 (100) hide show
  1. package/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +13 -2
  2. package/android/src/main/java/com/rnmapbox/rnmbx/components/AbstractEventEmitter.kt +13 -7
  3. package/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXShapeSource.kt +23 -17
  4. package/android/src/main/java/com/rnmapbox/rnmbx/components/styles/sources/RNMBXShapeSourceManager.kt +1 -2
  5. package/android/src/main/java/com/rnmapbox/rnmbx/shapeAnimators/AnimatableElement.kt +38 -0
  6. package/android/src/main/java/com/rnmapbox/rnmbx/shapeAnimators/RNMBXChangeLineOffsetsShapeAnimatorModule.kt +217 -0
  7. package/android/src/main/java/com/rnmapbox/rnmbx/shapeAnimators/RNMBXMovePointShapeAnimatorModule.kt +108 -0
  8. package/android/src/main/java/com/rnmapbox/rnmbx/shapeAnimators/ShapeAnimatorCommon.kt +142 -0
  9. package/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXChangeLineOffsetsShapeAnimatorModuleSpec.java +52 -0
  10. package/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXMovePointShapeAnimatorModuleSpec.java +2 -2
  11. package/ios/RNMBX/RNMBXCircleLayer.swift +48 -1
  12. package/ios/RNMBX/RNMBXFillExtrusionLayer.swift +47 -1
  13. package/ios/RNMBX/RNMBXFillLayer.swift +47 -1
  14. package/ios/RNMBX/RNMBXLineLayer.swift +44 -1
  15. package/ios/RNMBX/RNMBXLogging.swift +78 -39
  16. package/ios/RNMBX/RNMBXModelLayer.swift +44 -1
  17. package/ios/RNMBX/RNMBXRasterLayer.swift +48 -2
  18. package/ios/RNMBX/RNMBXShapeSource.swift +30 -17
  19. package/ios/RNMBX/RNMBXSkyLayer.swift +22 -1
  20. package/ios/RNMBX/RNMBXSymbolLayer.swift +47 -1
  21. package/ios/RNMBX/ShapeAnimators/AnimatableElement.swift +48 -0
  22. package/ios/RNMBX/ShapeAnimators/RNMBXChangeLineOffsetsShapeAnimatorModule.m +64 -0
  23. package/ios/RNMBX/ShapeAnimators/RNMBXChangeLineOffsetsShapeAnimatorModule.swift +214 -0
  24. package/ios/RNMBX/ShapeAnimators/RNMBXMovePointShapeAnimatorModule.m +5 -10
  25. package/ios/RNMBX/ShapeAnimators/RNMBXMovePointShapeAnimatorModule.swift +92 -24
  26. package/ios/RNMBX/ShapeAnimators/ShapeAnimatorCommon.swift +71 -33
  27. package/ios/RNMBX/ShapeAnimators/ShapeAnimatorManager.swift +3 -1
  28. package/ios/RNMBX/codeparts/LayerPropsCommon.codepart-swift.ejs +51 -0
  29. package/lib/commonjs/Mapbox.js +4 -2
  30. package/lib/commonjs/Mapbox.js.map +1 -1
  31. package/lib/commonjs/components/ShapeSource.js.map +1 -1
  32. package/lib/commonjs/shapeAnimators/ChangeLineOffsetsShapeAnimator.js +27 -0
  33. package/lib/commonjs/shapeAnimators/ChangeLineOffsetsShapeAnimator.js.map +1 -0
  34. package/lib/commonjs/{shape_animators → shapeAnimators}/MovePointShapeAnimator.js +4 -4
  35. package/lib/commonjs/shapeAnimators/MovePointShapeAnimator.js.map +1 -0
  36. package/lib/commonjs/shapeAnimators/ShapeAnimatorManager.js.map +1 -0
  37. package/lib/commonjs/shapeAnimators/index.js +2 -0
  38. package/lib/commonjs/shapeAnimators/index.js.map +1 -0
  39. package/lib/commonjs/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.js +10 -0
  40. package/lib/commonjs/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.js.map +1 -0
  41. package/lib/commonjs/specs/NativeRNMBXMovePointShapeAnimatorModule.js.map +1 -1
  42. package/lib/commonjs/utils/Logger.js +13 -7
  43. package/lib/commonjs/utils/Logger.js.map +1 -1
  44. package/lib/module/Mapbox.js +4 -2
  45. package/lib/module/Mapbox.js.map +1 -1
  46. package/lib/module/components/ShapeSource.js.map +1 -1
  47. package/lib/module/shapeAnimators/ChangeLineOffsetsShapeAnimator.js +19 -0
  48. package/lib/module/shapeAnimators/ChangeLineOffsetsShapeAnimator.js.map +1 -0
  49. package/lib/module/shapeAnimators/MovePointShapeAnimator.js +13 -0
  50. package/lib/module/shapeAnimators/MovePointShapeAnimator.js.map +1 -0
  51. package/lib/module/shapeAnimators/ShapeAnimatorManager.js.map +1 -0
  52. package/lib/module/shapeAnimators/index.js +2 -0
  53. package/lib/module/shapeAnimators/index.js.map +1 -0
  54. package/lib/module/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.js +6 -0
  55. package/lib/module/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.js.map +1 -0
  56. package/lib/module/specs/NativeRNMBXMovePointShapeAnimatorModule.js.map +1 -1
  57. package/lib/module/utils/Logger.js +13 -7
  58. package/lib/module/utils/Logger.js.map +1 -1
  59. package/lib/typescript/src/Mapbox.d.ts +3 -1
  60. package/lib/typescript/src/Mapbox.d.ts.map +1 -1
  61. package/lib/typescript/src/components/ShapeSource.d.ts +2 -1
  62. package/lib/typescript/src/components/ShapeSource.d.ts.map +1 -1
  63. package/lib/typescript/src/shapeAnimators/ChangeLineOffsetsShapeAnimator.d.ts +24 -0
  64. package/lib/typescript/src/shapeAnimators/ChangeLineOffsetsShapeAnimator.d.ts.map +1 -0
  65. package/lib/typescript/src/shapeAnimators/MovePointShapeAnimator.d.ts +11 -0
  66. package/lib/typescript/src/shapeAnimators/MovePointShapeAnimator.d.ts.map +1 -0
  67. package/lib/typescript/src/shapeAnimators/ShapeAnimatorManager.d.ts.map +1 -0
  68. package/lib/typescript/src/shapeAnimators/index.d.ts +4 -0
  69. package/lib/typescript/src/shapeAnimators/index.d.ts.map +1 -0
  70. package/lib/typescript/src/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.d.ts +13 -0
  71. package/lib/typescript/src/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.d.ts.map +1 -0
  72. package/lib/typescript/src/specs/NativeRNMBXMovePointShapeAnimatorModule.d.ts +2 -2
  73. package/lib/typescript/src/specs/NativeRNMBXMovePointShapeAnimatorModule.d.ts.map +1 -1
  74. package/lib/typescript/src/utils/Logger.d.ts +2 -2
  75. package/lib/typescript/src/utils/Logger.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/setup-jest.js +5 -0
  78. package/src/Mapbox.ts +3 -1
  79. package/src/components/ShapeSource.tsx +3 -1
  80. package/src/shapeAnimators/ChangeLineOffsetsShapeAnimator.ts +57 -0
  81. package/src/shapeAnimators/MovePointShapeAnimator.ts +27 -0
  82. package/src/shapeAnimators/index.ts +3 -0
  83. package/src/specs/NativeRNMBXChangeLineOffsetsShapeAnimatorModule.ts +37 -0
  84. package/src/specs/NativeRNMBXMovePointShapeAnimatorModule.ts +6 -2
  85. package/src/utils/Logger.ts +17 -9
  86. package/android/src/main/java/com/rnmapbox/rnmbx/shape_animators/RNMBXMovePointShapeAnimatorModule.kt +0 -55
  87. package/android/src/main/java/com/rnmapbox/rnmbx/shape_animators/ShapeAnimatorCommon.kt +0 -110
  88. package/lib/commonjs/shape_animators/MovePointShapeAnimator.js.map +0 -1
  89. package/lib/commonjs/shape_animators/ShapeAnimatorManager.js.map +0 -1
  90. package/lib/module/shape_animators/MovePointShapeAnimator.js +0 -13
  91. package/lib/module/shape_animators/MovePointShapeAnimator.js.map +0 -1
  92. package/lib/module/shape_animators/ShapeAnimatorManager.js.map +0 -1
  93. package/lib/typescript/src/shape_animators/MovePointShapeAnimator.d.ts +0 -7
  94. package/lib/typescript/src/shape_animators/MovePointShapeAnimator.d.ts.map +0 -1
  95. package/lib/typescript/src/shape_animators/ShapeAnimatorManager.d.ts.map +0 -1
  96. package/src/shape_animators/MovePointShapeAnimator.ts +0 -18
  97. /package/lib/commonjs/{shape_animators → shapeAnimators}/ShapeAnimatorManager.js +0 -0
  98. /package/lib/module/{shape_animators → shapeAnimators}/ShapeAnimatorManager.js +0 -0
  99. /package/lib/typescript/src/{shape_animators → shapeAnimators}/ShapeAnimatorManager.d.ts +0 -0
  100. /package/src/{shape_animators → shapeAnimators}/ShapeAnimatorManager.tsx +0 -0
@@ -52,8 +52,9 @@ import com.rnmapbox.rnmbx.modules.RNMBXOfflineModule
52
52
  import com.rnmapbox.rnmbx.modules.RNMBXOfflineModuleLegacy
53
53
  import com.rnmapbox.rnmbx.modules.RNMBXSnapshotModule
54
54
  import com.rnmapbox.rnmbx.modules.RNMBXTileStoreModule
55
- import com.rnmapbox.rnmbx.shape_animators.RNMBXMovePointShapeAnimatorModule
56
- import com.rnmapbox.rnmbx.shape_animators.ShapeAnimatorManager
55
+ import com.rnmapbox.rnmbx.shapeAnimators.RNMBXChangeLineOffsetsShapeAnimatorModule
56
+ import com.rnmapbox.rnmbx.shapeAnimators.RNMBXMovePointShapeAnimatorModule
57
+ import com.rnmapbox.rnmbx.shapeAnimators.ShapeAnimatorManager
57
58
  import com.rnmapbox.rnmbx.utils.ViewTagResolver
58
59
 
59
60
  class RNMBXPackage : TurboReactPackage() {
@@ -103,6 +104,7 @@ class RNMBXPackage : TurboReactPackage() {
103
104
  RNMBXImageModule.NAME -> return RNMBXImageModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
104
105
  RNMBXPointAnnotationModule.NAME -> return RNMBXPointAnnotationModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
105
106
  RNMBXMovePointShapeAnimatorModule.NAME -> return RNMBXMovePointShapeAnimatorModule(reactApplicationContext, getShapeAnimators(s))
107
+ RNMBXChangeLineOffsetsShapeAnimatorModule.NAME -> return RNMBXChangeLineOffsetsShapeAnimatorModule(reactApplicationContext, getShapeAnimators(s))
106
108
  }
107
109
  return null
108
110
  }
@@ -292,6 +294,15 @@ class RNMBXPackage : TurboReactPackage() {
292
294
  false,
293
295
  isTurboModule
294
296
  )
297
+ moduleInfos[RNMBXChangeLineOffsetsShapeAnimatorModule.NAME] = ReactModuleInfo(
298
+ RNMBXChangeLineOffsetsShapeAnimatorModule.NAME,
299
+ RNMBXChangeLineOffsetsShapeAnimatorModule.NAME,
300
+ false,
301
+ false,
302
+ false,
303
+ false,
304
+ isTurboModule
305
+ )
295
306
  moduleInfos
296
307
  }
297
308
  }
@@ -10,6 +10,7 @@ import com.facebook.react.uimanager.ViewGroupManager
10
10
  import com.facebook.react.uimanager.events.Event
11
11
  import com.facebook.react.uimanager.events.EventDispatcher
12
12
  import com.rnmapbox.rnmbx.events.IEvent
13
+ import com.rnmapbox.rnmbx.utils.Logger
13
14
 
14
15
  /**
15
16
  * Created by nickitaliano on 8/23/17.
@@ -40,14 +41,19 @@ abstract class AbstractEventEmitter<T : ViewGroup?>(reactApplicationContext: Rea
40
41
  return
41
42
  }
42
43
  mRateLimitedEvents[eventCacheKey] = System.currentTimeMillis()
43
- mEventDispatcher!!.dispatchEvent(
44
- AbstractEvent(
45
- event.iD,
46
- event.key,
47
- event.canCoalesce(),
48
- event.toJSON()
44
+
45
+ try {
46
+ mEventDispatcher!!.dispatchEvent(
47
+ AbstractEvent(
48
+ event.iD,
49
+ event.key,
50
+ event.canCoalesce(),
51
+ event.toJSON()
52
+ )
49
53
  )
50
- )
54
+ } catch (e: Exception) {
55
+ Logger.e("Error dispatching event:", e.toString())
56
+ }
51
57
  }
52
58
 
53
59
  override fun addEventEmitters(context: ThemedReactContext, view: T) {
@@ -1,32 +1,28 @@
1
1
  package com.rnmapbox.rnmbx.components.styles.sources
2
2
 
3
3
  import android.content.Context
4
- import com.mapbox.maps.extension.style.sources.generated.GeoJsonSource
5
- import com.rnmapbox.rnmbx.utils.ImageEntry
6
- import android.graphics.drawable.BitmapDrawable
7
4
  import com.facebook.react.bridge.Promise
8
- import com.facebook.react.bridge.ReadableMap
9
- import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView
10
- import com.rnmapbox.rnmbx.events.FeatureClickEvent
11
5
  import com.facebook.react.bridge.WritableMap
12
6
  import com.facebook.react.bridge.WritableNativeMap
13
7
  import com.mapbox.bindgen.Value
14
8
  import com.mapbox.geojson.Feature
15
- import com.rnmapbox.rnmbx.events.AndroidCallbackEvent
16
9
  import com.mapbox.geojson.FeatureCollection
17
10
  import com.mapbox.geojson.GeoJson
18
11
  import com.mapbox.geojson.Geometry
19
12
  import com.mapbox.maps.*
20
13
  import com.mapbox.maps.extension.style.expressions.generated.Expression
21
- import com.rnmapbox.rnmbx.shape_animators.ShapeAnimationConsumer
22
- import com.rnmapbox.rnmbx.shape_animators.ShapeAnimator
23
- import com.rnmapbox.rnmbx.shape_animators.ShapeAnimatorManager
14
+ import com.mapbox.maps.extension.style.sources.generated.GeoJsonSource
15
+ import com.rnmapbox.rnmbx.components.RemovalReason
16
+ import com.rnmapbox.rnmbx.components.mapview.RNMBXMapView
17
+ import com.rnmapbox.rnmbx.events.AndroidCallbackEvent
18
+ import com.rnmapbox.rnmbx.events.FeatureClickEvent
19
+ import com.rnmapbox.rnmbx.shapeAnimators.ShapeAnimationConsumer
20
+ import com.rnmapbox.rnmbx.shapeAnimators.ShapeAnimator
24
21
  import com.rnmapbox.rnmbx.utils.Logger
22
+ import com.rnmapbox.rnmbx.v11compat.feature.*
25
23
  import java.net.URL
26
- import java.util.ArrayList
27
- import java.util.HashMap
28
24
 
29
- import com.rnmapbox.rnmbx.v11compat.feature.*
25
+ private const val LOG_TAG = "RNMBXShapeSource"
30
26
 
31
27
  class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceManager) :
32
28
  RNMBXSource<GeoJsonSource>(context), ShapeAnimationConsumer {
@@ -47,6 +43,7 @@ class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceM
47
43
  }
48
44
 
49
45
  override fun addToMap(mapView: RNMBXMapView) {
46
+
50
47
  // Wait for style before adding the source to the map
51
48
  mapView.getMapboxMap().getStyle {
52
49
  val map = mapView.getMapboxMap()
@@ -54,6 +51,14 @@ class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceM
54
51
  }
55
52
  }
56
53
 
54
+ override fun removeFromMap(mapView: RNMBXMapView, reason: RemovalReason): Boolean {
55
+
56
+ if (reason == RemovalReason.VIEW_REMOVAL) {
57
+ mShapeAnimator?.unsubscribe(this)
58
+ }
59
+ return super.removeFromMap(mapView, reason)
60
+ }
61
+
57
62
  override fun setId(id: Int) {
58
63
  super.setId(id)
59
64
  mManager.tagAssigned(id)
@@ -85,7 +90,8 @@ class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceM
85
90
  mShapeAnimator = shapeAnimator
86
91
  shapeAnimator.subscribe(this)
87
92
 
88
- shapeUpdated(shapeAnimator.getShape())
93
+ val shape = shapeAnimator.getShape()
94
+ shapeUpdated(shape)
89
95
  }
90
96
  } else {
91
97
  mShape = geoJSONStr
@@ -108,8 +114,8 @@ class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceM
108
114
  else -> {
109
115
  Logger.e(
110
116
  LOG_TAG,
111
- "Cannot convert shape to GeoJSONSourceData, neitthe Geometry, nor Feature or FeatureCollection: $geoJson"
112
- );
117
+ "Cannot convert shape to Geometry, Feature, or FeatureCollection: $geoJson"
118
+ )
113
119
  return null
114
120
  }
115
121
  }
@@ -214,7 +220,7 @@ class RNMBXShapeSource(context: Context, private val mManager: RNMBXShapeSourceM
214
220
  )
215
221
  ) { features ->
216
222
  if (features.isError) {
217
- Logger.e("RNMBXShapeSource", String.format("Error: %s", features.error))
223
+ Logger.e(LOG_TAG, String.format("Error: %s", features.error))
218
224
  } else {
219
225
  val payload: WritableMap = WritableNativeMap()
220
226
  val result: MutableList<Feature> = ArrayList(
@@ -7,13 +7,12 @@ import com.rnmapbox.rnmbx.components.AbstractEventEmitter
7
7
  import com.facebook.react.uimanager.ThemedReactContext
8
8
  import com.facebook.react.uimanager.annotations.ReactProp
9
9
  import com.facebook.react.bridge.ReadableType
10
- import com.facebook.react.common.MapBuilder
11
10
  import com.facebook.react.viewmanagers.RNMBXShapeSourceManagerInterface
12
11
  import com.mapbox.bindgen.Value
13
12
  import com.mapbox.maps.extension.style.expressions.generated.Expression
14
13
  import com.rnmapbox.rnmbx.events.constants.EventKeys
15
14
  import com.rnmapbox.rnmbx.events.constants.eventMapOf
16
- import com.rnmapbox.rnmbx.shape_animators.ShapeAnimatorManager
15
+ import com.rnmapbox.rnmbx.shapeAnimators.ShapeAnimatorManager
17
16
  import com.rnmapbox.rnmbx.utils.ExpressionParser
18
17
  import com.rnmapbox.rnmbx.utils.Logger
19
18
  import com.rnmapbox.rnmbx.utils.ViewTagResolver
@@ -0,0 +1,38 @@
1
+ package com.rnmapbox.rnmbx.shapeAnimators
2
+
3
+ internal class AnimatableElement<T>(
4
+ var source: T,
5
+ var progress: T,
6
+ var target: T,
7
+ var startedAtSec: Double,
8
+ var progressDurationSec: Double,
9
+ var totalDurationSec: Double,
10
+ /** A function returning the difference in meters between the two values. */
11
+ var getDistanceRemaining: (a: T, b: T) -> Double
12
+ ) {
13
+ fun distanceRemaining(): Double {
14
+ return getDistanceRemaining(source, target)
15
+ }
16
+
17
+ fun durationRatio(): Double {
18
+ return if (totalDurationSec > 0.0) {
19
+ progressDurationSec / totalDurationSec
20
+ } else {
21
+ 1.0
22
+ }
23
+ }
24
+
25
+ fun setProgress(value: T, animatorAgeSec: Double) {
26
+ progress = value
27
+ progressDurationSec = (animatorAgeSec - startedAtSec)
28
+ }
29
+
30
+ fun reset(_source: T, _progress: T, _target: T, durationSec: Double, animatorAgeSec: Double) {
31
+ this.source = _source
32
+ this.progress = _progress
33
+ this.target = _target
34
+ this.startedAtSec = animatorAgeSec
35
+ this.progressDurationSec = 0.0
36
+ this.totalDurationSec = durationSec
37
+ }
38
+ }
@@ -0,0 +1,217 @@
1
+ package com.rnmapbox.rnmbx.shapeAnimators
2
+
3
+ import com.facebook.react.bridge.Promise
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReadableArray
6
+ import com.facebook.react.module.annotations.ReactModule
7
+ import com.mapbox.geojson.GeoJson
8
+ import com.mapbox.geojson.LineString
9
+ import com.mapbox.geojson.Point
10
+ import com.mapbox.turf.TurfConstants.UNIT_METERS
11
+ import com.mapbox.turf.TurfMeasurement
12
+ import com.mapbox.turf.TurfMisc
13
+ import com.rnmapbox.rnmbx.NativeRNMBXChangeLineOffsetsShapeAnimatorModuleSpec
14
+
15
+ class ChangeLineOffsetsShapeAnimator(tag: Tag, _lineString: LineString, startOffset: Double, endOffset: Double): ShapeAnimatorCommon(tag) {
16
+ private var lineString = _lineString
17
+ private var startOfLine = AnimatableElement<Double>(
18
+ startOffset,
19
+ startOffset,
20
+ startOffset,
21
+ 0.0,
22
+ 0.0,
23
+ 0.0,
24
+ { a, b -> b - a }
25
+ )
26
+ private var endOfLine = AnimatableElement<Double>(
27
+ endOffset,
28
+ endOffset,
29
+ endOffset,
30
+ 0.0,
31
+ 0.0,
32
+ 0.0,
33
+ { a, b -> b - a }
34
+ )
35
+
36
+ override fun getAnimatedShape(animatorAgeSec: Double): GeoJson {
37
+ if (startOfLine.durationRatio() < 1) {
38
+ startOfLine.setProgress(
39
+ startOfLine.source + (startOfLine.distanceRemaining() * startOfLine.durationRatio()),
40
+ animatorAgeSec
41
+ )
42
+ }
43
+
44
+ if (endOfLine.durationRatio() < 1) {
45
+ endOfLine.setProgress(
46
+ endOfLine.source + (endOfLine.distanceRemaining() * endOfLine.durationRatio()),
47
+ animatorAgeSec
48
+ )
49
+ }
50
+
51
+ if (startOfLine.durationRatio() >= 1 && endOfLine.durationRatio() >= 1) {
52
+ stop()
53
+ }
54
+
55
+ if (lineString.coordinates().count() < 2) {
56
+ return emptyGeoJsonObj
57
+ }
58
+
59
+ val totalDistance = TurfMeasurement.length(lineString, UNIT_METERS)
60
+ if (totalDistance == 0.0) {
61
+ return emptyGeoJsonObj
62
+ }
63
+
64
+ if (startOfLine.progress + endOfLine.progress >= totalDistance) {
65
+ return emptyGeoJsonObj
66
+ }
67
+
68
+ val trimmed = TurfMisc.lineSliceAlong(
69
+ lineString,
70
+ startOfLine.progress,
71
+ totalDistance - endOfLine.progress,
72
+ UNIT_METERS
73
+ )
74
+ return trimmed
75
+ }
76
+
77
+ fun setLineString(lineString: LineString, startOffset: Double?, endOffset: Double?) {
78
+ this.lineString = lineString
79
+ if (startOffset != null) {
80
+ startOfLine.reset(
81
+ startOffset,
82
+ startOffset,
83
+ startOffset,
84
+ 0.0,
85
+ getAnimatorAgeSec()
86
+ )
87
+ }
88
+ if (endOffset != null) {
89
+ endOfLine.reset(
90
+ endOffset,
91
+ endOffset,
92
+ endOffset,
93
+ 0.0,
94
+ getAnimatorAgeSec()
95
+ )
96
+ }
97
+ refresh()
98
+ }
99
+
100
+ fun setStartOffset(offset: Double, durationSec: Double) {
101
+ if (durationSec == 0.0) {
102
+ startOfLine.reset(
103
+ offset,
104
+ offset,
105
+ offset,
106
+ durationSec,
107
+ getAnimatorAgeSec()
108
+ )
109
+ refresh()
110
+ } else {
111
+ start()
112
+ startOfLine.reset(
113
+ startOfLine.progress,
114
+ startOfLine.progress,
115
+ offset,
116
+ durationSec,
117
+ getAnimatorAgeSec()
118
+ )
119
+ }
120
+ }
121
+
122
+ fun setEndOffset(offset: Double, durationSec: Double) {
123
+ if (durationSec == 0.0) {
124
+ endOfLine.reset(
125
+ offset,
126
+ offset,
127
+ offset,
128
+ durationSec,
129
+ getAnimatorAgeSec()
130
+ )
131
+ refresh()
132
+ } else {
133
+ start()
134
+ endOfLine.reset(
135
+ endOfLine.progress,
136
+ endOfLine.progress,
137
+ offset,
138
+ durationSec,
139
+ getAnimatorAgeSec()
140
+ )
141
+ }
142
+ }
143
+ }
144
+
145
+ @ReactModule(name = RNMBXChangeLineOffsetsShapeAnimatorModule.NAME)
146
+ class RNMBXChangeLineOffsetsShapeAnimatorModule(
147
+ reactContext: ReactApplicationContext?,
148
+ val shapeAnimatorManager: ShapeAnimatorManager
149
+ ): NativeRNMBXChangeLineOffsetsShapeAnimatorModuleSpec(reactContext) {
150
+ companion object {
151
+ const val LOG_TAG = "RNMBXChangeLineOffsetsShapeAnimatorModule"
152
+ const val NAME = "RNMBXChangeLineOffsetsShapeAnimatorModule"
153
+ }
154
+
155
+ override fun create(
156
+ tag: Double,
157
+ coordinates: ReadableArray,
158
+ startOffset: Double,
159
+ endOffset: Double,
160
+ promise: Promise?
161
+ ) {
162
+ val lineString = buildLineString(coordinates)
163
+
164
+ shapeAnimatorManager.add(
165
+ ChangeLineOffsetsShapeAnimator(
166
+ tag.toLong(),
167
+ lineString,
168
+ startOffset,
169
+ endOffset
170
+ )
171
+ )
172
+ promise?.resolve(tag.toInt())
173
+ }
174
+
175
+ private fun getAnimator(tag: Double): ChangeLineOffsetsShapeAnimator {
176
+ return shapeAnimatorManager.get(tag.toLong()) as ChangeLineOffsetsShapeAnimator
177
+ }
178
+
179
+ override fun setLineString(tag: Double, coordinates: ReadableArray?, startOffset: Double, endOffset: Double, promise: Promise?) {
180
+ val animator = getAnimator(tag)
181
+
182
+ if (coordinates == null) {
183
+ return
184
+ }
185
+
186
+ val _startOffset = if (startOffset != -1.0) startOffset else null
187
+ val _endOffset = if (endOffset != -1.0) endOffset else null
188
+
189
+ val lineString = buildLineString(coordinates)
190
+ animator.setLineString(lineString, _startOffset, _endOffset)
191
+ promise?.resolve(true)
192
+ }
193
+
194
+ override fun setStartOffset(tag: Double, offset: Double, duration: Double, promise: Promise?) {
195
+ val animator = getAnimator(tag)
196
+ animator.setStartOffset(offset, duration / 1000)
197
+ promise?.resolve(true)
198
+ }
199
+
200
+ override fun setEndOffset(tag: Double, offset: Double, duration: Double, promise: Promise?) {
201
+ val animator = getAnimator(tag)
202
+ animator.setEndOffset(offset, duration / 1000)
203
+ promise?.resolve(true)
204
+ }
205
+ }
206
+
207
+ private fun buildLineString(_coordinates: ReadableArray): LineString {
208
+ var coordinates: List<Point> = listOf()
209
+
210
+ for (i in 0 until _coordinates.size()) {
211
+ val arr = _coordinates.getArray(i)
212
+ val coord = Point.fromLngLat(arr.getDouble(0), arr.getDouble(1))
213
+ coordinates = coordinates.plus(coord)
214
+ }
215
+
216
+ return LineString.fromLngLats(coordinates)
217
+ }
@@ -0,0 +1,108 @@
1
+ package com.rnmapbox.rnmbx.shapeAnimators
2
+
3
+ import com.facebook.react.bridge.Promise
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactMethod
6
+ import com.facebook.react.bridge.ReadableArray
7
+ import com.facebook.react.module.annotations.ReactModule
8
+ import com.mapbox.geojson.GeoJson
9
+ import com.mapbox.geojson.LineString
10
+ import com.mapbox.geojson.Point
11
+ import com.mapbox.turf.TurfConstants.UNIT_METERS
12
+ import com.mapbox.turf.TurfMeasurement
13
+ import com.rnmapbox.rnmbx.NativeRNMBXMovePointShapeAnimatorModuleSpec
14
+
15
+ class MovePointShapeAnimator(tag: Tag, coordinate: Point) : ShapeAnimatorCommon(tag) {
16
+ private var point = AnimatableElement<Point>(
17
+ coordinate,
18
+ coordinate,
19
+ coordinate,
20
+ 0.0,
21
+ 0.0,
22
+ 0.0,
23
+ { a, b -> TurfMeasurement.distance(a, b) }
24
+ )
25
+
26
+ override fun getAnimatedShape(animatorAgeSec: Double): GeoJson {
27
+ val line = LineString.fromLngLats(listOf(point.source, point.target))
28
+ val lineLength = TurfMeasurement.length(line, UNIT_METERS)
29
+ if (lineLength == 0.0) {
30
+ stop()
31
+ }
32
+
33
+ val ratio = point.durationRatio()
34
+ if (ratio >= 0 && ratio < 1) {
35
+ point.setProgress(
36
+ TurfMeasurement.along(line, lineLength * ratio, UNIT_METERS),
37
+ animatorAgeSec
38
+ )
39
+ } else if (ratio >= 1) {
40
+ stop()
41
+ }
42
+
43
+ return point.progress
44
+ }
45
+
46
+ fun moveTo(coordinate: Point, durationSec: Double) {
47
+ if (durationSec == 0.0) {
48
+ point.reset(
49
+ coordinate,
50
+ coordinate,
51
+ coordinate,
52
+ durationSec,
53
+ getAnimatorAgeSec()
54
+ )
55
+ refresh()
56
+ } else {
57
+ start()
58
+ point.reset(
59
+ point.progress,
60
+ point.progress,
61
+ coordinate,
62
+ durationSec,
63
+ getAnimatorAgeSec()
64
+ )
65
+ }
66
+ }
67
+ }
68
+
69
+ @ReactModule(name = RNMBXMovePointShapeAnimatorModule.NAME)
70
+ class RNMBXMovePointShapeAnimatorModule(
71
+ reactContext: ReactApplicationContext?,
72
+ val shapeAnimatorManager: ShapeAnimatorManager
73
+ ): NativeRNMBXMovePointShapeAnimatorModuleSpec(reactContext) {
74
+ companion object {
75
+ const val LOG_TAG = "RNMBXMovePointShapeAnimatorModule"
76
+ const val NAME = "RNMBXMovePointShapeAnimatorModule"
77
+ }
78
+
79
+ @ReactMethod
80
+ override fun create(tag: Double, startCoordinate: ReadableArray, promise: Promise) {
81
+ shapeAnimatorManager.add(
82
+ MovePointShapeAnimator(
83
+ tag.toLong(),
84
+ Point.fromLngLat(
85
+ startCoordinate.getDouble(0),
86
+ startCoordinate.getDouble(1)
87
+ )
88
+ )
89
+ )
90
+ promise.resolve(tag.toInt())
91
+ }
92
+
93
+ @ReactMethod
94
+ override fun moveTo(
95
+ tag: Double,
96
+ coordinate: ReadableArray?,
97
+ duration: Double,
98
+ promise: Promise?
99
+ ) {
100
+ val animator = shapeAnimatorManager.get(tag.toLong()) as MovePointShapeAnimator
101
+
102
+ val targetCoord = Point.fromLngLat(
103
+ coordinate!!.getDouble(0),
104
+ coordinate.getDouble(1)
105
+ )
106
+ animator.moveTo(targetCoord, duration / 1000)
107
+ }
108
+ }
@@ -0,0 +1,142 @@
1
+ package com.rnmapbox.rnmbx.shapeAnimators
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
5
+ import com.mapbox.geojson.FeatureCollection
6
+ import com.mapbox.geojson.GeoJson
7
+ import com.rnmapbox.rnmbx.utils.Logger
8
+ import org.json.JSONObject
9
+ import java.util.Date
10
+ import java.util.Timer
11
+ import java.util.TimerTask
12
+
13
+ typealias Tag = Long
14
+
15
+ interface ShapeAnimationConsumer {
16
+ fun shapeUpdated(geoJson: GeoJson)
17
+ }
18
+
19
+ abstract class ShapeAnimator(val tag: Tag) {
20
+ abstract fun getShape(): GeoJson
21
+ abstract fun getAnimatedShape(animatorAgeSec: Double): GeoJson
22
+ abstract fun subscribe(consumer: ShapeAnimationConsumer)
23
+ abstract fun unsubscribe(consumer: ShapeAnimationConsumer)
24
+ abstract fun refresh()
25
+ abstract fun start()
26
+ abstract fun stop()
27
+ }
28
+
29
+ private const val LOG_TAG = "RNMBXShapeAnimator"
30
+
31
+ abstract class ShapeAnimatorCommon(tag: Tag): ShapeAnimator(tag) {
32
+ val emptyGeoJsonObj: FeatureCollection = FeatureCollection.fromFeatures(listOf())
33
+
34
+ private var timer: Timer? = null
35
+ private var startedAt = Date()
36
+
37
+ private val fps = 30.0
38
+ private val period = 1.0 / fps
39
+
40
+ /** The number of seconds the animator has been running continuously. */
41
+ fun getAnimatorAgeSec(): Double {
42
+ val now = Date()
43
+ return (now.time - startedAt.time).toDouble() / 1000
44
+ }
45
+
46
+ // region subscribers
47
+ private var subscribers = mutableListOf<ShapeAnimationConsumer>()
48
+
49
+ override fun subscribe(consumer: ShapeAnimationConsumer) {
50
+ if (subscribers.contains(consumer)) {
51
+ return
52
+ }
53
+
54
+ subscribers.add(consumer)
55
+ }
56
+
57
+ override fun unsubscribe(consumer: ShapeAnimationConsumer) {
58
+ subscribers.remove(consumer)
59
+ if (subscribers.isEmpty()) {
60
+ stop()
61
+ }
62
+ }
63
+ // endregion
64
+
65
+ override fun refresh() {
66
+ val timestamp = getAnimatorAgeSec()
67
+ // Log.d(
68
+ // LOG_TAG,
69
+ // "Refreshing animator for tag $tag (timestamp: $timestamp, subscribers: ${subscribers.count()})"
70
+ // )
71
+
72
+ val shape = getAnimatedShape(timestamp)
73
+ runOnUiThread {
74
+ subscribers.forEach {
75
+ it.shapeUpdated(shape)
76
+ }
77
+ }
78
+ }
79
+
80
+ override fun start() {
81
+ if (timer != null) {
82
+ Log.d(LOG_TAG, "Timer for animator $tag is already running (subscribers: ${subscribers.count()})")
83
+ return
84
+ }
85
+
86
+ Log.d(LOG_TAG, "Started timer for animator $tag (subscribers: ${subscribers.count()})")
87
+
88
+ startedAt = Date()
89
+ timer = Timer()
90
+ timer?.schedule(object : TimerTask() {
91
+ override fun run() {
92
+ refresh()
93
+ }
94
+ }, 0, (period * 1000).toLong())
95
+ }
96
+
97
+ override fun stop() {
98
+ if (timer == null) {
99
+ Log.d(LOG_TAG, "Timer for animator $tag is already stopped (subscribers: ${subscribers.count()})")
100
+ return
101
+ }
102
+
103
+ Log.d(LOG_TAG,"Stopped timer for animator $tag (subscribers: ${subscribers.count()})")
104
+
105
+ timer?.cancel()
106
+ timer = null
107
+ }
108
+
109
+ override fun getShape(): GeoJson {
110
+ return getAnimatedShape(getAnimatorAgeSec())
111
+ }
112
+ }
113
+
114
+ class ShapeAnimatorManager {
115
+ private val animators = hashMapOf<Tag, ShapeAnimator>();
116
+
117
+ fun add(animator: ShapeAnimator) {
118
+ animators[animator.tag] = animator
119
+ }
120
+
121
+ fun isShapeAnimatorTag(shape: String): Boolean {
122
+ return shape.startsWith("{\"__nativeTag\":")
123
+ }
124
+
125
+ fun get(tag: String): ShapeAnimator? {
126
+ return if (isShapeAnimatorTag(tag)) {
127
+ val obj = JSONObject(tag)
128
+ val _tag = obj.getLong("__nativeTag")
129
+ get(_tag);
130
+ } else {
131
+ null
132
+ }
133
+ }
134
+
135
+ fun get(tag: Tag): ShapeAnimator? {
136
+ val result = animators[tag]
137
+ if (result == null) {
138
+ Logger.e(LOG_TAG, "Shape animator for tag $tag was not found")
139
+ }
140
+ return result
141
+ }
142
+ }