diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraStop.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraStop.java index f6623b56c..97e4c9c6f 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraStop.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraStop.java @@ -179,6 +179,9 @@ public static CameraStop fromReadableMap(Context context, @NonNull ReadableMap r case CameraMode.FLIGHT: stop.setMode(CameraMode.FLIGHT); break; + case CameraMode.LINEAR: + stop.setMode(CameraMode.LINEAR); + break; case CameraMode.NONE: stop.setMode(CameraMode.NONE); break; diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraUpdateItem.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraUpdateItem.java index 11053f463..4bfb472bd 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraUpdateItem.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/CameraUpdateItem.java @@ -76,8 +76,10 @@ public void onFinish() { if (mCameraMode == CameraMode.FLIGHT) { map.animateCamera(mCameraUpdate, duration, callback); + } else if (mCameraMode == CameraMode.LINEAR) { + map.easeCamera(mCameraUpdate, duration, false, callback); } else if (mCameraMode == CameraMode.EASE) { - map.easeCamera(mCameraUpdate, duration, callback); + map.easeCamera(mCameraUpdate, duration, true, callback); } } diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/RCTMGLCamera.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/RCTMGLCamera.java index 8cb38e132..7bf17454e 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/RCTMGLCamera.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/RCTMGLCamera.java @@ -327,7 +327,7 @@ public void onFinish() { }; if (isAnimated) { - mMapView.easeCamera(cameraUpdate, USER_LOCATION_CAMERA_MOVE_DURATION, callback); + mMapView.easeCamera(cameraUpdate, USER_LOCATION_CAMERA_MOVE_DURATION, true, callback); } else { mMapView.moveCamera(cameraUpdate, callback); } diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/constants/CameraMode.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/constants/CameraMode.java index 016fa7096..4d0bc1bcc 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/constants/CameraMode.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/camera/constants/CameraMode.java @@ -11,11 +11,12 @@ public class CameraMode { - @IntDef({ FLIGHT, EASE, NONE }) + @IntDef({ FLIGHT, EASE, LINEAR, NONE }) @Retention(RetentionPolicy.SOURCE) public @interface Mode {} public static final int FLIGHT = 1; public static final int EASE = 2; - public static final int NONE = 3; + public static final int LINEAR = 3; + public static final int NONE = 4; } diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.java index d24d7405b..10a47d18b 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/mapview/RCTMGLMapView.java @@ -343,8 +343,8 @@ public void moveCamera(CameraUpdate cameraUpdate) { mMap.moveCamera(cameraUpdate); } - public void easeCamera(CameraUpdate cameraUpdate, int duration, MapboxMap.CancelableCallback callback) { - mMap.easeCamera(cameraUpdate, duration, callback); + public void easeCamera(CameraUpdate cameraUpdate, int duration, boolean easingInterpolator, MapboxMap.CancelableCallback callback) { + mMap.easeCamera(cameraUpdate, duration, easingInterpolator, callback); } public void easeCamera(CameraUpdate cameraUpdate) { diff --git a/android/rctmgl/src/main/java/com/mapbox/rctmgl/modules/RCTMGLModule.java b/android/rctmgl/src/main/java/com/mapbox/rctmgl/modules/RCTMGLModule.java index 6a58d304b..c36077797 100644 --- a/android/rctmgl/src/main/java/com/mapbox/rctmgl/modules/RCTMGLModule.java +++ b/android/rctmgl/src/main/java/com/mapbox/rctmgl/modules/RCTMGLModule.java @@ -106,6 +106,7 @@ public Map getConstants() { Map cameraModes = new HashMap<>(); cameraModes.put("Flight", CameraMode.FLIGHT); cameraModes.put("Ease", CameraMode.EASE); + cameraModes.put("Linear", CameraMode.LINEAR); cameraModes.put("None", CameraMode.NONE); // style source constants diff --git a/docs/Camera.md b/docs/Camera.md index 2819b010d..7fdc1f147 100644 --- a/docs/Camera.md +++ b/docs/Camera.md @@ -6,7 +6,7 @@ | Prop | Type | Default | Required | Description | | ---- | :--: | :-----: | :------: | :----------: | | animationDuration | `number` | `2000` | `false` | The duration a camera update takes (in ms) | -| animationMode | `enum` | `'easeTo'` | `false` | The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `moveTo` | +| animationMode | `enum` | `'easeTo'` | `false` | The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `linearTo`, `moveTo` | | defaultSettings | `shape` | `none` | `false` | Default view settings applied on camera | |   centerCoordinate | `array` | `none` | `false` | Center coordinate on map [lng, lat] | |   heading | `number` | `none` | `false` | Heading on map | diff --git a/docs/docs.json b/docs/docs.json index 4f30a1751..2b95a0d1b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -414,7 +414,7 @@ "required": false, "type": "enum", "default": "'easeTo'", - "description": "The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `moveTo`" + "description": "The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `linearTo`, `moveTo`" }, { "name": "defaultSettings", diff --git a/index.d.ts b/index.d.ts index d7f2adcc2..4c56df12c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -479,7 +479,7 @@ export interface MapViewProps extends ViewProps { export interface CameraProps extends CameraSettings, ViewProps { animationDuration?: number; - animationMode?: 'flyTo' | 'easeTo' | 'moveTo'; + animationMode?: 'flyTo' | 'easeTo' | 'linearTo' | 'moveTo'; defaultSettings?: CameraSettings; minZoomLevel?: number; maxZoomLevel?: number; @@ -516,7 +516,7 @@ export interface CameraSettings { }; zoomLevel?: number; animationDuration?: number; - animationMode?: 'flyTo' | 'easeTo' | 'moveTo'; + animationMode?: 'flyTo' | 'easeTo' | 'linearTo' | 'moveTo'; stops?: CameraSettings[]; } diff --git a/ios/RCTMGL/CameraMode.h b/ios/RCTMGL/CameraMode.h index 46c034af2..b46750698 100644 --- a/ios/RCTMGL/CameraMode.h +++ b/ios/RCTMGL/CameraMode.h @@ -12,6 +12,7 @@ extern int const RCT_MAPBOX_CAMERA_MODE_FLIGHT; extern int const RCT_MAPBOX_CAMERA_MODE_EASE; +extern int const RCT_MAPBOX_CAMERA_MODE_LINEAR; extern int const RCT_MAPBOX_CAMERA_MODE_NONE; @end diff --git a/ios/RCTMGL/CameraMode.m b/ios/RCTMGL/CameraMode.m index 8bd67224d..b27df6caf 100644 --- a/ios/RCTMGL/CameraMode.m +++ b/ios/RCTMGL/CameraMode.m @@ -12,6 +12,7 @@ @implementation CameraMode int const RCT_MAPBOX_CAMERA_MODE_FLIGHT = 1; int const RCT_MAPBOX_CAMERA_MODE_EASE = 2; -int const RCT_MAPBOX_CAMERA_MODE_NONE = 3; +int const RCT_MAPBOX_CAMERA_MODE_LINEAR = 3; +int const RCT_MAPBOX_CAMERA_MODE_NONE = 4; @end diff --git a/ios/RCTMGL/CameraStop.m b/ios/RCTMGL/CameraStop.m index 1d40af949..65d67a69f 100644 --- a/ios/RCTMGL/CameraStop.m +++ b/ios/RCTMGL/CameraStop.m @@ -21,6 +21,8 @@ - (void)setMode:(NSNumber *)mode _mode = [NSNumber numberWithInt:modeInt]; } else if (modeInt == RCT_MAPBOX_CAMERA_MODE_NONE) { _mode = [NSNumber numberWithInt:modeInt]; + } else if (modeInt == RCT_MAPBOX_CAMERA_MODE_LINEAR) { + _mode = [NSNumber numberWithInt:modeInt]; } else { _mode = [NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_EASE]; } diff --git a/ios/RCTMGL/CameraUpdateItem.m b/ios/RCTMGL/CameraUpdateItem.m index 515ee0a7b..9f841a4c2 100644 --- a/ios/RCTMGL/CameraUpdateItem.m +++ b/ios/RCTMGL/CameraUpdateItem.m @@ -32,11 +32,13 @@ - (void)execute:(RCTMGLMapView *)mapView withCompletionHandler:(void (^)(void))c if (_cameraStop.mode == [NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_FLIGHT]) { [self _flyToCamera:mapView withCompletionHandler:completionHandler]; } else if (_cameraStop.mode == [NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_EASE]) { - [self _moveCamera:mapView animated:YES withCompletionHandler:completionHandler]; + [self _moveCamera:mapView animated:YES ease:YES withCompletionHandler:completionHandler]; + } else if (_cameraStop.mode == [NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_LINEAR]) { + [self _moveCamera:mapView animated:YES ease:NO withCompletionHandler:completionHandler]; } else if ([self _areBoundsValid:_cameraStop.bounds]) { [self _fitBoundsCamera:mapView withCompletionHandler:completionHandler]; } else { - [self _moveCamera:mapView animated:NO withCompletionHandler:completionHandler]; + [self _moveCamera:mapView animated:NO ease:NO withCompletionHandler:completionHandler]; } } @@ -51,16 +53,17 @@ - (void)_flyToCamera:(RCTMGLMapView*)mapView withCompletionHandler:(void (^)(voi } } -- (void)_moveCamera:(RCTMGLMapView*)mapView animated:(BOOL)animated withCompletionHandler:(void (^)(void))completionHandler +- (void)_moveCamera:(RCTMGLMapView*)mapView animated:(BOOL)animated ease:(BOOL)ease withCompletionHandler:(void (^)(void))completionHandler { if ([self _hasCenterCoordAndZoom]) { [self _centerCoordWithZoomCamera:mapView animated:animated withCompletionHandler:completionHandler]; } else { RCTMGLCameraWithPadding *nextCamera = [self _makeCamera:mapView]; + NSString *easeFunctionName = ease ? kCAMediaTimingFunctionEaseInEaseOut : kCAMediaTimingFunctionLinear; [mapView setCamera:nextCamera.camera withDuration:animated ? _cameraStop.duration : 0 - animationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] + animationTimingFunction:[CAMediaTimingFunction functionWithName:easeFunctionName] edgePadding:nextCamera.boundsPadding completionHandler:completionHandler]; } diff --git a/ios/RCTMGL/MGLModule.m b/ios/RCTMGL/MGLModule.m index d9a795000..80cf59850 100644 --- a/ios/RCTMGL/MGLModule.m +++ b/ios/RCTMGL/MGLModule.m @@ -73,6 +73,7 @@ + (BOOL)requiresMainQueueSetup NSMutableDictionary *cameraModes = [[NSMutableDictionary alloc] init]; [cameraModes setObject:[NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_FLIGHT] forKey:@"Flight"]; [cameraModes setObject:[NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_EASE] forKey:@"Ease"]; + [cameraModes setObject:[NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_LINEAR] forKey:@"Linear"]; [cameraModes setObject:[NSNumber numberWithInt:RCT_MAPBOX_CAMERA_MODE_NONE] forKey:@"None"]; // style sources diff --git a/javascript/components/Camera.js b/javascript/components/Camera.js index 91b69d29b..77e021b81 100644 --- a/javascript/components/Camera.js +++ b/javascript/components/Camera.js @@ -81,9 +81,9 @@ class Camera extends React.Component { animationDuration: PropTypes.number, /** - * The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `moveTo` + * The animationstyle when the camara updates. One of; `flyTo`, `easeTo`, `linearTo`, `moveTo` */ - animationMode: PropTypes.oneOf(['flyTo', 'easeTo', 'moveTo']), + animationMode: PropTypes.oneOf(['flyTo', 'easeTo', 'linearTo', 'moveTo']), /** * Default view settings applied on camera @@ -161,6 +161,7 @@ class Camera extends React.Component { Flight: 'flyTo', Move: 'moveTo', Ease: 'easeTo', + Linear: 'linearTo', }; UNSAFE_componentWillReceiveProps(nextProps) { @@ -503,6 +504,8 @@ class Camera extends React.Component { return MapboxGL.CameraModes.Flight; case Camera.Mode.Move: return MapboxGL.CameraModes.None; + case Camera.Mode.Linear: + return MapboxGL.CameraModes.Linear; default: return MapboxGL.CameraModes.Ease; }