I'm very new to React-Native and Javascript and have been trying to learn. I'm trying to set an image's width to the screen size divided by 10. I set up a constructor and a state with the screen width and height, but am unable to use the state to set the width or height of my image.
constructor(props) {
super(props);
const { width, height } = Dimensions.get("window")
this.state = {
width,
height
}
}
If I do this...
<Image source={require('./my-icon.png')} style={{width: {this.state.width}, height: 40}}/>
It gives me an error saying that 'this' is a reserved word.
I fixed it. I guess I made a dumb mistake. I removed the brackets and it worked.
<Image source={require('./my-icon.png')} style={{width: this.state.width/10, height: 40}}/>
Related
I want to click images to open a modal as image previews, so the modal has no margin and padding just shows one whole image preview.
But the problem I have is the image size...
Initially, after clicking the modal open button, I get the images' width and height and overwrite values for width and height.
But some images are 5000px width x 3000px height which is too big for a screen and I use this image preview for not only laptops but also iPad or bigger screens size.
How do you define the size of the image for different screen sizes?
Now the width and height values are fixed.
If the width is bigger than , I set width 800 px and height 500px.
If the height is bigger than width, I set width 500px and height 800px.
and style object-fit: cover but the chance is the image could be square...
const Attachment =() =>{
const [width, setWidth] = React.useState(0);
const [height, setHeight] = React.useState(0);
const handleOpenModal = () => {
setOpenModal(true);
getMeta(attachmentCdnUrl);
};
function getMeta(url) {
const img = new Image();
img.addEventListener('load', function () {
setWidth(800);
setHeight(500);
if (this.naturalWidth > this.naturalHeight) {
setWidth(800);
setHeight(500);
} else {
setHeight(800);
setWidth(500);
}
});
img.src = url;
}
return(
...
<Modal
open={openModal}
onClose={handleCloseModal}
aria-labelledby="child-modal-title"
aria-describedby="child-modal-description"
>
<Box
sx={{
...style, // here to overwrite width and height
width: width,
height: height,
}}
>
<img
src={attachmentCdnUrl} // here to overwrite width and height
style={{
...style,
width: width,
height: height,
}}
/>
</Box>
</Modal>
...
)
}
This code doesn't look exactly the same so just pasting this won't work.
I'm building a component in ReactJs that shows some text over a image in a page. This text is configured in a configuration manager app that is created with ReactJs too.
I am using vw (viewport width) as units, beacuse this component needs to be responsive. Using those units the size text is always fitted right. And if I resize the windows the text is in the same place.
My problem is the configuration manager where I configure the text that is going to appear, because I am making a preview of this component inside of modal window.
I need to locate correctly and exactly where the text will appear like if it were the orignal render. It needs to be like a minature of the real component.
I am using vw too, but it doesn't work. It appears in another site of the container and also when I resize the window the text moves too.
I tried to use vmin units, but they did not work too.
I need the container to take the reference as if it were the browser window so that the viewport width units use the same measurements like a preview.
Or if you have any other idea to do this.
This is a reduced part of the code in ReactJS. Also the state is charged with test data for understanding the problem
import React, { Component } from 'react';
import '../styles/main.scss';
class PreviewEditor extends Component {
constructor(props) {
super(props);
this.state = {
text: {
text: '',
fontSize: 2,
position: {
vertical: {
key: 'top',
value: 20
},
horizontal: {
key: 'right',
value: 10
}
}
}
}
}
render() {
let object = this.props;
return (
<div>
<div className='container-body'>
<div>
<div className="container-preview">
<img src={object.url}></img>
<div className="conteiner-text" style={{
[this.state.text.position.vertical.key]: this.state.text.position.vertical.value + "vw",
[this.state.text.position.horizontal.key]: this.state.text.position.horizontal.value + "vw",
fontSize: this.state.text.fontSize + "vw",
}}>
<label>{this.state.text.text}</label>
</div>
</div>
</div>
<div className="row">
............ TODO
</div>
</div>
</div>
);
}
}
export default PreviewEditor
And this the css part
.container-preview {
background-color: #2dc5c5;
width: 100%;
position: relative;
}
.container-preview > img{
max-width: 100%;
}
.conteiner-text{
display: inline-block;
position: absolute;
}
vw stands for viewport width, it aims at always setting size relative to the current viewport, no matter the container. If you just want size relative to container width you should rather user percentage sizes.
So, in your case, you could set each container width differently (using vw for the actual container and pixels for the preview, for example) and all their content sizes in percentage to always have the same ratio at different scales.
Our app includes a screen where there is a large circle in the background which changes position. It's mostly absolute positioning using this sort of style. The circle changes to use the right style and animates into the new position underneath some tutorial text.
const { height, width } = Dimensions.get('screen')
const circleRadius = isIphoneX() ? height * 0.55 : height * 0.60
export const styles = StyleSheet.create({
circleMassiveLeft: {
position: 'absolute',
backgroundColor: primary,
width: circleRadius * 2,
height: circleRadius * 2,
borderRadius: circleRadius,
left: -circleRadius + width - 50,
top: -circleRadius + height / 2
},
circleMassiveRight: {
position: 'absolute',
backgroundColor: primary,
width: circleRadius * 2,
height: circleRadius * 2,
borderRadius: circleRadius,
left: -circleRadius + 50,
top: -circleRadius + height / 2
}
})
This has been working great to display the circle in the correct position across multiple display sizes. Since it needs to be so precisely positioned, using absolute positioning seems to be a better solution than flex in this case. Our challenge is that when changing the system settings in Android to display size small, the circle becomes smaller. Of course, that makes sense in a way, but this particular element looks pretty awful because of the layout of the rest of the screen when it's resized to be smaller. Elements that used to be on top of it are now poking out! Is there a way to make sure that this element displays at the same size regardless of Android system display size settings? Poking around the docs, there doesn't seem to be a basic setting for this.
Try to use www.npmjs.com/package/react-native-responsive-dimensions
read this
In the article they using: react-native-size-matters
Im trying to set my header height so its responsive for tablets and smartphones. I've have tried using flex column:
const headerStyle = {
paddingHorizontal: theme.metrics.mainPadding,
paddingTop: 0,
paddingBottom: 0,
backgroundColor: theme.colors.blue,
flex: 0.5,
flexDirection: 'column',
};
However, the header looks ok on a tablet but too tall on a smartphone.
What is the best way to set dimensions for different devices?
EDIT:
I have this function:
export function em(value: number) {
return unit * value;
}
And I am now using it in my stylesheet:
headerHeight: em(6),
headerImageWidth: em(3),
headerImageHeight: em(3),
headerLogoHeight: em(6),
headerLogoWidth: em(20),
The image looks ok on tablet, but now on smartphone its too small. If i understand correctly, I need to use dimensions.width to set an appropriate unit value in my function?
Smartphone
Tablet
I can think of two ways
Using flex
<View style={{flex:1}}>
<View style={{flex:0.2}}>
<Text>Header</Text>
</View>
<View style={{flex:0.8}} />
</View>
You have mentioned using flex, but not working. I am not sure how exactly as if you are using it like above, size should be relative to screen size.
Using Dimensions
How about using the Dimensions module. It can be used to get the width and height of the window and you can set height based on that
import {
Dimensions
} from 'react-native';
const winWidth = Dimensions.get('window').width;
const winHeight = Dimensions.get('window').height;
header = {
height: winHeight * 0.2 // 20%
}
Then use width and height to set the height of the header (ex. percentage-based)
The trouble is that I need these images with generated IDs "cam_snap_XXX" to become a different width if they are dragged and dropped into this area. I can make the height change but NOT THE WIDTH because the width is designated to 20px if x==1. Never is the image height specified therefore I believe that is the reason it is changeable? Q: How can I make these image widths change from 20px to 100px if "dragged"?
while (cnt <= 100) {
cam_icon=document.getElementById('cam_snap_' + cnt);
cam_icon.style.visibility = 'hidden';
if (x==1) {
cam_icon.style.width = '20px';
cam_icon.style.visibility = 'visible';
}
cnt++;
}
The height changes from the following javascript...
//js for adding class "dragged" which gives new height and width image parameters
$('.droparea td.drop').droppable({
onDrag: function (e, source) {
$(this).addClass('dragged'); //Changes height correctly not width though.
}
}
And the css..
//css for attempting to change image width and height on drop
.dragged{
height: 100px; //Works because height stretches image height from ~20px to 100px.
width: 100px; //**Doesn't work and is useless because width remains 20px.**
}
Should I try removing the class before adding class 'dragged' to these images? Using removeClass()? Any ideas are welcome even if not the solution.
This part of javascript modifies your HTML
cam_icon.style.width = '20px';
cam_icon.style.visibility = 'visible';
to
<someTag id="cam_snap_x" style="width:20px;visibility:visible">
According to css rules inline style (inside an HTML element) has the highest priority. so you'll have to change attribute value to see changes in UI.
Solution 1: change your onDrag function like below.
$('.droparea td.drop').droppable({
onDrag: function (e, source) {
$(this).width(100).height(100); //This will change the style property
}
}
Solution 2: Use !important to prioritize value specified in class over inline style attribute
.dragged{
height: 100px;
width: 100px !important;
}