Dennis
Dennis

Reputation: 1975

Resize an image when window resized, centered and keep the aspect ratio on React/TS

I want to resize an image when window is resized. I want to center this image to the container div element. I also want to have padding on 4 sides. (top/left/bottom/right: 15% for example)

Live Demo: https://react-ts-f4jemk.stackblitz.io

Live Editor: https://stackblitz.com/edit/react-ts-f4jemk

This is how it should look like:

sample

When window resized, image should get bigger or smaller based on window size. In this case i want to keep aspect ratio and blank on top, left, bottom and right so that image is visible and centered on div.

What I tried so far:

 updateDimensions() {

    let imgHeight = this.state.imgHeight
    let imgWidth = this.state.imgWidthMax

    let w = window,
      d = document,
      documentElement = d.documentElement,
      body = d.getElementsByTagName('body')[0],
      width = w.innerWidth || documentElement.clientWidth || body.clientWidth,
      height = w.innerHeight || documentElement.clientHeight || body.clientHeight

    if (imgWidth && imgWidth > 0) {
      imgWidth = imgWidth + width - this.state.width
      imgHeight = imgHeight + height - this.state.height
      const ratioW = width / imgWidth
      const ratioH = height / imgHeight
      this.setState({ width: width, height: height, imgHeight, imgWidth })
      return
    }

    this.setState({ width: width, height: height, imgHeight, imgWidth })

  }
  componentWillMount() {
    this.updateDimensions()
  }
  componentDidMount() {
    window.addEventListener("resize", this.updateDimensions)
    setTimeout(() => {
      const imgHeight: number = this.imgEl.clientHeight
      const imgWidth: number = this.imgEl.clientWidth
      this.setState({ imgHeight, imgWidth, imgHeightMax: imgHeight, imgWidthMax: imgWidth })

    }, 1000)
  }
  componentWillUnmount() {
    window.removeEventListener("resize", this.updateDimensions)
  }

I also tried to do it via CSS-only. However, either width or height is getting larger then browser height/width.

.img {
   width: auto; // or 100%
   height: 100%; // or auto
}

My updateDimensions() works however, my calculations are wrong. How can i properly handle this situation? How can i calculate properly?

Upvotes: 2

Views: 4063

Answers (1)

Ramon Portela
Ramon Portela

Reputation: 409

I updated your function to resize the image based on its aspect ratio

  updateDimensions() {
    let w = window,
      d = document,
      documentElement = d.documentElement,
      body = d.getElementsByTagName("body")[0],
      inner = d.querySelector(".inner");

    //this calculates the padding %
    const height = inner.clientHeight - inner.clientHeight * 0.15;
    const width = inner.clientWidth - inner.clientWidth * 0.15;

    let imgWidth = width;
    //calculates hight base os aspect ratio
    let imgHeight = (imgWidth * height) / width;

    //if height is greater than the inner container, set the maximun size and recalculate width base on max-height
    if (imgHeight > height) {
      imgHeight = height;
      imgWidth = (imgHeight * width) / height;
    }

    this.setState({ width, height, imgWidth, imgHeight });
  }

Here is the updated code on the online editor: https://stackblitz.com/edit/react-ts-jbzynn?file=index.tsx

Upvotes: 1

Related Questions