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>