I would like a zoom out effect for my header, what loads zoomed in, and on scroll it zoom out.
What I do is to increase the size with transform: scale(1.4) and on scroll I calculate a percentage from the scrollTop and header height and I multiply it with 0.4. The problem is that on scroll the screen starts to vibrate, the scale isn't smooth. Do you have any idea what's wrong with my code or can you tell me what's the best practice to achieve this?
jQuery(document).ready(function(){
function zoom_out() {
var page_header_height = jQuery('#page-header-custom').outerHeight();
var scroll_top = jQuery(window).scrollTop();
var zoom_multiplier = 0.4;
var multiplier = (zoom_multiplier*(1-((scroll_top-jQuery('#page-header-custom').offset().top)/page_header_height))) > 1 ? 1 : (zoom_multiplier*(1-((scroll_top-jQuery('#page-header-custom').offset().top)/page_header_height)));
if(multiplier <= 1) {
jQuery('#page-header-inner').stop(true, true).transition({ scale: 1/(1+multiplier), translate: '0, -50%' });
jQuery('#page-header-custom').stop(true, true).transition({
scale: 1+multiplier
});
}
}
zoom_out();
jQuery(window).on('scroll', function(){
zoom_out();
});
});
I created a JSFiddle to see it in action.
I've updated your Fiddle with smooth scaling using window.requestAnimationFrame
. The scale animation is vibrating because you're triggering a translation on each scroll
event. Think about it like this:
zoom_out()
gets triggered and tells an element to transition it's transform
properties. Your element is now transitioning at a certain speed: "length" / transitiontime.scroll
events have passed and are all triggering zoom_out()
. The next transition will probably happen at a different speed, resulting in 'vibrating' animation.First you can get rid of jQuery's transition()
method. If you fire the function at 60fps or close to 60fps it will appear to animate smoothly to the human eye, without the need of transitioning or animating.
if(multiplier <= 1) {
//jQuery('#page-header-inner').stop(true, true).transition({ scale: 1/(1+multiplier), translate: '0, -50%' });
//jQuery('#page-header-custom').stop(true, true).transition({ scale: 1+multiplier });
//becomes:
jQuery('#page-header-inner').css({ scale: 1/(1+multiplier), translate: '0, -50%' });
jQuery('#page-header-custom').css({ scale: 1+multiplier });
}
}
Getting the function triggered at ~60fps can be achieved in multiple ways:
Throttle your scroll event to 60fps.
Or use window.requestAnimationFrame like in the updated Fiddle
function zoom_out(){
//calculation code & setting CSS
window.requestAnimationFrame(zoom_out);
}
//trigger it once instead of the scroll event handler
window.requestAnimationFrame(zoom_out);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With