Reputation: 2059
I have 4 sections
, each section
height = 100vh.
And a function
that prints True
to the console
when reaching a half section height before section2
, till section2
bottom reaches the top
of the page (which means scrolling over it).
Animate an element
with jQuery this way:
x
will start as 1 and ends at 2, vice versa, in 10 steps, each step is 0.1
if (true) {
$(element).css({
transform: "scale(x)",
}, 500, 'easeInOutSine');
}
else {
$(element).css({
transform: "scale(x)",
}, 500, 'easeInOutSine');
}
So I have to convert the height
of scrolling (number) from the start to the end, into a 10 step, every 1/10
of scrolling it adds 0.1
.
In math, it looks like this (without the other half of section1):
var section = $(".section2");
var section_height = section.height();
var one_of_ten = section_height / 10;
var count = 0;
var x = 1;
while(x <= 2){
count = 0;
while(count <= one_of_ten){
count++;
}
x+=0.1;
}
It prints to the console
the numbers from 1 to 2 in 10 steps.
How can I get the height of the scrolling part and check for every 1/10 step to add 0.1 to x?
function check_onscroll(){
var section = $(".section2");
var sectionHeight = section.height();
var sectionTop = section.offset().top;
$(window).scroll(function () {
var scrollFromTop = $(window).scrollTop();
if (sectionTop - ($(window).height() / 2) <= scrollFromTop
&& scrollFromTop <= sectionTop + section.height()){
console.log("True");
}
});
}
check_onscroll();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
height: auto;
}
.section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.section1 {
background-color: red;
}
.section2 {
background-color: yellow;
}
.section3 {
background-color: green;
}
.section4 {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section section1">
<h2>Section 1</h2>
</div>
<div class="section section2">
<h2>Section 2</h2>
</div>
<div class="section section3">
<h2>Section 3</h2>
</div>
<div class="section section4">
<h2>Section 4</h2>
</div>
Upvotes: 3
Views: 586
Reputation: 36624
I'm not sure what it is that you want to scale, so this snippet scales the h2 element depending on how much of its section is in view. If less than 50% is in view then it's still at scale 1. For each 10th of the remaining (i.e. half) section it increases the scale.
We use intersectionObserver to do this for us as it will tell us the ratio of the section that is in view.
First we create an intersectionObserver, telling it to observe when an element is 50% within the viewport and then every 1/10th of the remainder thereafter.
Then we ask the observer to observe each section.
When a section is observed coming into the viewport by 50% or 55% or 60% ... up to .. 100% then we scale its h2 element by 1 plus this amount (i.e. between 0 and 1).
If you console.log the ratios in the observer callback function you will see that they are not always exactly 0.1 or 0.2 etc but they are fractions which show how much of the half element is actually in view. Using these values rather than calculating an x+ 0.1 gives a more accurate picture of how much scrolling has been done so the results are smoother.
(note, there didn't seem to be much of a use for jquery in this snippet so it has been dropped)
let callback = (entries, observer) => {
//taken from MDN documentation:
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
entry.target.querySelector('h2').style.transform = 'scale(' + (1+entry.intersectionRatio) + ')';
});
};
let options = {
threshold: [ 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00]
}
let observer = new IntersectionObserver(callback, options);
const sections = document.querySelectorAll('.section');
sections.forEach(section => { observer.observe(section, options);});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
height: auto;
}
.section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.section1 {
background-color: red;
}
.section2 {
background-color: yellow;
}
.section3 {
background-color: green;
}
.section4 {
background-color: blue;
}
<div class="section section1">
<h2>Section 1</h2>
</div>
<div class="section section2">
<h2>Section 2</h2>
</div>
<div class="section section3">
<h2>Section 3</h2>
</div>
<div class="section section4">
<h2>Section 4</h2>
</div>
Upvotes: 2
Reputation: 3819
You can listen the scroll
event and get the current scrollTop()
to see where the user scroll are at. Then do the math.
Something like the below:
var section = $(".section2");
var sectionHeight = section.height();
var sectionTop = section.offset().top;
function check_onscroll(){
var scrollFromTop = $(window).scrollTop();
if (sectionTop - ($(window).height() / 2) <= scrollFromTop
&& scrollFromTop <= sectionTop + section.height()){
curHalfPosition = scrollFromTop - (sectionTop / 2);
curPace = (sectionHeight / 2) / 10;
scale = parseInt(curHalfPosition / curPace);
scale_section (section, scale);
}
}
function scale_section(element, scale)
{
scale = (10 + scale) / 10;
if (scale > 2 && scale < 1) return;
$(element[0]).css({
transform: "scale("+scale+")",
}, 500, 'easeInOutSine');
}
$(window).scroll(check_onscroll);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
height: auto;
}
.section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.section1 {
background-color: red;
}
.section2 {
background-color: yellow;
}
.section3 {
background-color: green;
}
.section4 {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section section1">
<h2>Section 1</h2>
</div>
<div class="section section2">
<h2>Section 2</h2>
</div>
<div class="section section3">
<h2>Section 3</h2>
</div>
<div class="section section4">
<h2>Section 4</h2>
</div>
Upvotes: 0