I have a page "link.html" which has an anchor pointing to index.html page <a href = "index.html?#myInnerLink"
I want smoothscroll to the div on another page(index.html) which has an Id of "myInnerLink" in jquery .. it is working fine but the problem is that it is scrolling from bottom to top instead of top to bottom to that particular div
"myInnerLink" div is internal in "myDiv" div... Thanks
link.html
<a id="mylink" href="index.html?#myInnerLink">Go To MY InnerLink</a>
index.html
<div id="myDiv" class="mydiv">
SomeText here...
<div id="myInnerLink">
ScrollTo This Div...
</div>
</div>
jquery
$(document).ready(function() {
if (window.location.hash) {
var hash = window.location.hash;
$('#myDiv').animate({
scrollTop : $(hash).offset().top
}, 500);
};
});
I'm currently using this script below, which is modified and originally came from https://jsfiddle.net/s61x7c4e/
function doScrolling(element, duration) {
let bodyRect = document.body.getBoundingClientRect(),
elementRect = element.getBoundingClientRect(),
offset = ((elementRect.top - bodyRect.top) - 40);
let startingY = window.pageYOffset,
elementY = offset,
targetY,
diff,
easeInOutCubic,
start;
duration = duration || 500;
// if element is close to page's bottom then window will scroll only to some position above the element...
targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY;
diff = targetY - startingY;
easeInOutCubic = function (t) {
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
};
if (!diff) return;
// bootstrap our animation,
// it will get called right before next frame shall be rendered...
window.requestAnimationFrame(function step(timestamp) {
if (!start) start = timestamp;
let time = timestamp - start, // elapsed milliseconds since start of scrolling...
percent = Math.min(time / duration, 1); // get percent of completion in range [0, 1]
// apply the easing, it can cause bad-looking
// slow frames in browser performance tool, so be careful...
percent = easeInOutCubic(percent);
window.scrollTo(0, startingY + diff * percent);
// proceed with animation as long as we wanted it to.
if (time < duration) {
window.requestAnimationFrame(step)
}
})
}
document.getElementById('scrollMid').addEventListener('click', function(){
var element = document.getElementById('middle');
doScrolling(element, 1000);
});
Related
I have an icon drawn when i scroll down the page and undrawn when i scroll up.
I would like to make it draw only when i scroll down and stay this way for the rest of the session.
$(document).ready(function() {
var $dashOffset = $(".path").css("stroke-dashoffset");
$(window).scroll(function() {
var $percentageComplete = (($(window).scrollTop() / ($("html").height() - $(window).height())) * 100);
var $newUnit = parseInt($dashOffset, 10);
var $offsetUnit = $percentageComplete * ($newUnit / 100);
$(".path").css("stroke-dashoffset", $newUnit - $offsetUnit);});
var $bg = $(".background")
$(document).scroll(function(){
$bg.css({transform: $(this).scrollTop()<1 ? "scale":"scale(1,1)"});
});
});
This is a follow-on from this question: Animation based on scroll position
The goal is to loop through each element, and change it's rotation and perspective based on the users scroll position. I guess from an organic UX viewpoint, you'd want the top of the browser window to 'squash' the topmost item, and smoothy flip the element down.
Here's a screenshot for guidance:
Here is a Fiddle: https://jsfiddle.net/nfquerido/0zpc2a76/
And the loop function:
var _items = function () {
forEach(items, function (item) {
var scrollTop = _scrollTop(),
elementTop = item.offsetTop,
documentHeight = _getDocumentHeight(),
// Transform the item based on scroll
rotationFactor = Math.max(0, scrollTop - elementTop),
perspectiveFactor = Math.max(0, scrollTop - elementTop),
rotation = (rotationFactor / (documentHeight - windowHeight) * 90),
perspective = (perspectiveFactor / (documentHeight - windowHeight) * 2000),
transform = 'perspective(' + perspective + ') rotateX(' + rotation + 'deg)';
// Elements off the top edge.
if(scrollTop > elementTop) {
item.classList.add('scrolling');
item.style.webkitTransform = transform;
} else {
item.classList.remove('scrolling');
item.style.webkitTransform = null; // Reset the transform
}
});
};
I updated your fiddle: https://jsfiddle.net/0zpc2a76/1/
If I understand your question correctly, I think you are trying to get the blue boxes to "fold over" as if they are being pushed down by the top of the viewport. For that, your calculations seem to be wrong, so I updated some of the variable assignments:
rotation = (rotationFactor / (item.offsetHeight) * 90),
perspective = 2000 - (perspectiveFactor / (item.offsetHeight) * 2000),
I am using the following javascript code to scroll my div into view when a user click on a div.
<script>
function showDiv2() {
document.getElementById('about').style.display = "none";
document.getElementById('terms').style.display = "none";
document.getElementById('breaker').style.display = "block";
document.getElementById('contact_us').style.display = "block";
document.getElementById( 'contact_us' ).scrollIntoView('slow');
}
</script>
this code works and scrolls the div into view, but there is no effect, instead of the page scrolling smoothly down to my div it sort of just jumps to the div. Is there a way I can make this smoothly and slowly scroll down to my div? Thanks
According to Element.scrollIntoView() documentation try this:
element.scrollIntoView({block: "end", behavior: "smooth"});
but you must remember that this is an experimental feature and works good only in Firefox
For a more comprehensive list of methods for smooth scrolling, see my answer here.
To scroll to a certain position in an exact amount of time, window.requestAnimationFrame can be put to use, calculating the appropriate current position each time. To scroll to an element, just set the y-position to element.offsetTop.
/*
#param pos: the y-position to scroll to (in pixels)
#param time: the exact amount of time the scrolling will take (in milliseconds)
*/
function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}
Demo:
function scrollToSmoothly(pos, time) {
var currentPos = window.pageYOffset;
var start = null;
if(time == null) time = 500;
pos = +pos, time = +time;
window.requestAnimationFrame(function step(currentTime) {
start = !start ? currentTime : start;
var progress = currentTime - start;
if (currentPos < pos) {
window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
} else {
window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
}
if (progress < time) {
window.requestAnimationFrame(step);
} else {
window.scrollTo(0, pos);
}
});
}
document.getElementById("toElement").addEventListener("click", function(e){
scrollToSmoothly(document.querySelector('div').offsetTop, 500 /* milliseconds */);
});
document.getElementById("backToTop").addEventListener("click", function(e){
scrollToSmoothly(0, 500);
});
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="backToTop">Scroll back to top</button>
</div>
The SmoothScroll.js library can also be used, which supports scrolling to an element on the page in addition to more complex features such as smooth scrolling both vertically and horizontally, scrolling inside other container elements, different easing behaviors, scrolling relatively from the current position, and more.
document.getElementById("toElement").addEventListener("click", function(e){
smoothScroll({toElement: document.querySelector('div'), duration: 500});
});
document.getElementById("backToTop").addEventListener("click", function(e){
smoothScroll({yPos: 'start', duration: 500});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll#1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<button id="toElement">Scroll To Element</button>
<div style="margin: 1000px 0px; text-align: center;">Div element
<button id="backToTop">Scroll back to top</button>
</div>
I am trying to animate a video on scroll like the landing page for the new iPhone 6. I have the video animating on scroll, but I am trying to some how ease the the video once the mousewheel has been released. I'm not sure how I should approach this challenge. Should I be trying to use an actual easeOut function? Or should I do it some other way?
Here is a snippet of the JS I currently have. And a live example here.
function easeOut(t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
};
var $win = $(window),
$video = $('video'),
frameRate = 29.97,
target = 0,
scroll = 0,
isTicking, scrollTimeout, delta, target;
var ScrollVideo = function() {
this.scrollY = 0;
$win.on('mousewheel DOMMouseScroll', this.onScroll.bind(this));
};
ScrollVideo.prototype = {
/**
* Callback for our scroll event
* keeps track of the last scroll value
*/
onScroll: function(event) {
var e = event.originalEvent ? event.originalEvent : event; // get original event if available
target += (e.wheelDelta > 0) ? -70 : 70;
if (target < 0) target = 0;
delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
this.requestScrollTick();
},
/**
* Calls rAF if it hasn't already
* been done
*/
requestScrollTick: function() {
if( !isTicking ) {
window.requestAnimationFrame(this.scrollHandler);
}
isTicking = true;
},
/**
* Animate stuff on scroll
*/
scrollHandler: function() {
scroll += (target - scroll) * 0.1;
console.log(scroll);
if(delta < 0) {
$video[0].currentTime += (1 / frameRate);
}
else {
$video[0].currentTime -= (1 / frameRate);
}
// stop ticking
isTicking = false;
}
};
var scrollVideo = new ScrollVideo();
I'd love to be able to tackle this, any help/direction is greatly appreciated.
how can i add an easing/animation/slowly moving to this function?
At the moment it just jumps.
Now it should move to the "anchor" with an animation.
<script type='text/javascript'>
setTimeout("window.scrollBy(0,270);",3000);
</script>
also possible with plain javascript using request animation frame..
// first add raf shim
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// main function
function scrollToY(scrollTargetY, speed, easing) {
// scrollTargetY: the target scrollY property of the window
// speed: time in pixels per second
// easing: easing equation to use
var scrollY = window.scrollY,
scrollTargetY = scrollTargetY || 0,
speed = speed || 2000,
easing = easing || 'easeOutSine',
currentTime = 0;
// min time .1, max time .8 seconds
var time = Math.max(.1, Math.min(Math.abs(scrollY - scrollTargetY) / speed, .8));
// easing equations from https://github.com/danro/easing-js/blob/master/easing.js
var PI_D2 = Math.PI / 2,
easingEquations = {
easeOutSine: function (pos) {
return Math.sin(pos * (Math.PI / 2));
},
easeInOutSine: function (pos) {
return (-0.5 * (Math.cos(Math.PI * pos) - 1));
},
easeInOutQuint: function (pos) {
if ((pos /= 0.5) < 1) {
return 0.5 * Math.pow(pos, 5);
}
return 0.5 * (Math.pow((pos - 2), 5) + 2);
}
};
// add animation loop
function tick() {
currentTime += 1 / 60;
var p = currentTime / time;
var t = easingEquations[easing](p);
if (p < 1) {
requestAnimFrame(tick);
window.scrollTo(0, scrollY + ((scrollTargetY - scrollY) * t));
} else {
console.log('scroll done');
window.scrollTo(0, scrollTargetY);
}
}
// call it once to get started
tick();
}
// scroll it!
scrollToY(0, 1500, 'easeInOutQuint');
For anyone viewing this question in 2019: this can now be done natively by using
window.scrollBy({
top: 0,
left: 270,
behavior: 'smooth'
});
This works in all major browsers except edge and safari. See https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy#Examples
Adapted from this answer:
function scrollBy(distance, duration) {
var initialY = document.body.scrollTop;
var y = initialY + distance;
var baseY = (initialY + y) * 0.5;
var difference = initialY - baseY;
var startTime = performance.now();
function step() {
var normalizedTime = (performance.now() - startTime) / duration;
if (normalizedTime > 1) normalizedTime = 1;
window.scrollTo(0, baseY + difference * Math.cos(normalizedTime * Math.PI));
if (normalizedTime < 1) window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
}
This should allow you to smoothly scroll by the specified distance.
This will Work, Assume you need to Smooth-scrolls to the top of the page.
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
Another example with jQuery, uses the easing plugin for some nice effects:
http://tympanus.net/codrops/2010/06/02/smooth-vertical-or-horizontal-page-scrolling-with-jquery/
got it myself. because of wordpress and the jquery.noConflict Mode i hade to modify the code:
<script type="text/javascript">
(function($){
$(document).ready(function(){
setTimeout(function() {
$('body').scrollTo( '300px', 2500 );
}, 3000);
});
}(jQuery));
</script>
thanks for everybody!!!
When using jQuery, you could easily use the .animate function.
Here's an example on how it should work.
Using jQuery makes this much easier, perhaps with the scrollto plugin. http://flesler.blogspot.se/2007/10/jqueryscrollto.html
Consider a solution such:
<script type='text/javascript' src='js/jquery.1.7.2.min.js'></script>
<script type='text/javascript' src='js/jquery.scrollTo-min.js'></script>
<script type='text/javascript' src='js/jquery.easing.1.3.js'></script><!-- only for other easings than swing or linear -->
<script type='text/javascript'>
$(document).ready(function(){
setTimeout(function() {
$('html,body').scrollTo( {top:'30%', left:'0px'}, 800, {easing:'easeInBounce'} );
}, 3000);
});
</script>
Of course you need to dl the scripts.
See http://jsfiddle.net/7bFAF/2/ for a working example
We can make it simpler by using the css property scroll-behavior
html {
scroll-behavior: smooth;
}