From 24edfeb19dd2666574684942958825b07810bc80 Mon Sep 17 00:00:00 2001 From: Naftali Beder Date: Tue, 13 Feb 2024 08:45:39 -0600 Subject: [PATCH] Fix double padding on camera when setting bounds (#3354) * Zero padding when it's already baked into center/zoom from bounds * Apply bounds camera directly to prevent padding being applied twice * Update example to allow granular control over padding * Scale down padding if it surpasses map size * Remove instant set on zero duration to allow dynamic duration in flyTo * Enable setting min and max zoom limits * Allow removing map zoom limits and avoid unneeded zoom comparisons * Remove unused import --- example/src/examples/V10/CameraAnimation.tsx | 289 +++++++++++-------- ios/RNMBX/RNMBXCamera.swift | 99 +++---- 2 files changed, 210 insertions(+), 178 deletions(-) diff --git a/example/src/examples/V10/CameraAnimation.tsx b/example/src/examples/V10/CameraAnimation.tsx index 1e1b6185f..faafa9a67 100644 --- a/example/src/examples/V10/CameraAnimation.tsx +++ b/example/src/examples/V10/CameraAnimation.tsx @@ -1,9 +1,8 @@ -import { Divider, Text } from '@rneui/base'; +import { CheckBox, Divider, Slider, Text } from '@rneui/base'; import { Camera, CameraAnimationMode, CameraBounds, - CameraPadding, CircleLayer, Logger, MapView, @@ -36,80 +35,48 @@ const initialCoordinate: Coordinate = { longitude: -73.984638, }; -const zeroPadding: CameraPadding = { - paddingTop: 0, - paddingBottom: 0, - paddingLeft: 0, - paddingRight: 0, -}; -const evenPadding: CameraPadding = { - paddingTop: 40, - paddingBottom: 40, - paddingLeft: 40, - paddingRight: 40, -}; -const minZoomLevel = 8; -const maxZoomLevel = 16; - -const randPadding = (): CameraPadding => { - const randNum = () => { - const items = [0, 150, 300]; - return items[Math.floor(Math.random() * items.length)]; - }; - - return { - paddingTop: randNum(), - paddingBottom: randNum(), - paddingLeft: randNum(), - paddingRight: randNum(), - }; -}; - const toPosition = (coordinate: Coordinate): Position => { return [coordinate.longitude, coordinate.latitude]; }; +const rand = () => Math.random() * 0.008; + const CameraAnimation = () => { - const [animationMode, setAnimationMode] = - useState('moveTo'); + const [easing, setEasing] = useState('easeTo'); const [coordinates, setCoordinates] = useState([ initialCoordinate, ]); - const [padding, setPadding] = useState(zeroPadding); - - const paddingDisplay = useMemo(() => { - return `L ${padding.paddingLeft} | R ${padding.paddingRight} | T ${padding.paddingTop} | B ${padding.paddingBottom}`; - }, [padding]); + const [paddingLeft, setPaddingLeft] = useState(0); + const [paddingRight, setPaddingRight] = useState(0); + const [paddingTop, setPaddingTop] = useState(0); + const [paddingBottom, setPaddingBottom] = useState(0); + const [minZoom, setMinZoom] = useState(undefined); + const [maxZoom, setMaxZoom] = useState(undefined); - const move = useCallback( - (_animationMode: CameraAnimationMode, shouldCreateMultiple: boolean) => { - setAnimationMode(_animationMode); - - if (shouldCreateMultiple) { - const _centerCoordinate = { - latitude: initialCoordinate.latitude + Math.random() * 0.2, - longitude: initialCoordinate.longitude + Math.random() * 0.2, - }; - const _coordinates = Array(10) - .fill(0) - .map((_) => { - return { - latitude: _centerCoordinate.latitude + Math.random() * 0.2, - longitude: _centerCoordinate.longitude + Math.random() * 0.2, - }; - }); - setCoordinates(_coordinates); - } else { - setCoordinates([ - { - latitude: initialCoordinate.latitude + Math.random() * 0.2, - longitude: initialCoordinate.longitude + Math.random() * 0.2, - }, - ]); - } - }, - [], - ); + const move = useCallback((kind: 'center' | 'bounds') => { + if (kind === 'bounds') { + const _centerCoordinate = { + latitude: initialCoordinate.latitude + rand(), + longitude: initialCoordinate.longitude + rand(), + }; + const _coordinates = Array(10) + .fill(0) + .map((_) => { + return { + latitude: _centerCoordinate.latitude + rand(), + longitude: _centerCoordinate.longitude + rand(), + }; + }); + setCoordinates(_coordinates); + } else if (kind === 'center') { + setCoordinates([ + { + latitude: initialCoordinate.latitude + rand(), + longitude: initialCoordinate.longitude + rand(), + }, + ]); + } + }, []); const features = useMemo((): Feature[] => { return coordinates.map((p) => { @@ -152,19 +119,101 @@ const CameraAnimation = () => { } }, [coordinates]); - const locationDisplay = useMemo(() => { - if (coordinates.length > 1) { - const ne = centerOrBounds.bounds?.ne.map((n) => n.toFixed(3)); - const sw = centerOrBounds.bounds?.sw.map((n) => n.toFixed(3)); - return `ne ${ne} | sw ${sw}`; - } else if (coordinates.length === 1) { - const lon = coordinates[0].longitude.toFixed(4); - const lat = coordinates[0].latitude.toFixed(4); - return `lon ${lon} | lat ${lat}`; - } else { - throw new Error('invalid location passed'); - } - }, [coordinates, centerOrBounds]); + const easingCheckBox = useCallback( + (value: CameraAnimationMode, label: string) => { + const isChecked = value === easing; + return ( + + setEasing(value)} + containerStyle={{ + backgroundColor: 'transparent', + marginRight: -4, + }} + /> + + {label} + + + ); + }, + [easing], + ); + + const paddingCounter = useCallback( + (value: number, setValue: (value: number) => void, label: string) => { + return ( + + + {label} + {`${Math.round(value)}`} + + setValue(_value)} + /> + + ); + }, + [], + ); + + const zoomLimitCounter = useCallback( + ( + value: number | undefined, + setValue: (value?: number) => void, + label: string, + ) => { + return ( + + + {label} + {`${ + value ?? 'Not set' + }`} + + { + if (_value < 0) { + setValue(undefined); + } else { + setValue(Math.round(_value)); + } + }} + /> + + ); + }, + [], + ); return ( <> @@ -172,11 +221,16 @@ const CameraAnimation = () => { {features.map((feature) => { @@ -192,53 +246,39 @@ const CameraAnimation = () => { - centerCoordinate + Coordinate -