How to take full page screenshot of webview in react native? Already tried "react-native-view-shot " Link but it only takes screenshot of the visible area. Someone please help. Thanks
Asked
Active
Viewed 1,287 times
2
-
Did you find solution? I also have the same problem – Sriteja Sugoor Jan 05 '21 at 13:46
-
@SritejaSugoor please find the below answer. Thanks – Kh An Sep 21 '21 at 10:13
1 Answers
2
For future readers: Below is the final script after many attempts, which takes full page screenshot from Webview. I have used ProgressWebView instead of Webview. You can use Webview if you want. This code works in functional components. Note: When the page is fully loaded then click on the Take Screenshot button
import React, { useState } from 'react';
import { View, Button } from 'react-native';
import { captureRef } from "react-native-view-shot";
import ProgressWebView from "react-native-progress-webview";
import json5 from 'json5'
import { Dimensions } from 'react-native';
const Report = () => {
const [componentHeight, setComponentHeight] = useState(0)
const [globalComponentHeight, setGlobalComponentHeight] = useState(0)
const [componentHeightFlex, setComponentHeightFlex] = useState(1)
let url = 'https://stackoverflow.com/questions/63708244/webview-full-page-screenshot-in-react-native'
let webview = null;
let count = 0
const injectJS = _ => {
const script = `
let method${count} = _ => {
let documentHeight = document.body.scrollHeight
let data = {componentHeight: documentHeight}
window.ReactNativeWebView.postMessage(JSON.stringify(data))
}
method${count}()`
webview.injectJavaScript(script)
count++
}
const takeScreenshot = _ => {
console.log(globalComponentHeight)
const {height} = Dimensions.get("window")
console.log(height)
if(globalComponentHeight <= height) setComponentHeight(height)
else setComponentHeight(globalComponentHeight)
setComponentHeightFlex(null)
setTimeout(_ => {
captureRef(webview, {
format: "png",
quality: 0.9,
result: "base64"
}).then(
_screenshot => {
console.log(_screenshot)
//First save your screenshot from _screenshot(base64 string). You can send base64 string to your server and save
//Then make the component default as below
setComponentHeight(0)
setComponentHeightFlex(1)
},
error => console.error("Oops, screenshot failed", error)
);
}, 100)
}
return (
<View style={{ marginTop: 40, flex: 1, display: 'flex' }}>
<Button mode='contained' onPress={takeScreenshot} title="Take Screenshot"/>
<View
style={{
height: componentHeight,
flex: componentHeightFlex
}}
>
<ProgressWebView
ref={ref => {
if (ref != null)
webview = ref
}}
bounces={false}
style={{ position: 'relative' }}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={true}
source={{ uri: url }}
startInLoadingState={true}
onLoad={e => injectJS()}
onMessage={e => {
let data = json5.parse(e.nativeEvent.data)
// console.log(data)
setGlobalComponentHeight(parseInt(data.componentHeight))
}}
></ProgressWebView>
</View>
</View>
);
}
export default Report

Kh An
- 481
- 6
- 13
-
Neither progressive web view nor a webview is a React component though, so the call fails. Only workaround that comes to my mind is to set the ref to the parent View, but that takes us back to capturing only the visible content, not the entire page. Any ideas? – DanDayne Mar 23 '23 at 23:31