I want to put some overlays ontop of my camera view so that when the shot is taken by view shot it will be a picture with the overlays ontop.
My issue is that when I put my component nested inside the component it doesn't show up in the result of the view-shot.
If I just do the Overlay then it works but once I nest it inside the Camera component ( using expo-camera import { Camera, CameraType } from "expo-camera"; ) only the camera shows up in the view-shot when I take it.
I have tried adding collapsable={false} to all my views inside the component but that doesn't fix it.
Is there something I am doing wrong?
import { Camera, CameraType } from "expo-camera";
import { useEffect, useRef, useState } from "react";
import {
Button,
Dimensions,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
Image,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Stack, useRouter } from "expo-router";
import Overlay from "./components/overlay";
import ViewShot from "react-native-view-shot";
const MyComponent: React.FC = () => {
const viewShotRef = useRef<ViewShot | null>(null);
const [screenshotUri, setScreenshotUri] = useState<string>("");
const handleRetake = () => {
setScreenshotUri("");
};
const handleCapture = async () => {
console.log("viewShotRef.current=", viewShotRef.current);
if (viewShotRef.current) {
try {
const uri = await viewShotRef.current.capture!();
console.log("Captured and do something with ", uri);
setScreenshotUri(uri);
} catch (error) {
console.error("Capture failed:", error);
}
}
};
const [type, setType] = useState(CameraType.front);
const [permission, requestPermission] = Camera.useCameraPermissions();
const [camera, setCamera] = useState<Camera | null>(null);
const toggleCameraType = () => {
setType((current) =>
current === CameraType.back ? CameraType.front : CameraType.back,
);
};
const [hasCameraPermission, setHasCameraPermission] = useState<boolean>();
// Screen Ratio and image padding
const [imagePadding, setImagePadding] = useState(0);
const [ratio, setRatio] = useState("4:3"); // default is 4:3
const { height, width } = Dimensions.get("window");
const screenRatio = height / width;
const [isRatioSet, setIsRatioSet] = useState(false);
// on screen load, ask for permission to use the camera
useEffect(() => {
const getCameraStatus = async () => {
const request = await requestPermission();
setHasCameraPermission(request.granted);
};
getCameraStatus();
}, []);
const prepareRatio = async () => {
let desiredRatio = "4:3";
if (Platform.OS === "android" && camera) {
const ratios = await camera.getSupportedRatiosAsync();
// ..... ratio calculation
setImagePadding(remainder);
setRatio(desiredRatio);
setIsRatioSet(true);
}
};
const setCameraReady = async () => {
if (!isRatioSet) {
await prepareRatio();
}
};
if (hasCameraPermission === null) {
return (
<View className="flex-1 items-center justify-center self-center">
<Text>Waiting for camera permissions</Text>
</View>
);
} else if (hasCameraPermission === false) {
return (
<View className="flex-1 items-center justify-center self-center">
<Text>No access to camera</Text>
</View>
);
} else {
return (
<SafeAreaView className="flex-1">
<Stack.Screen options={{ title: "Live" }} />
<View className="flex-1 justify-center bg-neutral-800">
{/*
We created a Camera height by adding margins to the top and bottom,
but we could set the width/height instead
since we know the screen dimensions
*/}
{screenshotUri == "" ? (
<ViewShot ref={viewShotRef} style={{ flex: 1 }}>
<Camera
style={{
flex: 1,
// marginTop: imagePadding,
marginBottom: imagePadding,
}}
onCameraReady={setCameraReady}
ratio={ratio}
type={type}
ref={(ref) => {
setCamera(ref);
}}
>
<Overlay
toggleCameraType={toggleCameraType}
handleCapture={handleCapture}
distance={1.32}
duration={4.55}
/>
</Camera>
</ViewShot>
) : (
<View>
<TouchableOpacity
onPress={handleRetake}
className="absolute left-2 top-2 z-10"
>
<Text>Retake</Text>
</TouchableOpacity>
<Image
source={{ uri: screenshotUri }}
style={{
height: undefined,
width: "100%",
aspectRatio: 9 / 16,
alignSelf: "center",
}}
/>
</View>
)}
</View>
</SafeAreaView>
);
}
Version & Platform
using react native expo (managed workflow, not expo go) version number of react-native-view-shot is "react-native-view-shot": "3.5.0",
I want to put some overlays ontop of my camera view so that when the shot is taken by view shot it will be a picture with the overlays ontop. My issue is that when I put my component nested inside the component it doesn't show up in the result of the view-shot.
If I just do the Overlay then it works but once I nest it inside the Camera component ( using expo-camera import { Camera, CameraType } from "expo-camera"; ) only the camera shows up in the view-shot when I take it.
I have tried adding collapsable={false} to all my views inside the component but that doesn't fix it.
Is there something I am doing wrong?
Version & Platform
using react native expo (managed workflow, not expo go) version number of react-native-view-shot is "react-native-view-shot": "3.5.0",
**Platform: Android