How to resize react native webview content? - react-native

This is my code, I'm trying to load a stream from my IP camera.
<View style={{flex:1,marginTop:70, flexDirection:'column', justifyContent:'space-between'}}>
<Hue/>
<View style={{flex:1}}>
<WebView
source={{uri: 'http://192.168.2.6:81/videostream.cgi?user=admin&pwd=XXXXX'}}
style={{/*marginTop: 20, flex: 1, width:450, height:100*/}}
javaScriptEnabled={false}
domStorageEnabled={false}
startInLoadingState={false}
scalesPageToFit={false}
scrollEnabled={true}
/>
</View>
<Text>Just some text</Text>
</View>
<Hue/> is a component to check if the WebView is still loading (because in a normal case, it won't load if it's not the only component).
The width property have an ambiguous behavior: reducing it increase the height of the webview. Leaving an empty scrolling space.
Moreover, modifying the height of the webview component does nothing at all.
I tried to modify the parent view applying height and width with no luck.
Also, I did not find any props to modify the webview content itself.
Is there any way, or a react-native component that can help me to integrate my IP camera stream in my application ?
Any suggestion is very appreciated.
EDIT
Updated the code according to Ashwin's comment and I still get this :
EDIT 2
I updated my code according to sfratini answer but if I set the scroll enabled and then scroll, I'm able so see that there is always a part of the image not displayed. Seems that react does not understand to resize to 100%.. It's strange...

<WebView
source={{
uri: this.props.url
}}
style={{ height: height, width, resizeMode: 'cover', flex: 1 }}
injectedJavaScript={`const meta = document.createElement('meta'); meta.setAttribute('content', 'width=width, initial-scale=0.5, maximum-scale=0.5, user-scalable=2.0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta); `}
scalesPageToFit={false}
onLoadEnd={this._onLoadEnd}
/>

Managed to get the same behavior for ios and Android. Thanks Gowtham Palanisamy.
<WebView
source={{ uri: url }}
style={{ flex: 1 }}
injectedJavaScript={`
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
if (!iOS) {
const meta = document.createElement('meta');
let initialScale = 1;
if(screen.width <= 800) {
initialScale = ((screen.width / window.innerWidth) + 0.1).toFixed(2);
}
const content = 'width=device-width, initial-scale=' + initialScale ;
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', content);
document.getElementsByTagName('head')[0].appendChild(meta);
}
`}
scalesPageToFit={Platform.OS === 'ios'}
/>

just a note that webview has standard style and also containerStyle see documentation. standard style i believe has background: white, and containerStyle has flex: 1.
To make an image responsive, i made my code like this (iframeWidth is just window width dimension minus some padding):
if (node.name === 'img') {
const imgHeight = Number(node.attribs.height);
const imgAlt = node.attribs.alt;
const imgSource = node.attribs.src;
const imageHtml = `<img src="${imgSource}" height="${
imgHeight * 2.3
}" alt="${imgAlt}" />`;
return (
<WebView
key={index}
source={{ html: imageHtml }}
startInLoadingState
scalesPageToFit
allowsInlineMediaPlayback
domStorageEnabled
style={{ backgroundColor: 'transparent' }}
containerStyle={[{ flex: 0, width: iFrameWidth, height: imgHeight }]}
/>
);
}
Hope this helps to someone!

Using Gowtham Palanisamy's approach, set the source content as an html input and set its viewport to render content inside parent container.
<View>
<WebView
javaScriptEnabled={false}
domStorageEnabled={false}
startInLoadingState={false}
scalesPageToFit={false}
scrollEnabled={true}
source={{
html: `
<head>
<meta content="width=width, initial-scale=1, maximum-scale=1" name="viewport"></meta>
</head>
<body style="background-image: url('${this.props.source}'); background-size:cover;"></body>
`,
}}
/>
</View>

This is is more better and accurate
style={{ height: 350, width: '100%', resizeMode: 'cover', flex: 1 }}
injectedJavaScript={`const meta = document.createElement('meta'); meta.setAttribute('content', 'width=width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta); `}
scalesPageToFit={true}

I believe you want this:
<WebView
source={this.props.source}
style={{
width: '100%',
height: 300
}}
scrollEnabled={false}
/>;

Related

SVG getting cut in react native

I am using react-native-svg with react-native-svg-transformer for rendering SVGs in our app. All SVGs are rendering correctly except this one SVG which just cuts off at its right side. This is the rendered SVG (The right side of the svg is cutoff):
and this is the original svg which I want to render as it is:
I don't know what I am doing wrong, but I also tried using the viewBox prop, still no effect. How can I rectify this?
Code:
import YourEldercarePartner from '../../Assets/Images/WelcomeScreenSVGImages/Your-Eldercare-Partner.svg';
const data = [
...
{
heading: "Welcome to Emoha!",
svg: {
image: YourEldercarePartner,
width: hp(40),
height: hp(40)
},
message: "India’s largest virtual community of Elders. This app is your one-stop solution for everything Elders need to live a healthy and energized life in the comfort of home."
},
...
];
return (
<Swiper
ref={swiper}
loop={false}
onIndexChanged={index => setIndex(index)}
showsButtons={false}
showsPagination={true}
renderPagination={handlePagination}
>
{
data.map((datum, idx) => <Screen datum={datum} key={idx}/> )
}
</Swiper>
)
const Screen = ({ datum }) => (
<View style={styles.container}>
<View style={styles.main}>
<Text style={styles.heading}>
{datum.heading}
</Text>
<View style={{ marginTop: 10, flex: 10, justifyContent: 'flex-start' }}>
<datum.svg.image
width={datum.svg.width}
height={datum.svg.height}
/>
</View>
<Text style={styles.message}>
{datum.message}
</Text>
</View>
</View>
)
Kind of late, but had similar problem and it was because svg width was actually smaller than mask width inside svg.
For example:
<svg width="261" height="251" viewBox="0 0 261 251" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask1_11005_24077" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="7" y="0" width="251" height="251">
Here mask width was accidentally 251 and after changing to 261 it was fixed and image not cut anymore. Don't see your svg anymore so I don't know if this was case for you, but was for me with multiple images.

is there any way to learn uri has no image react-native

I am developing a e-commerce app and some products does not have pictures and because of that sometimes ımage components looks empty. It looks bad. (To get pictures i am using uri.)
My question is how can i know if there isn't a picture on that uri?
<FastImage
source={{
uri: photoUri,
priority: FastImage.priority.high,
}}
style={styles.logo}
/>
You can try react-native-elements, it will show PlaceholderImage when uri error
import { Image as ImageElement } from 'react-native-elements'
import { Image } from 'react-native'
<ImageElement
style={{ width: 100, height: 100 }}
source={{ uri: reduceImageSize(item.image, width) }}
PlaceholderContent={(
<Image source={require('image-placeholder.png')} style={{ width: 100, height: 100 }} />
)}
/>

How to change the resolution of a video (React-Native)

Basically title, i'm trying to change the resolution of the videos because they are too heavy, i'm using react-native-video to display the videos and i saw that it has a selectedVideoTrack which can be used to change it but it is not working for me. could i be using it wrong?
<Video
selectedVideoTrack={{
type: "resolution",
value: 240
}}
resizeMode = "stretch"
source={{ uri: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4' }}
style={{ width: 300, height: 300 }}
controls={true}
ref={(ref) => {
this.player = ref
}} />

Map in react-native-webview, How to zoom?

I put a map in a webview using react-native-webview this way :
<WebView
geolocationEnabled={true}
source={{
uri:
"https://www.blablabla",
}}
originWhitelist={[
"https://www.blavla.org",
"https://www.blabla.com",
]}
style={{ marginHorizontal: 0, backgroundColor: "transparent" }}
/>
Giving me this :
But as you see, it's not really clear, I'd like to zoom to have a better reading of the map (it's too small this way we can't read anything). How can I do that please ?
Thanks for any help !!! :)
Your site has page width set in meta already
So you will need to override that with injectedJavaScript
injectedJavaScript={`const meta = document.createElement('meta');
meta.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-
scale=0.5, user-scalable=0'); meta.setAttribute('name', 'viewport');
document.getElementsByTagName('head')[0].appendChild(meta); `}
scalesPageToFit={false}

My Text input is resizing automatically when i clicked on it

render() {
return (
<View style={{flex:1,flexDirection:'column',justifyContent:'space-evenly',alignItems:'center',backgroundColor:datum.secondaryColor}}>
<TextInput
placeholderTextColor={datum.secondaryColor}
style={{
height: '7%', borderColor:datum.primaryColor, borderWidth: 1,
width:'50%',backgroundColor:datum.primaryColor, fontWeight: '200'
}}
onChangeText={(value) => this.setState({name:value})}
placeholder="Name"
/>
<TextInput
placeholderTextColor={datum.secondaryColor}
style={{height: '7%', borderColor:datum.primaryColor, borderWidth: 1,width:'50%',backgroundColor:datum.primaryColor, fontWeight: '200'}}
onChangeText={(value) => this.setState({number:value})}
placeholder="Mobile no"
/>
<Button
onPress={()=>this.signupPressed()
}
title="Signup"
color={datum.primaryColor}
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
}
actually, I am designing a simple form page, I am struggling while handling keyboard, Yes I have also seen react native docs, in that they have suggested me to use Keyboardavoiding view but that makes the layout even worse so, can anyone tell how to handle the issue
Im think the virtual keyboard is affecting your width and height, instead of using percentages for your width and height, you can try using dimensions:
var windowWidth = Dimensions.get('window').width;
var windowHeight = Dimensions.get('window').height;
width: width * 0.5
height: height * 0.07