0

I am using react-native-view-shot to save a screenshot of a view, whose height is not initially defined, as I am using padding and setting the height of the view using the onLayout method.

The problem is that, when the view has an initial fixed height, the screenshot taken does not have a white background, which is what I want. However, when I set the height when the onLayout is invoked, the screenshot has a white background.

Here's my code:

const [height, setHeight] = useState();

  <View
    onLayout={(e) => {
      setHeight(e.nativeEvent.layout.height);
    }}
    ref={contentRef}
    style={{
      height,
      width: width - 12,
      backgroundColor: "darkblue",
      borderRadius: 32,
    }}
  >
    <Text style={styles.text}>This is a test using padding</Text>
  </View>

https://snack.expo.dev/@pietroputelli/react-native-view-shot

=========== EDIT ===========

 <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <View ref={shotRef} style={{ backgroundColor: "transparent" }}>
        <View
          onLayout={(e) => {
            setHeight(e.nativeEvent.layout.height);
          }}
          style={{
            height,
            width: width / 2 - 12,
            backgroundColor: "darkblue",
            borderRadius: 32,
          }}
        >
          <Text style={{ color: "white" }}>This is a test using padding</Text>
        </View>
      </View>
      <Button
        onPress={() => {
          captureRef(shotRef, {
            format: "png",
            quality: 0.8,
          }).then(
            async (uri) => {
              await MediaLibrary.saveToLibraryAsync(uri);
            },
            (error) => console.error("Oops, snapshot failed", error)
          );
        }}
        title="Take screenshot"
      />
    </View>
PietroPutelli
  • 482
  • 4
  • 20

1 Answers1

0

I can able to generate the same from viewshot: take another view and give a reference to that view and generate a screenshot from that. might be its issue of reference. Please check the below screenshot.

enter image description here

            <View ref={viewshotRef}
                style={{
                    // whatever you want to add as per your requirement 
                }} >
                <View
                    onLayout={(e) => {
                        setHeight(e.nativeEvent.layout.height);
                    }}
                    style={{
                        height,
                        width: DEVICE_WIDTH / 2 - 12,
                        backgroundColor: "darkblue",
                        borderRadius: 32,
                    }}
                >
                    <Text style={{ color: 'white' }}>This is a test using padding</Text>
                </View>
            </View>

For base64:

import * as MediaLibrary from "expo-media-library";
import React, { useRef, useState } from "react";
import {
    Button,
    Dimensions,
    StyleSheet,
    Text,
    View,
} from "react-native";
import ViewShot, { captureRef } from "react-native-view-shot";

const { width } = Dimensions.get("window");

export default function ViewCapture() {
    const contentRef = useRef();

    const [height, setHeight] = useState(undefined);

    return (
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "transparent" }}>
            <ViewShot ref={contentRef} options={{ result: 'base64' }}>
                <View
                    onLayout={(e) => {
                        setHeight(e.nativeEvent.layout.height);
                    }}
                    style={{
                        height,
                        width: width - 12,
                        backgroundColor: "darkblue",
                        borderRadius: 32,
                    }}
                >
                    <Text style={{ color: "white" }}>This is a test using padding</Text>
                </View>
            </ViewShot>
            {/* </View> */}

            <Button
                onPress={() => {
                    contentRef.current.capture().then((url) => {
                        console.log("on success", "data:image/jpeg;base64,", url)
                        //   await MediaLibrary.saveToLibraryAsync(uri);
                    },
                        (error) => console.error("Oops, snapshot failed", error)
                    );
                }}
                title="Take screenshot"
            />
        </View>

    );
}

For File:

You need to set the result as tmpfile so you will get file uri in the callback

   <ViewShot ref={contentRef} options={{ result: 'tmpfile' }}>

I hope it will work!

Nensi Kasundra
  • 1,980
  • 6
  • 21
  • 34