Here is a sample code sandbox for this issue.
Things I want to do is
1, Click open modal button to open the modal.
2, This opened modal shows a whole image. (No margin, padding just want to show the whole image itself)
So I need to get image width and height that is different based on which images get passed.
Right now, I can get width and height like this.
function getMeta(url) {
const img = new Image();
img.addEventListener("load", function () {
console.log(this.naturalWidth + " " + this.naturalHeight);
setWidth(this.naturalWidth);
setHeight(this.naturalHeight);
});
img.src = url;
}
To execute this function like this
getMeta("https://cdn.pixabay.com/photo/2022/03/08/07/08/water-7055153_1280.jpg");
But I don't know how to set width and height to Box component dynamically.
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 500, // this needs dynamic
height: 500, // this needs dynamic
bgcolor: "background.paper",
boxShadow: 24,
p: 4
};
export default function BasicModal() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
getMeta(
"https://cdn.pixabay.com/photo/2022/03/08/07/08/water-7055153_1280.jpg"
);
};
const handleClose = () => setOpen(false);
const [width, setWidth] = React.useState(0);
console.log("width", width);
const [height, setHeight] = React.useState(0);
console.log("height", height);
function getMeta(url) {
const img = new Image();
img.addEventListener("load", function () {
console.log(this.naturalWidth + " " + this.naturalHeight);
setWidth(this.naturalWidth);
setHeight(this.naturalHeight);
});
img.src = url;
}
return (
<div>
<Button onClick={handleOpen}>Open modal</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<div>This is an image</div>
</Box>
</Modal>
</div>
);
}
Attempts
I thought I could simply use setState for width and height
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: width, // changed
height: height, // changed
bgcolor: "background.paper",
boxShadow: 24,
p: 4
};
export default function BasicModal() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
getMeta(
"https://cdn.pixabay.com/photo/2022/03/08/07/08/water-7055153_1280.jpg"
);
};
const [width, setWidth] = React.useState(0);
const [height, setHeight] = React.useState(0);
function getMeta(url) {
const img = new Image();
img.addEventListener("load", function () {
console.log(this.naturalWidth + " " + this.naturalHeight);
setWidth(this.naturalWidth); // set width
setHeight(this.naturalHeight); // set height
});
img.src = url;
}
...
But this didn't work.
Attempt2
This kind works. I use makeStyles but I'm just wondering why I need two variables for styling.
const useStyles = makeStyles({
root: (props) => ({
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: props.width, // this needs dynamic
height: props.height, // this needs dynamic
bgcolor: "background.paper",
boxShadow: 24
})
});
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 500, // this needs dynamic
height: 500, // this needs dynamic
bgcolor: "background.paper",
boxShadow: 24
};
.
.
.
return (
<div>
<Button onClick={handleOpen}>Open modal</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box
sx={style} // here
className={classes.root} // here
component="img"
src="https://cdn.pixabay.com/photo/2022/06/13/15/36/grain-7260250__340.jpg"
></Box>
</Modal>
</div>
);
It seems like I need both useStyles and style. If I remove one of them, it starts broking the style.
Here is the code for this at the moment.