Fade background to black on bottom of page - javascript

Im trying to fade in a DIV using opacity when the user gets close to the bottom of the page.
Let's say the page is 3000px high, i want the fade in to start at 2400px and end up completely faded in when the user hits the bottom.
Here is the function i use on the top, but i cant figure out the math i need to get the oposite effect on the bottom of the page...
useEffect(() => {
const handleScroll = event => {
const checkpoint = 500;
const start = 200;
let opacity;
const currentScroll = window.pageYOffset;
if (currentScroll >= start) {
if (currentScroll <= checkpoint) {
opacity = 1 - currentScroll / checkpoint;
} else {
opacity = 0;
}
} else {
opacity = 1 - currentScroll / checkpoint;
}
document.querySelector(".intro").style.opacity = opacity;
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
This is my try. But it does not work.
In short. My theory is to map the difference between the checkpoint variable 2400 and the height variable 3000 to a value between 0.0 and 1. Then assign it to the opacity of the Div. But sadly my head cant figure it out.
useEffect(() => {
const handleScroll = event => {
let opacity;
const height = document.documentElement.scrollHeight - window.innerHeight
const checkpoint = height - 700;
const currentScroll = window.scrollY;
// if (currentScroll >= start) {
if (currentScroll <= checkpoint) {
opacity = 0
console.log('if opacity: ',opacity)
} else {
opacity = currentScroll / checkpoint * 1;
console.log('else opacity: ',opacity)
}
document.querySelector(".footer").style.opacity = opacity;
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
Any help here would be greatly appreciated!
-R

Please check this code
import React, { useEffect, useState } from "react";
export default function App() {
const [currentScroll, setCurrentScroll] = useState(0);
window.onscroll = function (e) {
// console.log(window.scrollY);
setCurrentScroll(window.scrollY);
};
useEffect(() => {
console.log(currentScroll);
},
[currentScroll]
);
return (
<div>
<h1>Hello World</h1>
.....
</div>
);
}

GSAP ScrollTrigger example.
ScrollTrigger.create({ trigger: document.body, start: "top top", end: "bottom bottom", // onCallback function });

Related

How can I pass function as an argument in javascript?

I would like to create a sticky element that disappears when a certain div (bottles) get to bottom of the screen.
I have this code that works:
function update() {
const bottles = document.getElementById("bottles");
const rect = bottles.getBoundingClientRect();
const distance = window.innerHeight - rect.bottom; //value is 0 when bottom of bottles is at the bottom of screen
if (distance < 0) {
Array.from(document.getElementsByClassName("sticky-element")).forEach((el) => el.classList.remove("hidden"));
} else {
Array.from(document.getElementsByClassName("sticky-element")).forEach((el) => el.classList.add("hidden"));
}
}
document.addEventListener('scroll', update);
update();
However this is not the best code and it's going to be part of AB testing so the distances would have to be different. Therefore I tried to do something like this but it doesn't work:
function update(distance) {
if (distance < 0) {
Array.from(document.getElementsByClassName("sticky-element")).forEach((el) => el.classList.remove("hidden"));
} else {
Array.from(document.getElementsByClassName("sticky-element")).forEach((el) => el.classList.add("hidden"));
}
}
In case of the option A:
function elementDistance() {
const bottles = document.getElementById("bottles");
const rect = bottles.getBoundingClientRect();
const distance = window.innerHeight - rect.bottom; //value is 0 when bottom of bottles is at the bottom of screen
return distance;
}
document.addEventListener('scroll', update);
document.addEventListener('scroll', elementDistance);
update(elementDistance);
In case of the option B:
function elementDistance() {
const distance = some other values
return distance;
}
document.addEventListener('scroll', update);
document.addEventListener('scroll', elementDistance);
update(elementDistance);

How to expand the video container smoothly as it comes to viewport in Nuxtjs

I have to make a webpage very similar to this one. I'm using Nuxt for this, I'm facing issues in making the video expand & shrink in the exact same way.
I've tried to replicate the issue on StackBlitz here. The directive is not working correctly actually. I want to achieve exactly the same transition as soon as the video enters into the view-port.
Code of the custom directive -
export default {
directives: {
inView: {
isLiteral: true,
inserted: (el, binding, _) => {
const isInView = () => {
const rect = el.getBoundingClientRect();
const inView = (rect.width > 0 && rect.height > 0 && rect.top >= 0 &&
(rect.bottom + 100) <= (window.innerHeight || document.documentElement.clientHeight));
if (inView) {
el.classList.add(binding.value);
// window.removeEventListener('scroll', isInView);
} else {
el.classList.remove(binding.value);
}
};
window.addEventListener('scroll', isInView);
isInView();
}
}
}
}
Instead of a scroll listener, use an IntersectionObserver to track when the element comes in or out of view. The following observer creates an IntersectionObserver with a 30% threshold, adding the binding.arg value as a CSS class to the element when in view:
export default {
directives: {
inView: {
mounted(el, binding) {
const threshold = 0.3 // trigger callback when element is 30% in view
const observer = new IntersectionObserver(entries => {
const elem = entries[0]
if (elem.intersectionRatio >= threshold) {
el.classList.add(binding.arg);
} else {
el.classList.remove(binding.arg);
}
}, { threshold })
observer.observe(el)
binding.instance.observer = observer
},
unmounted(el, binding) {
binding.instance.observer.disconnect()
},
}
},
}
Then use the directive on the video-wrapper element to animate (where scale is the animating class):
<div v-in-view:scale class="video-wrapper">
demo

How to add fade transitions in between state changes

I have this component that every time I change the value of the state I want it to fade between the different colors rather than change straight away how do I do this?
const Header = (props) => {
const [headerColor, setHeaderColor] = useState('#c8e9e6');
useEffect(() => {
document.addEventListener("scroll", () => {
console.log(window.scrollY);
if (window.scrollY < 700) {
setHeaderColor('#c8e9e6');
} else if (window.scrollY >= 700 && window.scrollY < 1500) {
setHeaderColor('#ffae5a');
} else if (window.scrollY >= 500) {
setHeaderColor('#b48fff');
}
});
});
return (
<div className={classes.HeaderContainer} style={{
backgroundColor: headerColor,
}```);
}
You can probably just add a css class the transition by using the property transition & -webkit-transition
For example set the colour to orange after 2 seconds:
.transaition{
background-color: #ffae5a;
-webkit-transition: background-color 2s; /* For Safari 3.1 to 6.0 */
transition: background-color 2s;
}

How to stop click event on resize & load if screen width is greater than?

I am facing this problem over and over again and just don't know how to solve this. I have a click event that I would like to fire only if the screen width is less than **576px* and if a page is loaded to make this event fire.
But when I resize the browser larger than 576px the click event still works.
Can someone please help me out how can I solve this common issue that I am facing?
Thanks in advance.
My code:
const onSearchMobile = () => {
let screenWidth = window.innerWidth;
let searchIcon = document.querySelector('.main-header__search--icon');
if (screenWidth <= 576) {
console.log('Yes lower then 576');
searchIcon.addEventListener('click', () => {
console.log('clicked!');
});
}
};
window.addEventListener('resize', onSearchMobile, false);
window.addEventListener('load', onSearchMobile);
Just check the width inside event
const onSearchMobile = () => {
let screenWidth = window.innerWidth;
let searchIcon = document.querySelector('.main-header__search--icon');
searchIcon.addEventListener('click', () => {
if (screenWidth <= 576) {
console.log('clicked!');
}
});
};
window.addEventListener('resize', onSearchMobile, false);
window.addEventListener('load', onSearchMobile);
Using MediaQueryList.onchange
let searchIcon = document.querySelector('.main-header__search--icon')
let clickListener = () => console.log('clicked!')
let mql = window.matchMedia('(max-width: 576px)')
mql.addEventListener("change", (e) => {
if (e.matches) {
searchIcon.addEventListener('click', clickListener)
} else {
searchIcon.removeEventListener('click', clickListener)
}
})
You can remove eventListener:
const onSearchMobile = () => {
let screenWidth = window.innerWidth;
let searchIcon = document.querySelector('.main-header__search--icon');
if (screenWidth <= 576) {
console.log('Yes lower then 576');
searchIcon.addEventListener('click', () => {
console.log('clicked!');
});
}
else {
searchIcon.removeEventListener('click');
}
};
window.addEventListener('resize', onSearchMobile, false);
window.addEventListener('load', onSearchMobile);

If scrolled 300 px change background color

I have a fixed nav that is grey. But I want it to change colour to white if you have scrolled 300 px.
Demo: http://eldecosmetics.com/blogs/vemund
Password: Pruget
Use this code:
window.addEventListener('scroll', function () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var nav = document.getElementById('scroll-nav');
if (scrollTop >= 300) {
nav.style.backgroundColor = 'grey';
} else {
nav.style.backgroundColor = '#f9f7f1';
}
}, false);
window.addEventListener("scroll", function(event) {
var top = this.scrollY;
if(top > 300) {
// Do Something
}
else {
// Rollback to previous state?
}
}, false);
You can do it like that

Categories