I have 3 elements with background images that I want to scale from x to 1. I want it to begin when the top of the element is just inside the viewport (this may vary a little).
I have achieved this effect the long way:
function animatePanelBackgrounds() {
var $toolsBG = $('#js-tools-bg'),
$dennysBG = $('#js-dennys-bg'),
$verizonBG = $('#js-verizon-bg'),
$llbeanBG = $('#js-llbean-bg');
var dennysTop = Math.floor( $("#js-dennys").offset().top );
var dennysGo = dennysTop - window.innerHeight;
var llbeanTop = Math.floor( $("#js-llbean").offset().top );
var llbeanGo = llbeanTop - window.innerHeight;
var verizonTop = Math.floor( $("#js-verizon").offset().top );
var verizonGo = verizonTop - window.innerHeight;
var toolsTop = Math.floor($toolsBG.offset().top);
var toolsGo = 0;
var ratio, $that;
if ( thisWindows.offsetY() >= toolsGo ) {
ratio = toolsTop/(thisWindows.offsetY()*10);
$that = $toolsBG;
$that.css({
"transform": "scale(" + (1.0 + thisWindows.offsetY()*.0002) + ")",
"-webkit-transform": "scale(" + (1.0 + thisWindows.offsetY()*.0002) + ")",
"-moz-transform": "scale(" + (1.0 + thisWindows.offsetY()*.0002) + ")"
})
}
if ( thisWindows.offsetY() >= dennysGo ) {
ratio = dennysTop/thisWindows.offsetY()*.8;
$that = $dennysBG;
if ( ratio <= 1 ) {
$that.css({
"transform": "scale(1)",
"-webkit-transform": "scale(1)",
"-moz-transform": "scale(1)"
})
} else {
$that.css({
"transform": "scale(" + ratio + ")",
"-webkit-transform": "scale(" + ratio + ")",
"-moz-transform": "scale(" + ratio + ")"
})
}
}
if ( thisWindows.offsetY() >= verizonGo ) {
ratio = verizonTop/thisWindows.offsetY()*.8;
$that = $verizonBG;
if ( ratio <= 1 ) {
$that.css({
"transform": "scale(1)",
"-webkit-transform": "scale(1)",
"-moz-transform": "scale(1)"
})
} else {
$that.css({
"transform": "scale(" + ratio + ")",
"-webkit-transform": "scale(" + ratio + ")",
"-moz-transform": "scale(" + ratio + ")"
})
}
}
if ( thisWindows.offsetY() >= llbeanGo ) {
ratio = llbeanTop/thisWindows.offsetY()*.8;
$that = $llbeanBG;
if ( ratio <= 1 ) {
$that.css({
"transform": "scale(1)",
"-webkit-transform": "scale(1)",
"-moz-transform": "scale(1)"
})
} else {
$that.css({
"transform": "scale(" + ratio + ")",
"-webkit-transform": "scale(" + ratio + ")",
"-moz-transform": "scale(" + ratio + ")"
})
}
}
}
$(window).on('scroll', function() {
animatePanelBackgrounds();
}
I have also achieved this with a function that take a couple simple parameters:
function scaleBackground(element, multiplier) {
var $el = $(element),
elTop = Math.floor( $el.offset().top),
startPosition = elTop - window.innerHeight;
$win.on('scroll', function() {
if(thisWindows.offsetY() >= startPosition) {
var ratio = elTop/thisWindows.offsetY()*multiplier;
if ( ratio <= 1 ) {
$el.css({
"transform": "scale(1)",
"-webkit-transform": "scale(1)",
"-moz-transform": "scale(1)"
})
} else {
$el.css({
"transform": "scale(" + ratio + ")",
"-webkit-transform": "scale(" + ratio + ")",
"-moz-transform": "scale(" + ratio + ")"
})
}
}
})
}
scaleBackground('#js-dennys-bg', '.8');
scaleBackground('#js-llbean-bg', '.8');
scaleBackground('#js-verizon-bg', '.8');
I feel like this should be handled in a loop of some sorts, but I haven't had any luck. Here's my basic attempt, I've tried tweaking little things in it along the way with 0 success:
var panels = $('.panel__bg');
for ( i = 0; i < panels.length; i++ ) {
var $that = $(panels[i]),
begin = $that.offset().top;
if ( begin <= window.scrollY ) {
var ratio = begin/(window.scrollY * 10);
if ( ratio <= 1 ) {
$that.css({
"transform": "scale(1)",
"-webkit-transform": "scale(1)",
"-moz-transform": "scale(1)"
})
} else {
$that.css({
"transform": "scale(" + ratio + ")",
"-webkit-transform": "scale(" + ratio + ")",
"-moz-transform": "scale(" + ratio + ")"
})
}
}
}
My question, finally, is simply: What is the best way to do this. By "best way", I am extremely concerned with performance and secondly concerned with readability/fewest lines of code.