React Native Maps - takeSnapshot 不捕获标记

Posted

技术标签:

【中文标题】React Native Maps - takeSnapshot 不捕获标记【英文标题】:React Native Maps - takeSnapshot not capturing markers 【发布时间】:2021-11-04 18:31:12 【问题描述】:

反应原生:https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz 反应:16.13.1 反应原生地图: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>;

请告诉我这种可能性。

【问题讨论】:

【参考方案1】:

你可以尝试使用宽度和高度吗?

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

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

【讨论】:

【参考方案2】:

您可以通过使用"react-native-view-shot" 创建快照来解决此问题

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案3】:

我认为这个错误取决于你何时调用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',
  ,
);

地图安装后的快照

在 onMapReady 和 800 毫秒延迟后拍摄快照

最好的问候,

【讨论】:

【参考方案4】:

经过多次尝试和添加延迟、高度/宽度的组合后,我无法使用 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 视图捕获到图像。我们可以提及捕获图像的高度、宽度、质量和格式。

【讨论】:

以上是关于React Native Maps - takeSnapshot 不捕获标记的主要内容,如果未能解决你的问题,请参考以下文章

react-native-maps 中的当前位置

更新 react-native-maps 以使用 create-react-native-app

react native - react-native-maps initialRegion 不起作用

无法在我的项目中运行 react-native-maps

React-Native-Maps:地图为空。仅显示 Google 徽标和标记

缩放到指定的标记 react-native-maps