on scroll div gradually fadein fadeout - javascript

I am trying to creating fadein fadeout effect with scrolling but not figure out how . it is like http://www.popsci.com/ . There If scroll then background image (div id fixed-image ) get fading. Them code something like. But I cannot figure out yet how to easily apply in my code. Would guys please check it my code .
var opacity = 1;
var img = element.find('img');
// Look for featured stories.
if (element.length > 0) {
// Attach background image element.
$('#page-wrapper').prepend('<div id="fixed-image" style="background-image: url(\'' + img.attr('data-lgsrc') + '\');"></div>');
img.addClass('hidden');
var scrollPercent;
$(window).scroll(function() {
// When User scrolls down, determine percentage from top to bottom of window.
scrollPercent = (($(window).scrollTop() / $(window).height() * 1.9) - 0.9);
if (scrollPercent < 0) {
$('#fixed-image').css({
'-webkit-filter' : 'blur(0px)',
'-moz-filter' : 'blur(0px)',
'-o-filter' : 'blur(0px)',
'-ms-filter' : 'blur(0px)',
'filter' : 'blur(0px)'
});
}
var opacityCount = 1.5 - Math.min(1.5, (scrollPercent + 1));
$('#fixed-image').css('opacity', opacityCount);
if (scrollPercent <= 1) {
$('#fixed-image').css('opacity', opacityCount);
$('#fixed-image').css({
'-webkit-filter' : 'blur(' + scrollPercent * 10 + 'px)',
'-moz-filter' : 'blur(' + scrollPercent * 10 + 'px)',
'-o-filter' : 'blur(' + scrollPercent * 10 + 'px)',
'-ms-filter' : 'blur(' + scrollPercent * 10 + 'px)',
'filter' : 'blur(' + scrollPercent * 10 + 'px)'
});
}
else {
$('.content-wrapper-outer').css('background-color', 'rgba(255,255,255,' + opacity + ')');
my demo is here https://jsfiddle.net/cyber007/6e6dbr6j/1/
i want slider class will be fadeIn and fadeout gradually base on scrolling
UPDATE
$(window).scroll(function(){
$(".slider").css("opacity", 1 - $(window).scrollTop() / 250);
});
https://jsfiddle.net/cyber007/6e6dbr6j/2/ this one work fine. jus one minor think in console i saw that opacity value keep running after 0 even going - value. i don't think after value 0 no need down value more

Here's a function to clip opacity at 0, although according to MDN: "Any value outside the interval [0 to 1], though valid, is clamped to the nearest limit in the range," so it's not strictly necessary.
$(window).scroll(function(){
var opacity = 1 - $(window).scrollTop() / 250;
if (opacity < 0 ) opacity = 0;
$(".slider").css("opacity", opacity);
});
UPDATE
For arbitrary start and end of your transition, use the linear equation , like so:
$(window).scroll(function(){
var start = 200, end = 600;
var opacity = 1 - ($(window).scrollTop() - start) / (end - start);
if (opacity > 1 ) opacity = 1;
if (opacity < 0 ) opacity = 0;
$(".slider").css("opacity", opacity);
});
Here's a JSFiddle.

Related

Hide image after certain amount scrolled

I’ve been successful using the code below to hide the element on scroll, but I need to tweak it so it changes opacity after the user scrolls 80vh:
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
$('.image123').css({
opacity: function() {
var elementHeight = $(this).height(),
opacity = ((elementHeight - scrollTop) / elementHeight);
return opacity;
}
});
});
Try this:
$(window).scroll(function () {
var vh = (document.documentElement.clientHeight * 80) / 100;//80vh to px
var scrollTop = $(this).scrollTop();
var current = parseFloat($('.image123').css('opacity'));
var opacity = Math.min(Math.max((scrollTop >= vh ? current - 0.1 : current + 0.1), 0), 1);
$('.image123').css({opacity: opacity});
});

How can I make my div spawn within 400 px of either side using jquery?

I'm making an animated background for a webpage that spawn div elements to look like bubbles and animates their transparency. I want the bubbles to only spawn within the left 400px and the right 400px of the screen. I can get them to spawn in the middle, but when I try to make it spawn on the edges it breaks the code. (maybe an infinite loop?)
function bubble() {
var rightOffset = $(window).width() - 400; //where i want them on the right
do {
var leftPx = Math.floor(Math.random() * $(window).width() - 100);
} while (leftPx >= 400 || rightOffset <= leftPx);
var topPx = Math.floor(Math.random() * $(window).height() - 100); //not even going to worry about the top yet
if(bubbleCount <= 30){
bubbleCount ++;
$('html').append("<div class=bubble style=' left: " + leftPx + "px; top: " + topPx + "px;'></div>");
$('.bubble').animate({
opacity: 0.5,
}, 3000, 'swing')
.animate({
opacity: 0,
}, 3000, 'swing', function(){
$(this).remove();
bubbleCount -= 1;
});
}
}
Why not simply randomize the side as well? This way you don't have to check and discard potential positions. Something like this.
function randomBetween(min,max) {
return Math.floor(Math.random()*(max-min+1)+min);
}
var width = $(window).width();
var leftPixels = Math.round(Math.random()) ? randomBetween(0, 400) :
randomBetween(width - 400, width);
What happens here is that it first randomly generates 0 or 1, and then if it's 1 it generates a LEFT side value and if 0 generates a RIGHT side value. No extra iterations that slow down your program.
I reproduced your bubble effect and didn't end up with a break in code!
I think what you are missing is that for an absolute-positioned bubble to be positioned from right, you need to give it a right CSS offset value; likewise, for a left absolute-positioned bubble, stick to the left property:
var rightOffset = $(window).width() - 400; //where i want them on the right
do {
var rightPx = Math.floor(Math.random() * $(window).width() - 100);
} while (rightPx >= 400 || rightOffset <= rightPx);
/*
* ...
*/
$('html').append("<div class='bubble' style=' right: " + rightPx + "px; top: " + topPx + "px;'></div>");

JQuery animate background positions in multiple divs on scroll

I have multiple divs on my page where I want to animate their background position onScroll, so here is what I have got for now
/* animate background possition on scroll */
$(window).scroll(function() {
var y = $(this).scrollTop();
if(y < $(".page-separator").offset().top && ( $(".page-separator").offset().top ) < ( y + $(window).height() ) ){
$(this).css('background-position', '0% ' + parseInt(-y / 10) + 'px');
}
});
But it doesn't work. I think it is because $(this)is not currently visible $(".page-separator") , can you please help me to fix it?
So I have modified my code here but I am stacked again, I can't pass parameter into .each jquery function
$(window).scroll(function() {
var y = $(window).scrollTop();
$(".page-separator").each(function(y){
//$(".page-separator").css('background-position', '0% ' + parseInt(-y / 10) + 'px');
if( y < $(this).offset().top && ( $(this).offset().top ) < ( y + $(window).height() ) ){
$(this).css('background-position', '0% ' + parseInt(-y / 10) + 'px');
}console.log(y);
});
});
when I see console.log(y) it only shows 0 1 2 nothing more, not the top position
To change the background-position of the visible .page-separator elements, you'd do :
$(window).on('scroll', function() {
var y = $(window).scrollTop();
$(".page-separator").filter(function() {
return $(this).offset().top < (y + $(window).height()) &&
$(this).offset().top + $(this).height() > y;
}).css('background-position', '0px ' + parseInt(-y / 10) + 'px');
});
FIDDLE
$(this) == $(window) in this case. You should add one class (ex: 'animate') for all divs, and use it as selector (ex: $('.animate'))

Refactor JS Function

I have this ugly chunk of code which is responsible for positioning some sub-navigation on a website and I want some opinion on how I could improve it, because even I admit it's ugly as hell :)
Maybe someone has a better structuring idea, because I don't due to the complex logic :
positionSubItems : function() {
var $that = $(this),
$parent = $that.parents().eq(1),
$elements = $parent.find(' > li'),
$activeElements = $parent.find(' > li.active'),
$container = $that.parent().find(".expandedViewContainer"),
highestBoundary = $($elements[0]).offset().top - $($elements[0]).outerHeight(true),
lowestBoundary = $($elements[$elements.length - 1]).offset().top + $($elements[$elements.length - 1]).outerHeight(true),
containerHeight = $container.outerHeight(true),
elementHeight = $that.outerHeight(true),
returnIndex = function(selector) {
return $(selector).parent().index();
};
if($that.data().subItemsPositioned !== true) {
$container.css({
'margin-top' : - ( containerHeight / 2 + (elementHeight / 2) )
});
if((lowestBoundary - highestBoundary) <= containerHeight) {
$container.css({
'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0))
});
}
if($container.offset().top < highestBoundary) {
$container.css({
'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)))
});
if((lowestBoundary - highestBoundary) < containerHeight) {
$container.css({
'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0))
});
}
}
if(($container.offset().top + containerHeight) >= lowestBoundary) {
$container.css({
'margin-top' : - ( containerHeight - (elementHeight * ($elements.length - returnIndex($that))) )
});
if((lowestBoundary - highestBoundary) <= containerHeight) {
$container.css({
'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0))
});
}
}
$that.data().subItemsPositioned = true;
}
}
So just let me briefly explain what it does. Let's say we have a left vertical navigation ( a vertical list of li ). In those lis we have a link and another div which also contains another list of items. So what this function need's to do it's position this sub level of lis according to some rules :
there are two boundaries, one upper which corresponds to the most upper 'li' item on the first level plus it's own height, and the other one lower which corresponds to the most low li on the first level plus it's own height
the first condition would be that always position the sub items, which are held by a container and displayed to the right of the parent li, so the parent it's shown in the middle of that container
based on the above rule, if the offset of the resulted positioning of the container exceeds the upper boundary, then reposition the container so the top offset of the container it's now at the same level as the upper boundary
continuing to click on the rest of the items follow the first rule, apply the second one if it's the case, then if this following condition it's meet apply it : when the offset of the bottom of the container exceeds the lowest boundary, reposition it so the bottom of the container it's always at the same level as the lowest boundary
after going through all of the above rules and conditions you also have to check if the height of the container is bigger than the height between the upper and lower boundary, in that case apply the first rule, position the container at the same level as the upper boundary
there is also another scenario encountered, if there are to few parent lis and the height of the container now exceeds the height of the height between boundaries again, so we'll have to apply the just above mentioned rule
and there is another scenario which I won't describe as I'm already to deep into details
So stating the above, I hope someone has a better way of doing all the logic and maybe a more cleaner way too :)
Without testing if the underlying logic makes sense, this is slightly easier to read in my opinion
if(!$that.data().subItemsPositioned) {
var offset=0;
var ulOuterHeight = (elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0);
switch(true) {
case (lowestBoundary - highestBoundary) <= containerHeight :
offset = ulOuterHeight;
break;
case $container.offset().top < highestBoundary :
if((lowestBoundary - highestBoundary) < containerHeight) {
offset = ulOuterHeight;
}
else offset = (elementHeight * 2) + (elementHeight * returnIndex($that))
break;
case ($container.offset().top + containerHeight) >= lowestBoundary :
if((lowestBoundary - highestBoundary) <= containerHeight) {
offset = ulOuterHeight;
}
else offset = containerHeight - (elementHeight * ($elements.length - returnIndex($that)));
break;
default: offset = containerHeight/2 + (elementHeight/2);
}
$container.css({'margin-top' : - offset });
$that.data().subItemsPositioned = true;
}
here is some kind of example (without exactly reading what your function does, just some refactorings to dry this function a little bit up
this is still some kind of ugly but i hope it helps to push you into the right direction
positionSubItems : function() {
var $that = $(this),
$parent = $that.parents().eq(1),
$elements = $parent.find(' > li'),
$activeElements = $parent.find(' > li.active'),
$container = $that.parent().find(".expandedViewContainer"),
highestBoundary = $($elements[0]).offset().top - $($elements[0]).outerHeight(true),
lowestBoundary = $($elements[$elements.length - 1]).offset().top + $($elements[$elements.length - 1]).outerHeight(true),
containerHeight = $container.outerHeight(true),
elementHeight = $that.outerHeight(true),
returnIndex = function(selector) {
return $(selector).parent().index();
},
containerCSS = function(marginTop) {
$container.css({
'margin-top' : - marginTop
});
},
doTheMarginTop = function() {
containerCSS((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0));
};
if($that.data().subItemsPositioned !== true) {
containerCSS(containerHeight / 2 + (elementHeight / 2));
if((lowestBoundary - highestBoundary) <= containerHeight) {
doTheMarginTop();
}
if($container.offset().top < highestBoundary) {
containerCSS(((elementHeight * 2) + (elementHeight * returnIndex($that))));
if((lowestBoundary - highestBoundary) < containerHeight) {
doTheMarginTop();
}
}
if(($container.offset().top + containerHeight) >= lowestBoundary) {
containerCSS( containerHeight - (elementHeight * ($elements.length - returnIndex($that))) );
if((lowestBoundary - highestBoundary) <= containerHeight) { doTheMarginTop(); }
}
$that.data().subItemsPositioned = true;
}
}
this piece of code seems to be always the same, try to put that out of the if conditions (probably into a function):
$container.css({
'margin-top' : - ((elementHeight * 2) + (elementHeight * returnIndex($that)) + ($activeElements.find(" > ul").outerHeight(true) || 0))
});
i think that should be a good point to start. look for lines of code which are duplicate

Lightweight scrollUp function - jQuery

Trying to make simple jQuery function to create a scrollToTop button that fades in as you scroll down.
$(document).ready(function() {
var start = 300;
var duration = 200;
var scrolled;
$('.scrollUp').css('opacity', '0.0');
$(window).scroll(function(){
var opacity = (scrolled - start) / duration;
scrolled = $(window).scrollTop();
if (0 < opacity < 1) {
$('.scrollUp').css('display', 'block').css('opacity', opacity);
} else if (1 < opacity) {
$('.scrollUp').css('display', 'block').css('opacity', '1.0');
} else {
$('.scrollUp').css('display', 'none').css('opacity', '0.0');
}
});
$('.scrollUp').click(function(){
$('html, body').animate({
scrollTop: 0
}, 500);
});
});
See it in action here: http://jsfiddle.net/JamesKyle/fBvGH/
This works, tested in jsfiddle:
$(document).ready(function() {
var start = 300;
var duration = 200;
var scrolled;
$('.scrollUp').css('opacity', '0.0');
$(window).scroll(function(){
var opacity = (scrolled - start) / duration;
scrolled = $(window).scrollTop();
if (0 < opacity < 1) {
$('.scrollUp').css('display', 'block').css('opacity', opacity);
} else if (1 < opacity) {
$('.scrollUp').css('display', 'block').css('opacity', '1.0');
} else {
$('.scrollUp').css('display', 'none').css('opacity', '0.0');
}
});
$('.scrollUp').click(function(){
$('html,body').animate({
scrollTop: 0
}, 500);
});
});
Update:
And here's a working example with the opacity animation.
Looks like this guy was looking for the same equation.
Better to use some math in situation's like this:
scrolled = $(window).scrollTop();
height = $('body').height();
height = Math.ceil((scrolled / height) * 100);
height = height / 100;
Second Update
Ok, you want it to start appearing after the dark blue section. Ok, so what you need to do is exclude that portion of the top before the gradient. You can do that by making an if clause that checks if the scrollTop value has hit the top part of the light blue gradient; around 300px from the top of the document. Then instead of using the body height in the above equation, use the total height of the gradient section; about 210px. This value will replace the var height in the jQuery above. Let me know if you have issues implementing this. Didn't notice you're comment on the above answer.
scrollTop is not a window property, so just change you code slightly:
$(window).animate({scrollTop : 0},500);
to
$('html, body').animate({scrollTop : 0},500);
here's the updated jsfiddle: http://jsfiddle.net/fBvGH/13/

Categories