Jquery transition Opacity based on var value - javascript

I am trying to animate an opacity value from 0 to 1, based on the scroll position within the viewport height. The code below sets variables for windowHeight and scrollTop, which can be combined to calculate percentageScrolled (0–100) of the viewport height. Based on this I am able to switch CSS values at set points, but instead I want to gradually change the opacity from 0–100 of percentageScrolled.
How can I adjust the code below to transition/animate the opacity?
Thanks.
$(window).on('scroll', function(){
// Vars
var windowHeight = $(window).height();
var scrollTop = $(this).scrollTop();
var percentageScrolled = (scrollTop*100)/windowHeight;
if( percentageScrolled < 100 ) {
$('.colour-overlay').css('opacity', '1');
} else {
$('.colour-overlay').css('opacity', '0');
}
});

You can remove the if and set the opacity to the percentage divided by 100
$(window).on('scroll', function() {
// Vars
var windowHeight = $(window).height();
var scrollTop = $(this).scrollTop();
$('.colour-overlay').css('opacity', scrollTop / windowHeight);
});
.colour-overlay {
display: block;
width: 20px;
height: 1200px;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="colour-overlay"></div>

$(‘.colour-overlay’).css(opacity, percentageScrolled / 100);
Instead of if else statement.
Also as a general advice try to avoid using var, use const or let instead and if your project doesnt depend on jquery try to avoid it too.
const overlays = document.querySelectorAll(‘.colour-overlay’);
window.addEventListener('scroll', () => {
const windowHeight = window.offsetHeight;
const scrollTop = window.scrollTop;
const percentageScrolled = (scrollTop * 100) / windowHeight;
for (const overlay of overlays) {
overlay.style.opacity = percentageScrolled / 100;
}
});
This would be the pure js solution.

Dont know if i understood you right, but a wrote an example have a look.
$(document).on('scroll', function(){
// Vars
// use body instead of window, body will return the right height where window will return the view size
var windowHeight = $("body").height();
var scrollTop = $(this).scrollTop();
var percentageScrolled = Math.abs((((scrollTop / windowHeight) * 100) / 100 ));
$('.colour-overlay').css('opacity', percentageScrolled);
});
.colour-overlay{
background:red;
height:1000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="colour-overlay"></div>

Related

Jquery add CSS class after 'X' amount of viewport height scrolled

So I have this jQuery function that adds / removes a CSS class to an element after 600px of the viewport height has been scrolled.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 600) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
I'd like to tweak it so instead of working based off a pixel value, it works off of the view height css measurement "VH", but the equivalent results are what matter in this case.
It can be done by getting the window height using $(window).height().
For instance suppose you have to scroll half the screen more (height is 150vh) and you have to detect when 40% has been scrolled:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 0.4 * $(window).height()) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
body{
margin: 0;
height: 150vh;
}
.cta_box {
height: 100%;
background: green;
}
.cta_box.fadeout {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cta_box"></div>
Use a percentage of the window height to compare
$(window).scroll(function() {
var height = $(window).height(),
scroll = $(window).scrollTop()
limit = 0.6; //implies 60 vh or 60% of viewport height
if (scroll >= height*limit) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
and even better would be to update some variable only when the window is resized to avoid computations all the time
var limit = 0.6, //implies 60 vh or 60% of viewport height
scrollLimit = 0;
$(window).resize(function(){
scrollLimit = $(window).height() * limit;
}).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= scrollLimit ) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
}).trigger('resize').trigger('scroll'); // trigger both events on start to force initial setup
Try something like this
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
For retrieveing the viewport Height, you could use $(window).innerHeight():
$(window).scroll(function() {
var scroll = $(window).innerHeight();
if (scroll >= 600) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
Hope this helps.
Leo.

Progressively adding opacity while scrolling

I am struggling with figuring out how to modify some existing code I have to replicate a feature I saw on a site. If you go to this site: , when you scroll down you will see the image gains opacity. My fiddle somewhat does this, but I cannot figure out how to apply a darker opacity and have the opacity progressively be added rather than all at once.
I know the level of opacity is being changed via the javascript, I am just not aware how to modify it to get the result I am after.
var scrollPosition = $(this).scrollTop();
var docHeight = $(document).height();
var diff = docHeight - scrollPosition;
console.log(scrollPosition);
$('#demolition1').css({'opacity':diff/docHeight});
Fiddle
<div id="home-main-img">
<img src="http:optimumwebdesigns.com/images/demolition1.jpg" alt="Demolition and Wrecking" id="demolition1">
</div>
<div class="height">
</div>
#home-main-img img{
width: 100%;
height: auto;
margin: 0;
display: block;
}
#home-main-img {
background: #000;
}
.height {
height:500px;
}
$(document).scroll(function(e){
var scrollPosition = $(this).scrollTop();
var docHeight = $(document).height();
var diff = docHeight - scrollPosition;
console.log(scrollPosition);
$('#demolition1').css({'opacity':diff/docHeight});
});
I think your mistake is setting diff against the doc height rather than the height of the item you want to fade out.
Your JS should be something like:
var $item = $('#demolition1');
$(document).scroll(function(e) {
var $this = $(this),
scrollPosition = $this.scrollTop(),
itemHeight = $item.height(),
diff = itemHeight - scrollPosition;
console.log(scrollPosition);
$item.css({'opacity': (diff/itemHeight) });
});
Here's a working JS Fiddle: https://jsfiddle.net/s6ta6bdc/
You can use image height, instead of document, to get the correct percentage of opacity
$(document).scroll(function(e){
var scrollPosition = $(this).scrollTop();
var imgHeight = $('#demolition1').height();
var diff = imgHeight - scrollPosition;
$('#demolition1').css({'opacity':diff/imgHeight});
});
try fiddle updated

opacity on scroll with jquery

I'm trying make the opacity of my div gradually increasing, as will moving the scroll, like this
$(document).ready(function() {
$(document).scroll(function(e) {
opacidade();
});
var element = $('#element');
var elementHeight = element.outerHeight();
function opacidade() {
var opacityPercent = window.scrollY / 100;
if (scrollPercent <= 1) {
element.css('opacity', opacityPercent);
}
}
});
is working but the opacity is uping very fast i find example decrease opacity but no uping upacity if in my rule css my div is declared opacity 0 any knwo how should be
Altered:
jsFiddle
$(document).ready(function() {
$(document).scroll(function(e){
opacidade();
});
var element = $('#element');
var elementHeight = element.outerHeight();
function opacidade(){
var opacityPercent = window.scrollY / $(document).height();
console.log(window.scrollY, opacityPercent);
element.css('opacity', opacityPercent);
}
});
The scrollY is a pixel value, so unless you limit your possible scroll range [0 - 100], there's no reason to divide it by 100.
So what you need is divide the scroll by the total document's height (or whatever it's parent that contains it and display a scrollbar)

Affix position not being recalculated on resize

I want to make my navbar become affixed when you scroll and it reaches the top even when you resize the window.
The position at which it's triggered is not updating even though I set it to recalculate the values when I $(window).resize(). What's wrong?
$(document).ready ->
$(window).resize ->
windowHeight = $(window).height()
navHeight = $('#navbar-affixable-wrapper > #navbar.affixable').outerHeight()
windowMinusNavHeight = windowHeight - navHeight
$('#navbar-affixable-wrapper > #navbar.affixable').affix
offset: { top: windowMinusNavHeight }
Or in javascript:
$(document).ready(function() {
return $(window).resize(function() {
var navHeight, windowHeight, windowMinusNavHeight;
windowHeight = $(window).height();
navHeight = $('#navbar-affixable-wrapper > #navbar.affixable').outerHeight();
windowMinusNavHeight = windowHeight - navHeight;
return $('#navbar-affixable-wrapper > #navbar.affixable').affix({
offset: {
top: windowMinusNavHeight
}
});
});
});
Can you return the offset top value as a function?
For example:
$(function(){
var $window = $( window );
var $navbar = $('#navbar-affixable-wrapper > #navbar.affixable');
$navbar.affix({
offset: {
top: function(){
// Calculate offset top value
return $window.height() - $navbar.outerHeight( true ); // I always pass true in there so margin is taken into consideration.
}
}
})
});
You can checkout the affix documentation on the Bootstrap website.

Get the visible height of a div with jQuery

I need to retrieve the visible height of a div within a scrollable area. I consider myself pretty decent with jQuery, but this is completely throwing me off.
Let's say I've got a red div within a black wrapper:
In the graphic above, the jQuery function would return 248, the visible portion of the div.
Once the user scrolls past the top of the div, as in the above graphic, it would report 296.
Now, once the user has scrolled past the div, it would again report 248.
Obviously my numbers aren't going to be as consistent and clear as they are in this demo, or I'd just hard code for those numbers.
I have a bit of a theory:
Get the height of the window
Get the height of the div
Get the initial offset of the div from the top of the window
Get the offset as the user scrolls.
If the offset is positive, it means the top of the div is still visible.
if it's negative, the top of the div has been eclipsed by the window. At this point, the div could either be taking up the whole height of the window, or the bottom of the div could be showing
If the bottom of the div is showing, figure out the gap between it and the bottom of the window.
It seems pretty simple, but I just can't wrap my head around it. I'll take another crack tomorrow morning; I just figured some of you geniuses might be able to help.
Thanks!
UPDATE: I figured this out on my own, but looks like one of the answers below is more elegant, so I'll be using that instead. For the curious, here's what I came up with:
$(document).ready(function() {
var windowHeight = $(window).height();
var overviewHeight = $("#overview").height();
var overviewStaticTop = $("#overview").offset().top;
var overviewScrollTop = overviewStaticTop - $(window).scrollTop();
var overviewStaticBottom = overviewStaticTop + $("#overview").height();
var overviewScrollBottom = windowHeight - (overviewStaticBottom - $(window).scrollTop());
var visibleArea;
if ((overviewHeight + overviewScrollTop) < windowHeight) {
// alert("bottom is showing!");
visibleArea = windowHeight - overviewScrollBottom;
// alert(visibleArea);
} else {
if (overviewScrollTop < 0) {
// alert("is full height");
visibleArea = windowHeight;
// alert(visibleArea);
} else {
// alert("top is showing");
visibleArea = windowHeight - overviewScrollTop;
// alert(visibleArea);
}
}
});
Calculate the amount of px an element (height) is in viewport
Fiddle demo
This tiny function will return the amount of px an element is visible in the (vertical) Viewport:
function inViewport($el) {
var elH = $el.outerHeight(),
H = $(window).height(),
r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom;
return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H));
}
Use like:
$(window).on("scroll resize", function(){
console.log( inViewport($('#elementID')) ); // n px in viewport
});
that's it.
jQuery .inViewport() Plugin
jsFiddle demo
from the above you can extract the logic and create a plugin like this one:
/**
* inViewport jQuery plugin by Roko C.B.
* http://stackoverflow.com/a/26831113/383904
* Returns a callback function with an argument holding
* the current amount of px an element is visible in viewport
* (The min returned value is 0 (element outside of viewport)
*/
;(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i,el) {
function visPx(){
var elH = $(el).outerHeight(),
H = $(win).height(),
r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
Use like:
$("selector").inViewport(function(px) {
console.log( px ); // `px` represents the amount of visible height
if(px > 0) {
// do this if element enters the viewport // px > 0
}else{
// do that if element exits the viewport // px = 0
}
}); // Here you can chain other jQuery methods to your selector
your selectors will dynamically listen to window scroll and resize but also return the initial value on DOM ready trough the first callback function argument px.
Here is a quick and dirty concept. It basically compares the offset().top of the element to the top of the window, and the offset().top + height() to the bottom of the window:
function getVisible() {
var $el = $('#foo'),
scrollTop = $(this).scrollTop(),
scrollBot = scrollTop + $(this).height(),
elTop = $el.offset().top,
elBottom = elTop + $el.outerHeight(),
visibleTop = elTop < scrollTop ? scrollTop : elTop,
visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
$('#notification').text(`Visible height of div: ${visibleBottom - visibleTop}px`);
}
$(window).on('scroll resize', getVisible).trigger('scroll');
html,
body {
margin: 100px 0;
}
#foo {
height: 1000px;
background-color: #C00;
width: 200px;
margin: 0 auto;
}
#notification {
position: fixed;
top: 0;
left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="foo"></div>
<div id="notification"></div>
The logic can be made more succinct if necessary, I've just declared separate variables for this example to make the calculation as clear as I can.
Here is a version of Rory's approach above, except written to function as a jQuery plugin. It may have more general applicability in that format. Great answer, Rory - thanks!
$.fn.visibleHeight = function() {
var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop;
scrollTop = $(window).scrollTop();
scrollBot = scrollTop + $(window).height();
elTop = this.offset().top;
elBottom = elTop + this.outerHeight();
visibleTop = elTop < scrollTop ? scrollTop : elTop;
visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
return visibleBottom - visibleTop
}
Can be called with the following:
$("#myDiv").visibleHeight();
jsFiddle
Here is the improved code for jquery function visibleHeight: $("#myDiv").visibleHeight();
$.fn.visibleHeight = function() {
var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop, height;
scrollTop = $(window).scrollTop();
scrollBot = scrollTop + $(window).height();
elTop = this.offset().top;
elBottom = elTop + this.outerHeight();
visibleTop = elTop < scrollTop ? scrollTop : elTop;
visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
height = visibleBottom - visibleTop;
return height > 0 ? height : 0;
}

Categories