Snap to scroll in scroll stop - javascript

Find below image reference:
What I want exactly is when only one section (section4) comes in window view around 40% - 80%. On scroll stop the section4 should auto scroll to fit on window.
Here, The basic fiddle without any script.
body,
html {
height: 100%;
margin: 0;
}
.sections {
height: 100%;
background: #000;
opacity: 0.7;
}
#section2 {
background: #ccc;
}
#section3 {
background: #9c0;
}
#section4 {
background: #999;
}
#section4 {
background: #ddd;
}
<div class="sections" id="section1"></div>
<div class="sections" id="section2"></div>
<div class="sections" id="section3"></div>
<div class="sections" id="section4"></div>
<div class="sections" id="section5"></div>
I have tried jquery visible plugin but it didn't help. So I have put commented one.
/*
var ww = $(window).width();
$(window).scroll(function(){
if ($('#section3').visible(true)) {
$('body, html').animate({scrollTop: $('#section4').offset().top});
}else if($('#section5').visible(true)) {
$('body, html').animate({scrollTop: $('#section4').offset().top});
}
});
*/

Use script to compare the scrollTop of the screen with the offset().top and the height of the section.
Note that ratio determines how much the element is seen on the screen (greater that 0.6 is used to determine if more than 60% of the section is visible on screen).
See demo below with comments inline:
/*debouce (courtesy:underscore.js)*/
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
// scroll listener
$(window).scroll(debounce(function() {
var $window = $(window);
// change this to '.sections' if you want the effect for all sections
$('#section4').each(function() {
var top_of_element = $(this).offset().top;
var bottom_of_element = $(this).offset().top + $(this).outerHeight();
var bottom_of_screen = $window.scrollTop() + $window.height();
var top_of_screen = $window.scrollTop();
var height_of_element = $(this).outerHeight();
// if element below top of screen
if (top_of_element > top_of_screen && bottom_of_screen < bottom_of_element) {
var ratio = (bottom_of_screen - top_of_element) / height_of_element;
if (ratio > 0.6) {
// animate by scrolling up
$('body, html').animate({
scrollTop: $(this).offset().top
});
}
}
// if element above top of screen
else if (bottom_of_element > top_of_screen && bottom_of_screen > bottom_of_element) {
var ratio = (bottom_of_element - top_of_screen) / height_of_element;
if (ratio > 0.6) {
// animate by scrolling down
$('body, html').animate({
scrollTop: $(this).offset().top
});
}
}
});
}, 250));
body,
html {
height: 100%;
margin: 0;
}
.sections {
height: 100%;
background: #000;
opacity: 0.7;
}
#section2 {
background: #ccc;
}
#section3 {
background: #9c0;
}
#section4 {
background: #999;
}
#section4 {
background: #ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sections" id="section1"></div>
<div class="sections" id="section2"></div>
<div class="sections" id="section3"></div>
<div class="sections" id="section4"></div>
<div class="sections" id="section5"></div>

Related

jQuery.scrollSpeed script won't let me scroll at all

I've been trying to get a smooth scrolling system using this jQuery script
Including version 1.0 only allows me to scroll up
Version 1.0.1 is the same
And version 1.0.2 prevents me from scrolling at all.
Can someone show me how to include it in a webpage? I've tried copying code from this codepen but have had no success.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
// Custom scrolling speed with jQuery
// Source: github.com/ByNathan/jQuery.scrollSpeed
// Version: 1.0
(function($) {
jQuery.scrollSpeed = function(step, speed) {
var $document = $(document),
$window = $(window),
$body = $('html, body'),
viewport = $window.height(),
top = 0,
scroll = false;
if (window.navigator.msPointerEnabled)
return false;
$window.on('mousewheel DOMMouseScroll', function(e) {
scroll = true;
if (e.originalEvent.wheelDeltaY < 0 || e.originalEvent.detail > 0)
top = (top + viewport) >= $document.height() ? top : top += step;
if (e.originalEvent.wheelDeltaY > 0 || e.originalEvent.detail < 0)
top = top <= 0 ? 0 : top -= step;
$body.stop().animate({
scrollTop: top
}, speed, 'default', function() {
scroll = false;
});
return false;
}).on('scroll', function() {
if (!scroll) top = $window.scrollTop();
}).on('resize', function() {
viewport = $window.height();
});
};
jQuery.easing.default = function(x, t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
};
})(jQuery);
</script>
<script>
jQuery.scrollSpeed(200, 800)
</script>
<style>
h1 {
font-family: 'Open Sans', sans-serif;
position: fixed;
top: 50%;
width: 100%;
text-align: center;
color: white;
text-shadow: 3px 3px 8px black;
}
#section1,
#section2,
#section3,
#section4 {
min-height: 800px;
}
#section1 {
background: royalblue;
}
#section2 {
background: gold;
}
#section3 {
background: purple;
}
#section4 {
background: teal;
}
</style>
</head>
<body style="">
<h1>Smooth Mouse Scroll</h1>
<div id="section1"></div>
<div id="section2"></div>
<div id="section3"></div>
<div id="section4"></div>
My current code
Fixed by adding
<!DOCTYPE html> to top of index.html

Making sections stick to top by adding class

I am trying to create a page where as each section reaches the top of the window, it will add a sticky class to the element to it becomes fixed to the top of the page.
I am trying to make the end result look like a bunch of pages that come up and stay at the top of the window
This is my code so far:-
$(document).ready(function(){
var stickyTopSection = $('.home, .about, .gallery, .contact').offset().top;
var stickyTop = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyTopSection) {
$(this).addClass('sticky');
} else {
$(this).removeClass('sticky');
}
};
stickyTop();
$(window).scroll(function() {
stickyTop();
});
});
.home, .about, .gallery, .contact{
height: 100vh;
width: 100%;
}
.sticky{
position: fixed;
top: 0;
left: 0;
}
.home{
z-index: 1;
background-color: #fff;
}
.about{
z-index: 2;
background-color: #eee;
}
.gallery{
z-index: 3;
background-color: #ddd;
}
.contact{
z-index: 4;
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<header id="home" class="home">
<h1>Welcome</h1>
</header>
<section id="about" class="about">
<h2>About</h2>
</section>
<section id="gallery" class="gallery">
<h2>Gallery</h2>
</section>
<section id="contact" class="contact">
<h2>Contact</h2>
</section>
You need to check each element individually, and what you have won't do that. Try this...
var stickyTopSections = $('.home, .about, .gallery, .contact');
var stickyTop = function() {
var scrollTop = $(window).scrollTop();
stickyTopSections.each(function() {
var $this = $(this);
if (scrollTop > $this.offset().top) {
$this.addClass('sticky');
}
else {
$this.removeClass('sticky');
}
});
};
stickyTop();
$(window).scroll(function() {
stickyTop();
});
stickyTopSections is a collection of elements, so each has to be parsed individually, hence the use of .each().
Consider using position: sticky, it's designed to solve this exactly problem. Support of it is quite good, but if it's not enough you could youse this great polyfill.
i have try with this other jQuery, is this what you need ?
function isElementInViewport (el) {
//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
$(document).on("scroll", function() {
//console.log("onscroll event fired...");
// check if the anchor elements are visible
$(".common").each(function (idx, el) {
var scrollTop = $(window).scrollTop();
if ( isElementInViewport(el) ) {
// update the URL hash
$(this).addClass('sticky');
}
else {
$(this).removeClass('sticky');
}
});
});
.common {
width:100%;
height:100vh;
}
.home {
background:#666;
}
.about {
background:#999;
}
.gallery {
background:#990;
}
.contact {
background:#06C;
}
<div class="home common"></div>
<div class="about common"></div>
<div class="gallery common"></div>
<div class="contact common"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Combine different animations with Skrollr.js for one element

I have the following structure of my page:
<div id="skrollr-body">
<div class="sections-container" id="sections-portrait">
<div class="section" id="section_1">
Section 1
<div class="baloon"
data-anchor-target="#section_1 .baloon"
data-center-top="bottom: -20%"
data-top="bottom: 50%"
></div>
</div>
<div class="section" id="section_2">
Section 2
</div>
<div class="section" id="section_3">
Section 3
</div>
<div class="section" id="section_4">
Section 4
</div>
</div>
<div class="sections-container" id="sections-landscape"></div>
Notice the div with class baloon. I want it to go from bottom to top (which it currently does), and after a while go a little bit down. Is it possible to do it with Skrollr.js and if it is - how?
Here's Demo CodePen DEMO
Well i haven't use Skrollr.js plugin but tried without it jQuery and Css
As Section is Shown after few second Baloon is moved from bottom to top and middle
Debounce on scroll and webtransitionend src
Function from David Walsh:
transitionEnd Callback
Debounce on wheel
debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
// Function from David Walsh: http://davidwalsh.name/css-animation-callback
function whichTransitionEvent() {
var t,
el = document.createElement("fakeelement");
var transitions = {
"transition": "transitionend",
"OTransition": "oTransitionEnd",
"MozTransition": "transitionend",
"WebkitTransition": "webkitTransitionEnd"
}
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}
var transitionEvent = whichTransitionEvent();
var winH = $(window).height();
$(document).ready(function() {
$('.section').height(winH);
var updateLay = debounce(function(e) {
callback(e);
}, 500);
$(window).on('wheel DOMMouseScroll', function(e) {
updateLay(e);
});
obj.textTransiton();
animLoop();
})
var globalSetting = {
y: 0,
delta: 0,
maxScroll: 0,
moved: false
}
function callback(event) {
var delta = Math.sign(event.originalEvent.wheelDelta) || -Math.sign(event.originalEvent.detail);
globalSetting.y += delta * winH;
globalSetting.delta = delta;
obj.move(obj.textTransiton);
}
function checkScrollExtents() {
if (globalSetting.y > 0) {
globalSetting.y = 0;
} else if (Math.abs(globalSetting.y) > globalSetting.maxScroll) {
globalSetting.y = -globalSetting.maxScroll;
}
}
function animLoop() {
globalSetting.maxScroll = obj.selector.height() - obj.selector.find('.section:last').height();
checkScrollExtents();
obj.scrolls();
window.requestAnimationFrame(animLoop);
}
var obj = {
'selector': $('#skrollr-body'),
'current': $('.current'),
scrolls: function() {
obj.vertical();
},
vertical: function() {
obj.selector.css('transform', 'translateY(' + globalSetting.y + 'px)');
},
textTransiton: function() {
var baloon = obj.current.find('.baloon');
baloon.css('transform', 'translateY(-' + winH + 'px)');
baloon.one(transitionEvent, function(event) {
baloon.css('transform', 'translateY(-' + (winH / 2) + 'px)');
});
},
move: function(callback) {
if (globalSetting.delta > 0) {
obj.Prev(callback);
} else {
obj.Next(callback);
}
},
Prev: function(c) {
if (obj.current.prev().length) {
var currt = obj.current.prev();
obj.updateCurrentModule(currt);
setTimeout(function() {
c();
}, 1000);
}
},
Next: function(c) {
if (obj.current.next().length) {
var currt = obj.current.next();
obj.updateCurrentModule(currt);
setTimeout(function() {
c();
}, 1000);
}
},
updateCurrentModule: function(currt) {
obj.current.removeClass('current');
obj.current.find('.baloon').css({
"-webkit-transform": "translateY(0px)"
});
currt.addClass('current');
obj.current = currt;
},
};
html,
body {
margin: 0;
overflow: hidden;
}
div {
transition: all 600ms ease-in !important;
}
.section {
position: relative;
color: white;
background-size: contain;
min-height: 100%;
white-space: nowrap;
position: relative;
min-width: 100%;
}
.baloon {
font-size: 10em;
color: #020000;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
bottom: 0px;
position: absolute;
margin: 0;
transition: all 1000ms cubic-bezier(0.32, 0.51, 0.78, 0.34) !important;
border: 1px solid;
background-color: white;
mix-blend-mode: exclusion;
width: 100%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="skrollr-body">
<div class="sections-container" id="sections-portrait">
<div class="section current" id="section_1" style="background-image: url(http://img13.deviantart.net/83ee/i/2014/145/5/e/naruto_negative_space_poster_by_jde_studios-d7jrnhc.jpg);">
<div class="baloon">
Naruto
</div>
</div>
<div class="section" id="section_2" style="background-image: url(http://www.jeffreydavidson.com.au/images/blogs/naruto-negative-space-posters/sasuke-negative-space.jpg);">
<div class="baloon">
Sasuke
</div>
</div>
<div class="section" id="section_3" style="background-image: url(https://s-media-cache-ak0.pinimg.com/736x/2f/2f/ef/2f2fefdccc4688ab3d640b65cca02d47.jpg);">
<div class="baloon">
Kakashi
</div>
</div>
<div class="section" id="section_4" style="background-image: url(http://www.jeffreydavidson.com.au/images/blogs/naruto-negative-space-posters/sakura-negative-space.jpg);">
<div class="baloon">
Sakura
</div>
</div>
</div>
<div class="sections-container" id="sections-landscape"></div>
</div>

Prevent shaking on hard scroll while animating scrollTop

I am scrolling section to section, but if I scroll harshly with the mouse (not just one easy scroll) or I scroll harshly on the laptop touchpad, it shakes up and down before the scrolling animation starts or even jumps 2 sections!
Is it possible to make it scroll smoothly and always one section only (not jump 2 sections) regardless of how hard someone scrolls and basically disable scrolling while the animation is taking place?
My code (JSFiddle):
var isAnimated = false;
var nbhdLength = $('.nbhd').length;
var lastSectionId = nbhdLength - 1;
var allHeight = (nbhdLength - 1) * window.innerHeight;
var up = true;
function setHeights() {
$('.nbhd').css('height', window.innerHeight);
}
setHeights();
$('html').mousewheel(function(e) {
var up = e.deltaY > 0;
if (up) {
console.log('up');
up = true;
} else {
console.log('down');
up = false;
// console.log(up);
}
if (!up && $('#id' + lastSectionId).hasClass('scrolledto') || (!up && !$('.scrolledto').length)) {
$('.scrolledto').removeClass('scrolledto');
return;
}
if (isAnimated) return;
isAnimated = true;
var currentSectionId = $('.nbhd.scrolledto').data('id');
up ? currentSectionId-- : currentSectionId++;
if (currentSectionId < 0) currentSectionId = 0;
if (!$('.scrolledto').length) currentSectionId = lastSectionId;
$('.scrolledto').removeClass('scrolledto');
var section = $('#id' + currentSectionId);
section.addClass('scrolledto');
var pos = section.offset().top;
$('body, html').animate({
scrollTop: pos
}, 1000, function() {
setTimeout(function() {
isAnimated = false;
}, 100)
console.log($(window).scrollTop());
});
});
.div {
width: 100%;
}
.red {
background: red;
}
.yellow {
background: yellow;
}
.green {
background: green;
}
.blue {
background: blue;
}
.abovefooter {
background: gray;
height: 200px;
}
.footer {
background: black;
height: 350px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
<div id="id0" data-id="0" class="nbhd red scrolledto"></div>
<div id="id1" data-id="1" class="nbhd yellow"></div>
<div id="id2" data-id="2" class="nbhd green"></div>
<div id="id3" data-id="3" class="nbhd blue"></div>
<div class="abovefooter"></div>
<div class="footer"></div>
You need to prevent the default mouseWheel event from happening, using javascript to perform the desired effect instead.
$('html').mousewheel(function(e) {
e.preventDefault();
//...
}
Demo: https://jsfiddle.net/b67uw0cx/1/

How to change color of text when entering fixed div using jQuery

I have a div with a background color that is fixed in the browser.
Scrolling through the site, I want the text color to change from black to white when it meets this overlay, then back to black again as it leaves it. This isn't really possible in css yet, so how can I set this in jQuery?
I'm using the ScrollTo plugin (http://flesler.blogspot.com/2007/10/jqueryscrollto.html) for my scrolling.
fiddle (css and html):
http://jsfiddle.net/L76NP/
html:
<body>
<div id="wrapper">
<div class="section">Section 1</div>
<div class="section">Section 2</div>
<div class="section">Section 3</div>
<div class="section">Section 4</div>
</div>
<div id="overlay"></div></body>
css:
body {color: #000000}
#wrapper { margin-left: auto;
margin-right: auto}
.section {
height: 300px;
width: 400px;
margin: 0 auto;
padding: 15px;}
#redbox {
background-color: #FF0000;
position: fixed;
top:100px;
bottom: 200px;
left: 0;
right: 0;
z-index: -100;}
Try this out:
http://jsfiddle.net/ALcm6/3/
Basically checking if the section fits within the box, and if so it's changing the text color. You can alter this for your specific needs.
$(window).scroll(function () {
var redbox = $("#redbox");
var redBoxTop = redbox.position().top;
var redBoxBottom = redBoxTop + redbox.outerHeight();
$(".section").each(function () {
var section = $(this);
var sectionTop = section.position().top - $(window).scrollTop() + 15;
var sectionBottom = section.position().top - $(window).scrollTop() + section.height();
if ((sectionTop >= redBoxTop && sectionTop <= redBoxBottom) || (sectionTop <= redBoxTop && sectionBottom >= redBoxBottom) || (sectionBottom >= redBoxTop && sectionBottom <= redBoxBottom)) {
section.css("color", "white");
} else {
section.css("color", "black");
}
});
});
$('#redbox').css('background-color','rgb(255,255,255)');//it's css controller
this is scroll event:
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
$('#redbox').css('background-color','rgb(255,255,255)');
} else {
$('#redbox').css('background-color','rgb(0,0,0)');
}
});
http://jsfiddle.net/LQ9QP/
it's a sample code And You can customize it.

Categories