Reputation: 2901
I would like to progressively change the background color 3 times.
For example, I want it to gradually go from blue to grey to purple. Currently, the background transitions as expected from blue to grey.
Trying to illustrate it:
= Blue
==
===
====
===== Grey
====
===
==
= Purple
Could someone please help me make it go from grey to purple after the first transition please?
$(document).ready(function(){
var scroll_pos = 0;
var animation_begin_pos = 0;
var animation_mid_pos = 500;
var animation_end_pos = 1000;
var beginning_color = new $.Color( 'rgb(0,156,243)' );
var middle_color = new $.Color( 'rgb(36,40,47)' );
var ending_color = new $.Color( 'rgb(97,20,204)' );
$(document).scroll(function() {
scroll_pos = $(this).scrollTop();
if( scroll_pos >= animation_begin_pos && scroll_pos < animation_mid_pos ) {
var percentScrolled = scroll_pos / ( animation_mid_pos - animation_begin_pos );
var newRed = beginning_color.red() + ( ( middle_color.red() - beginning_color.red() ) * percentScrolled );
var newGreen = beginning_color.green() + ( ( middle_color.green() - beginning_color.green() ) * percentScrolled );
var newBlue = beginning_color.blue() + ( ( middle_color.blue() - beginning_color.blue() ) * percentScrolled );
var newColor = new $.Color( newRed, newGreen, newBlue );
$('body').animate({ backgroundColor: newColor }, 0);
// messes up starting here
} else if ( scroll_pos >= animation_mid_pos && scroll_pos <= animation_end_pos ) {
scroll_ps = $(document).height() - $(this).scrollTop() - $(this).height();
var percentScrolled = scroll_pos / ( animation_end_pos - animation_mid_pos );
var newRed = middle_color.red() + ( ( ending_color.red() - middle_color.red() ) * percentScrolled );
var newGreen = middle_color.green() + ( ( ending_color.green() - middle_color.green() ) * percentScrolled );
var newBlue = middle_color.blue() + ( ( ending_color.blue() - middle_color.blue() ) * percentScrolled );
var newColor = new $.Color( newRed, newGreen, newBlue );
$('body').animate({ backgroundColor: newColor }, 0);
} else if ( scroll_pos > animation_end_pos ) {
$('body').animate({ backgroundColor: ending_color }, 0);
} else if ( scroll_pos < animation_begin_pos ) {
$('body').animate({ backgroundColor: beginning_color }, 0);
} else { }
});
});
Upvotes: 1
Views: 630
Reputation: 475
Created a function so that it would work with any amount of listed colors as long as they have an ordered stop value between 0 and 1.
var colorList = [
{
color: new $.Color('rgb(0,156,243)'),
stop: 0
}, {
color: new $.Color('rgb(36,40,47)'),
stop: 0.25
}, {
color: new $.Color('rgb(97,20,204)'),
stop: 0.5
}, {
color: new $.Color('rgb(36,40,47)'),
stop: 0.75
}, {
color: new $.Color('rgb(0,156,243)'),
stop: 1
}
];
function getGradientColor(colorList, percent)
{
percent = 0 || percent;
if (colorList.length < 1)
{
return new $.Color();
}
for (var n = colorList.length - 1; n > 0; n--)
{
if (percent >= colorList[n].stop) { break; }
}
if (n > colorList.length - 2)
{
n = colorList.length - 2;
f = 1;
}
var f = Math.min((percent - colorList[n].stop) / (colorList[n+1].stop - colorList[n].stop), 1);
var color1 = colorList[n].color;
var color2 = colorList[n+1].color;
return new $.Color(
Math.floor(color1.red()*(1-f) + color2.red()*f),
Math.floor(color1.green()*(1-f) + color2.green()*f),
Math.floor(color1.blue()*(1-f) + color2.blue()*f)
);
}
$(document).scroll(function() {
var scrollPosition = $(this).scrollTop();
var height = $('.tall').outerHeight();
var body_height = $(window).height();
// Ensure no divide by 0
var percent = (height > 0 ? scrollPosition / (height - body_height) : 0);
$("body").css("background", getGradientColor(colorList, percent));
}).trigger("scroll");
https://jsfiddle.net/fse62fpd/
Upvotes: 1
Reputation: 6787
The easiest way would be, if you calculated the scroll position into a number in range from 0 to 1 and have your colors in a list.
With that you can then calculate which two colors to pick (colors[n]
and colors[n+1]
) and how much you need to mix them (color1*(1-f)+color2*f
).
// list of colors
var colors = [
new $.Color('rgb(0,156,243)'),
new $.Color('rgb(36,40,47)'),
new $.Color('rgb(97,20,204)')
];
$(document).scroll(function() {
// calculate scroll position 0-1
var scroll_pos = $(document).scrollTop();
var height = $(document).outerHeight();
var body_height = $(window).height();
var pos = scroll_pos/(height-body_height);
// calculate which colors to pick and how much to mix them
pos *= colors.length-1;
var n = Math.floor(pos);
var f = pos % 1;
// prevent getting out of bounds color pick
if (n > colors.length-2)
{
n = colors.length-2
f = 1
}
// pick colors
var color1 = colors[n]
var color2 = colors[n+1];
// mix the two colors
var color = new $.Color(
Math.floor(color1.red()*(1-f) + color2.red()*f),
Math.floor(color1.green()*(1-f) + color2.green()*f),
Math.floor(color1.blue()*(1-f) + color2.blue()*f)
);
// set the background color
$("body").css("background", color);
});
Upvotes: 1