From b35bb00c5e49794f10b15be430f0f1e37b750b5c Mon Sep 17 00:00:00 2001 From: Nikischin Date: Mon, 2 Oct 2023 16:59:42 +0200 Subject: [PATCH] Implement visible portion features --- src/components/Map.tsx | 91 +++++++++++++++++++++++++++++++++++-- src/components/MapProps.tsx | 42 +++++++++++++++++ support.md | 16 +++---- 3 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/components/Map.tsx b/src/components/Map.tsx index 9e4e8c7..f656e7e 100644 --- a/src/components/Map.tsx +++ b/src/components/Map.tsx @@ -47,9 +47,16 @@ const Map = React.forwardRef { if (exists.current) return; - const options = initialRegion - ? { region: toMapKitCoordinateRegion(initialRegion) } - : {}; + const options = {}; + if (initialRegion) { // FIXME: legacy fallback + // @ts-ignore + options.region = toMapKitCoordinateRegion(initialRegion); + } else if (region) { + // @ts-ignore + options.region = toMapKitCoordinateRegion(region); + } + if (visibleMapRect) { + if (!visibleMapRect.x || !visibleMapRect.y || !visibleMapRect.width + || !visibleMapRect.height) { + throw new Error('Visible map rects has to include x, y, width and height'); + } + // @ts-ignore + options.visibleMapRect = new mapkit.MapRect( + visibleMapRect.x, + visibleMapRect.y, + visibleMapRect.width, + visibleMapRect.height, + ); + } + if (center) { + // @ts-ignore + options.center = center; + } + if (rotation) { + // @ts-ignore + options.rotation = rotation; + } setMap(new mapkit.Map(element.current!, options)); exists.current = true; }); @@ -180,10 +213,60 @@ const Map = React.forwardRef { if (!map) return; - // @ts-ignore + map.cameraZoomRange = new mapkit.CameraZoomRange(minCameraDistance, maxCameraDistance); }, [map, minCameraDistance, maxCameraDistance]); + // Camera Distance + useEffect(() => { + if (!map) return; + if (!cameraDistance) return; + + map.setCameraDistanceAnimated(cameraDistance, regionUpdateAnimates); + }, [cameraDistance]); + + // Map Rotation + useEffect(() => { + if (!map) return; + if (!rotation) return; + + map.setRotationAnimated(rotation, regionUpdateAnimates); + }, [rotation]); + + // Center Coordinates + useEffect(() => { + if (!map) return; + if (!center) return; + + map.setCenterAnimated( + new mapkit.Coordinate(center.latitude, center.longitude), + regionUpdateAnimates, + ); + }, [center]); + + // Region Coordinates + useEffect(() => { + if (!map) return; + if (!region) return; + + map.setRegionAnimated(toMapKitCoordinateRegion(region), regionUpdateAnimates); + }, [region]); + + // Region Coordinates + useEffect(() => { + if (!map) return; + if (!visibleMapRect) return; + if (!visibleMapRect.x || !visibleMapRect.y || !visibleMapRect.width || !visibleMapRect.height) { + throw new Error('Visible map rects has to include x, y, width and height'); + } + map.setVisibleMapRectAnimated(new mapkit.MapRect( + visibleMapRect.x, + visibleMapRect.y, + visibleMapRect.width, + visibleMapRect.height, + ), regionUpdateAnimates); + }, [visibleMapRect]); + // Point of interest filter useEffect(() => { if (!map) return; diff --git a/src/components/MapProps.tsx b/src/components/MapProps.tsx index 1290088..16928fa 100644 --- a/src/components/MapProps.tsx +++ b/src/components/MapProps.tsx @@ -181,6 +181,12 @@ export default interface MapProps { */ cameraBoundary?: CoordinateRegion; + /** + * The altitude of the camera relative to the elevation of the center of the map. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/3257749-cameradistance} + */ + cameraDistance?: number; + /** * The minimum allowed distance of the camera from the center of the map in meters. */ @@ -191,6 +197,42 @@ export default interface MapProps { */ maxCameraDistance?: number; + /** + * The map coordinate at the center of the map view. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973914-center} + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973935-setcenteranimated} + */ + center?: { latitude: number, longitude: number }; + + /** + * The area the map is displaying. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973924-region} + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973936-setregionanimated} + */ + region?: CoordinateRegion; + + /** + * The map’s rotation, in degrees. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2991322-rotation} + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2991323-setrotationanimated} + */ + rotation?: number; + + /** + * The visible area of the map, in map units. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973951-visiblemaprect} + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973937-setvisiblemaprectanimated} + */ + visibleMapRect?: { x: number, y: number, width: number, height: number }; + + /** + * Set the animation parameter for the change listener function of the center, rotation, + * cameraDistance or region update. + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973935-setcenteranimated} + * @see {@link https://developer.apple.com/documentation/mapkitjs/map/2973936-setregionanimated} + */ + regionUpdateAnimates?: boolean; + /** * The map has loaded. */ diff --git a/support.md b/support.md index 6749f24..1ea8202 100644 --- a/support.md +++ b/support.md @@ -38,10 +38,10 @@ | Feature | Supported | | ------------------------------------ | ------------------ | -| MapConstructorOptions.visibleMapRect | ❌ | +| MapConstructorOptions.visibleMapRect | ✅ | | MapConstructorOptions.region | ✅ (initialRegion) | -| MapConstructorOptions.center | ❌ | -| MapConstructorOptions.rotation | ❌ | +| MapConstructorOptions.center | ✅ | +| MapConstructorOptions.rotation | ✅ | | MapConstructorOptions.tintColor | ❌ | #### Appearance and controls @@ -105,12 +105,12 @@ | Feature | Supported | | --------------- | ---------------------------------------- | -| center | ❌ | -| region | ❌ | -| rotation | ❌ | -| visibleMapRect | ❌ | +| center | ✅ | +| region | ✅ | +| rotation | ✅ | +| visibleMapRect | ✅ | | cameraBoundary | ✅ | -| cameraDistance | ❌ | +| cameraDistance | ✅ | | cameraZoomRange | ✅ (minCameraDistance/maxCameraDistance) | #### Controls