React Native Maps - takeSnapshot无法捕获标记

7

React-Native: https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz

React: 16.13.1

React-Native-Maps: 0.28.0

我希望在快照中包含标记。当使用takeSnapshot方法时,所有标记都会被忽略。

const snapshot = this.viewRefTest.takeSnapshot({
  format: 'png', // image formats: 'png', 'jpg' (default: 'png')
  quality: 0.5, // image quality: 0..1 (only relevant for jpg, default: 1)
  result: 'file', // result types: 'file', 'base64' (default: 'file')
});

<MapView
  ref={(viewRefTest) => {
    this.viewRefTest = viewRefTest;
  }}
  showsUserLocation={true}
  followUserLocation={true}>
  <MapView.Marker coordinate={item.location}>
    <Image
      style={{ width: 30, height: 30 }}
      source={require('../../assets/images/trophy.png')}
    />
    <Callout style={{ width: 250, flexDirection: 'row', alignItems: 'center' }}>
      <Text>$23</Text>
      <View>
        <Text style={{ fontSize: 12 }}>Custom Text!</Text>
      </View>
    </Callout>
  </MapView.Marker>
</MapView>;

请告知我这个可能性。

4个回答

2

尝试了添加延迟、高度/宽度等多种组合后,我无法使用takeSnapshot方法捕获自定义标记。

作为解决方法,我使用了react-native-view-shotcaptureRef方法。

https://github.com/gre/react-native-view-shot

const uri = await captureRef(this.viewRefTest, {
            format: "png",
            quality: 1
        })

<MapView
  ref={(viewRefTest) => {
    this.viewRefTest = viewRefTest;
  }}
  showsUserLocation={true}
  followUserLocation={true}>
  <MapView.Marker coordinate={item.location}>
    <Image
      style={{ width: 30, height: 30 }}
      source={require('../../assets/images/trophy.png')}
    />
    <Callout style={{ width: 250, flexDirection: 'row', alignItems: 'center' }}>
      <Text>$23</Text>
      <View>
        <Text style={{ fontSize: 12 }}>Custom Text!</Text>
      </View>
    </Callout>
  </MapView.Marker>
</MapView>

CaptureRef 返回一个图片URI的Promise。它可以帮助我们将React Native视图捕获为一张图片。我们可以指定捕获图片的高度、宽度、质量和格式。


1

你能尝试使用宽度和高度吗?

const snapshot = this.viewRefTest.takeSnapshot({
  width: 500,
  height: 500,
  format: 'png',
  quality: 0.5,
  result: 'file',
});

snapshot.then((uri) => {
  console.log(uri);
});

0

我认为这个bug取决于何时调用this.viewRefTest.takeSnapshot()

您可以在我的https://expo.dev/@duongtungls/expo-map-view-example中检查

我认为在地图挂载后立即调用takeSnapshot不会得到标记或地图。 如果在onMapReady回调之后调用,仍需要等待几百毫秒才能完全拍摄地图和标记的快照。

我希望这个示例代码可以帮助您解决问题。

import { StatusBar } from 'expo-status-bar';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import MapView, { Marker } from 'react-native-maps';
import { Ionicons } from '@expo/vector-icons';

export default function App() {
  const mapRef = useRef(null);
  const [uri, setUri] = useState(null);

  const takeSnapshot = useCallback(() => {
    if (!mapRef || !mapRef.current) {
      return;
    }
    setTimeout(() => {
      const snapshot = mapRef.current.takeSnapshot({
        format: 'png', // image formats: 'png', 'jpg' (default: 'png')
        quality: 0.5, // image quality: 0..1 (only relevant for jpg, default: 1)
        result: 'file', // result types: 'file', 'base64' (default: 'file')
      });
      snapshot.then((uri) => {
        setUri(uri);
      });
    }, 800); // I add some timeout delay because without delay snapnot won't have map or marker.
  }, [mapRef]);

  return (
    <View style={styles.container}>
      {!uri && (
        <MapView
          ref={mapRef}
          style={{
            width: '100%',
            height: '100%',
          }}
          initialRegion={{
            latitude: 37.78825,
            longitude: -122.4324,
            latitudeDelta: 0.0922,
            longitudeDelta: 0.0421,
          }}
          onMapReady={takeSnapshot} // I think need wait for map ready to take snapshot but seem still need wait by setTimeout to get fully snapshot
        >
          <Marker
            coordinate={{
              latitude: 37.78825,
              longitude: -122.4324,
            }}
            title={'Test'}
          >
            <Ionicons name="trophy" size={32} color="red" />
            <Text>This is a marker</Text>
          </Marker>
        </MapView>
      )}
      {uri && (
        <Image
          style={{
            width: '100%',
            height: '100%',
            resizeMode: 'contain',
            borderColor: 'red',
            borderWidth: 10,
          }}
          source={{
            uri,
          }}
        />
      )}
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

地图加载完成后进行快照

enter image description here

在 onMapReady 后进行快照拍摄,并延迟 800 毫秒

enter image description here

此致敬礼,


0

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接