Skip to content
Advertisement

Widen Image on scroll down using React

I want an image animation effect while scrolling using react.js, something similar to this : https://www.roche.com/ I have this code :

<ArticleWrapper >
        <img  className='image' src={Img} alt='Image' />
</ArticleWrapper >

I want the img to be widen animated while scrolling down and returns to normal when scrolling up ! Thanks.

Advertisement

Answer

One of the possible solutions with runnable example

This is one of the way to do that:

  • Wrap your <img> with a padded and flex-centered container
  • Give style width: 100% to your <img>, to fit the container
  • Give a padding to your container (to get your image small as you want it at start)
  • Setup a scroll listener
  • Compute a new padding value for your image container
  • Update the container with the new padding value

In the snippet i have 2 important variables:

  • maxPadding the padding value (higher = smaller img)
  • maxScrollFor100 the point (in px) where the scroll is complete (full size <img>)

Here we have the runnable snippet

const maxScrollFor100 = 250; // Y Scroll Point where the image should be 100% width
const maxPadding = 100; // Initial padding of the container 
const imgContainer = document.getElementById('img-container');

// Get a CSS horizontal padding string by value and optional css unit 
function getPaddingHz(hzPadding, sizeUnit = 'px' /* you can change it using any CSS unit */) {
  return '0 ' + hzPadding + sizeUnit;
}

// Set initial container padding
imgContainer.style.padding = getPaddingHz(maxPadding);

// Setup scroll listener
window.addEventListener('scroll', function(event) {

  // Get the current scrollY point
  const sY = window.scrollY; 
  
  // Get a padding percentage (we want 100% with 0 scroll and 0% with 250 or + scroll)
  const percent = 100 - (sY >= maxScrollFor100 ? 100 : sY / (maxScrollFor100 / 100));
  
  // Show the current zoom percentage.
  // console.log("Actual Percent Zoom", percent.toFixed(1));

  // Compute the new padding value
  const padding = maxPadding * (percent / 100);

  // Update the dom with the new padding for the image container
  imgContainer.style.padding = getPaddingHz(padding);
  
}, {passive: true})
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
<!-- I use padding only to simulate content above and below the image 
     It also makes the snippet testable from mobile.                  -->
<div style="padding: 150px 0 500px 0">
  <div id="img-container" class="flex-center">
    <img 
      width="100%"
      src="https://i.stack.imgur.com/IKDXM.jpg"  
    />
  </div>
</div>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement