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:
maxPaddingthe padding value (higher = smaller img)maxScrollFor100the 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>