在React Native中使用AnimateCamera在功能组件中

发布于 2025-01-27 04:23:35 字数 5037 浏览 3 评论 0原文

摘要

我正在使用react-native-map,并尝试使用andaTecameraandaTemarkerTocoortion同时但根本无法动画andaTecamera

到目前为止的工作部件

我在下面共享的GIF中的“红色圆圈”应该从一个位置移至另一个位置,并使用动画移动。 我已经利用 >注释以便能够通过动画将代码变成功能组件的动画移动标记,并且确实有效。 移动标记gif

我的目标

我希望相机在标记外也移动,以便始终感觉到红色圆圈就像是在电话屏幕上的中心一样。当我按下下面的“动画”按钮时,所有这些都应该发生。

我试图对MapView做同样的事情,我为标记做了什么。

我已经在< mapView>mapref状态下创建了一个状态

const [mapRef, setMapRef] = useState(null);

提供的连接

 return (
            <View style={...}>
                <MapView
                    ref= {mapRef => {setMapRef(mapRef);}}
                    initialRegion = {
                        ...
                      }
                    ...
                 />

和 按下它进入此功能并尝试工作AnimAteCamera函数

function animateMarkerAndCamera() {

    let newCoordinate = {
        latitude: 32.601,
        longitude: 44.0172,
        latitudeDelta: 0.012,
        longitudeDelta: 0.012,
    };
    let Camera = {
        ...
    }
    if (myMarker) {
       
        myMarker.animateMarkerToCoordinate(newCoordinate, 4000);
        mapRef.animateCamera({Camera}, 4000)
    }

}

chose按照 docs

 let Camera = {
        center: {
            latitude: newCoordinate.latitude,
            longitude: newCoordinate.longitude,
        },
        pitch: 2,
        heading: 20,
        zoom: 40
    }

所以我希望它能像标记动画一样动画,但不起作用。

请告诉我我的错。

完整代码...

import React, {useState} from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import MapView, { AnimatedRegion, MarkerAnimated } from 'react-native-maps';

const PlayScreen = (props) => {

    const [myMarker, setMyMarker] = useState(null);
    const [mapRef, setMapRef] = useState(null);

    const [coordinate, setCoordinate] = useState(new AnimatedRegion({ 
        latitude: 32.5983,
        longitude: 44.0175,
        latitudeDelta: 0.012,
        longitudeDelta:0.012,
    }));
  
     function animateMarkerAndCamera() {
        
        let newCoordinate = {
            latitude: 32.601,
            longitude: 44.0172,
            latitudeDelta: 0.012,
            longitudeDelta: 0.012,
        };
        
        if(myMarker){
            myMarker.animateMarkerToCoordinate(newCoordinate,4000);
            mapRef.animateCamera(newCoordinate, 4000);
        }
        
    }
  
        return (
            <View style={styles.container}>
                <MapView
                    ref= {mapRef => {setMapRef(mapRef);}}
                    style={styles.map}
                    initialRegion={{
                        latitude: 32.5983,
                        longitude: 44.0175,
                        latitudeDelta: 0.012,
                        longitudeDelta: 0.012,
                    }}

                >
                    <MarkerAnimated 
                         ref={marker => {
                            setMyMarker(marker);
                        }} 
                        image={require('../../../Assets/Images/curlingStone.png')}
                        coordinate={coordinate}
                    />
                        
                </MapView>
                <View style={styles.buttonContainer}>
                    <TouchableOpacity
                        onPress={() => animateMarkerAndCamera()}
                        style={[styles.bubble, styles.button]}
                    >
                        <Text>Animate</Text>
                    </TouchableOpacity>
                </View>
            </View>
        );

}

const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,
        justifyContent: 'flex-end',
        alignItems: 'center',
    },
    map: {
        ...StyleSheet.absoluteFillObject,
    },
    bubble: {
        flex: 1,
        backgroundColor: 'rgba(255,255,255,0.7)',
        paddingHorizontal: 18,
        paddingVertical: 12,
        borderRadius: 20,
    },
    latlng: {
        width: 200,
        alignItems: 'stretch',
    },
    button: {
        width: 80,
        paddingHorizontal: 12,
        alignItems: 'center',
        marginHorizontal: 10,
    },
    buttonContainer: {
        flexDirection: 'row',
        marginVertical: 20,
        backgroundColor: 'transparent',
    },
});
export default PlayScreen

Summary

I'm using react-native-map and trying to use animateCamera and animateMarkerToCoordinate both at the same time but couldn't animate the animateCamera at all.

The working part so far

The "red circle" in the gif I've shared below, should be moving from one location to another location with animation.
I've taken advantage of this comment to be able to move marker with animation turning the code into functional component and it really worked.
Moving marker gif

My aim

I want the camera also move besides marker, so that the red circle should always be felt like it is centered in the phone screen. All this should occur when I press "animate" button below.

I've tried to do the same thing to the mapview what I've done to marker.

I've created a state

const [mapRef, setMapRef] = useState(null);

and supplied connection between <MapView> and mapRef state using the below line beginning with ref

 return (
            <View style={...}>
                <MapView
                    ref= {mapRef => {setMapRef(mapRef);}}
                    initialRegion = {
                        ...
                      }
                    ...
                 />

So when the button is pressed it goes inside this function and try to work animateCamera function

function animateMarkerAndCamera() {

    let newCoordinate = {
        latitude: 32.601,
        longitude: 44.0172,
        latitudeDelta: 0.012,
        longitudeDelta: 0.012,
    };
    let Camera = {
        ...
    }
    if (myMarker) {
       
        myMarker.animateMarkerToCoordinate(newCoordinate, 4000);
        mapRef.animateCamera({Camera}, 4000)
    }

}

By the way Camera adjusted like it is mentioned in docs

 let Camera = {
        center: {
            latitude: newCoordinate.latitude,
            longitude: newCoordinate.longitude,
        },
        pitch: 2,
        heading: 20,
        zoom: 40
    }

So I'm expecting for it to animate just like it did for marker's animation, but not working.

Please tell me my fault.

Full code...

import React, {useState} from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import MapView, { AnimatedRegion, MarkerAnimated } from 'react-native-maps';

const PlayScreen = (props) => {

    const [myMarker, setMyMarker] = useState(null);
    const [mapRef, setMapRef] = useState(null);

    const [coordinate, setCoordinate] = useState(new AnimatedRegion({ 
        latitude: 32.5983,
        longitude: 44.0175,
        latitudeDelta: 0.012,
        longitudeDelta:0.012,
    }));
  
     function animateMarkerAndCamera() {
        
        let newCoordinate = {
            latitude: 32.601,
            longitude: 44.0172,
            latitudeDelta: 0.012,
            longitudeDelta: 0.012,
        };
        
        if(myMarker){
            myMarker.animateMarkerToCoordinate(newCoordinate,4000);
            mapRef.animateCamera(newCoordinate, 4000);
        }
        
    }
  
        return (
            <View style={styles.container}>
                <MapView
                    ref= {mapRef => {setMapRef(mapRef);}}
                    style={styles.map}
                    initialRegion={{
                        latitude: 32.5983,
                        longitude: 44.0175,
                        latitudeDelta: 0.012,
                        longitudeDelta: 0.012,
                    }}

                >
                    <MarkerAnimated 
                         ref={marker => {
                            setMyMarker(marker);
                        }} 
                        image={require('../../../Assets/Images/curlingStone.png')}
                        coordinate={coordinate}
                    />
                        
                </MapView>
                <View style={styles.buttonContainer}>
                    <TouchableOpacity
                        onPress={() => animateMarkerAndCamera()}
                        style={[styles.bubble, styles.button]}
                    >
                        <Text>Animate</Text>
                    </TouchableOpacity>
                </View>
            </View>
        );

}

const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,
        justifyContent: 'flex-end',
        alignItems: 'center',
    },
    map: {
        ...StyleSheet.absoluteFillObject,
    },
    bubble: {
        flex: 1,
        backgroundColor: 'rgba(255,255,255,0.7)',
        paddingHorizontal: 18,
        paddingVertical: 12,
        borderRadius: 20,
    },
    latlng: {
        width: 200,
        alignItems: 'stretch',
    },
    button: {
        width: 80,
        paddingHorizontal: 12,
        alignItems: 'center',
        marginHorizontal: 10,
    },
    buttonContainer: {
        flexDirection: 'row',
        marginVertical: 20,
        backgroundColor: 'transparent',
    },
});
export default PlayScreen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蘸点软妹酱 2025-02-03 04:23:35

因此,正如我之前所解释的那样,我试图使用andaTecameraandamarkerTocoortion一起,以便感觉就像我的标记,红色圆圈,始终在中心而且只有坐标似乎在变化。

经过一番研究,我发现 this 并使我的代码类似。现在我获得了我想实现的目标。 gif在这里

我所做的更改是写为评论

代码在下面

import {useState, useRef} from 'react'
import ... //same as before

const PlayScreen = (props) => {
    const markerLatitude=32.5983
    const markerLongitude=44.0175
    //changed from useState to useRef
    const mapRef = useRef (null);
    const [myMarker, setMyMarker] = useState(null);
    const [coordinate, setCoordinate] = useState(new AnimatedRegion({
        latitude: markerLatitude,
        longitude: markerLongitude,
        latitudeDelta: 0.012,
        longitudeDelta: 0.012,
    }));

    function animateMarkerAndCamera() {

        let newCoordinate = {
            latitude: 32.601,
            longitude: 44.0172,
            latitudeDelta: 0.012,
            longitudeDelta: 0.012,
        };
        //camera will position itself to these coordinates.
        const newCamera= {
            center: {
                latitude: 32.601,
                longitude: 44.0172,
            },
            pitch: 0,
            heading: 0,
            //zoom: 17  --Use it when required
        }
        
        
        if (myMarker) {
            myMarker.animateMarkerToCoordinate(newCoordinate, 4000);
            //camera type, `newCamera`, used inside animateCamera
            mapRef.current.animateCamera(newCamera, {duration: 4000})
        }
        

    }

    return (
        <View style={styles.container}>
            <MapView
                ref={ mapRef } //There is also change here
                style={styles.map}
                initialRegion={{
                    latitude: 32.5983,
                    longitude: 44.0175,
                    latitudeDelta: 0.012,
                    longitudeDelta: 0.012,
                }}
                //These are newly added
                pitchEnabled ={false}
                zoomEnabled ={false}
            >
                <MarkerAnimated
                    ref={marker => {
                        setMyMarker(marker);
                    }}
                    {/*any kind of image can be replaced here */}
                    image={require('../../../Assets/Images/curlingStone.png')}
                    coordinate={coordinate}
                    
                />

            </MapView>
            <View style={styles.buttonContainer}>
                <TouchableOpacity
                    onPress={() => animateMarkerAndCamera()}
                    style={[styles.bubble, styles.button]}
                >
                    <Text>Animate</Text>
                </TouchableOpacity>
            </View>
        </View>
    );

}
export default PlayScreen

const styles = StyleSheet.create({ ... //same as before

So, as I've explained before, I was trying to use animateCamera and animateMarkerToCoordinate together so that it could feel like my marker, the red circle, is always at the center and only the coordinates seem to be changing.

After a little research, I've found this and made mine similar to this code. Now I obtained what I wanted to achieve.Gif is here

Changes I've made were written as comments

The code is below

import {useState, useRef} from 'react'
import ... //same as before

const PlayScreen = (props) => {
    const markerLatitude=32.5983
    const markerLongitude=44.0175
    //changed from useState to useRef
    const mapRef = useRef (null);
    const [myMarker, setMyMarker] = useState(null);
    const [coordinate, setCoordinate] = useState(new AnimatedRegion({
        latitude: markerLatitude,
        longitude: markerLongitude,
        latitudeDelta: 0.012,
        longitudeDelta: 0.012,
    }));

    function animateMarkerAndCamera() {

        let newCoordinate = {
            latitude: 32.601,
            longitude: 44.0172,
            latitudeDelta: 0.012,
            longitudeDelta: 0.012,
        };
        //camera will position itself to these coordinates.
        const newCamera= {
            center: {
                latitude: 32.601,
                longitude: 44.0172,
            },
            pitch: 0,
            heading: 0,
            //zoom: 17  --Use it when required
        }
        
        
        if (myMarker) {
            myMarker.animateMarkerToCoordinate(newCoordinate, 4000);
            //camera type, `newCamera`, used inside animateCamera
            mapRef.current.animateCamera(newCamera, {duration: 4000})
        }
        

    }

    return (
        <View style={styles.container}>
            <MapView
                ref={ mapRef } //There is also change here
                style={styles.map}
                initialRegion={{
                    latitude: 32.5983,
                    longitude: 44.0175,
                    latitudeDelta: 0.012,
                    longitudeDelta: 0.012,
                }}
                //These are newly added
                pitchEnabled ={false}
                zoomEnabled ={false}
            >
                <MarkerAnimated
                    ref={marker => {
                        setMyMarker(marker);
                    }}
                    {/*any kind of image can be replaced here */}
                    image={require('../../../Assets/Images/curlingStone.png')}
                    coordinate={coordinate}
                    
                />

            </MapView>
            <View style={styles.buttonContainer}>
                <TouchableOpacity
                    onPress={() => animateMarkerAndCamera()}
                    style={[styles.bubble, styles.button]}
                >
                    <Text>Animate</Text>
                </TouchableOpacity>
            </View>
        </View>
    );

}
export default PlayScreen

const styles = StyleSheet.create({ ... //same as before
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文