I'm trying to do some basic parallax animation, but the movement is extremely jittery as soon as I test in IE or any OSX browser - not sure why!
http://willmurdoch.com/scrolltest/
$(window).scroll(function(){
$('.hero').each(function(){
if($(this).offset().top - $(window).scrollTop() > -$(window).height() && $(this).offset().top - $(window).scrollTop() < $(window).height()){
var myTranslate = Math.ceil($(window).scrollTop() - $(this).offset().top);
$(this).find('.heroSlides').css('-webkit-transform', 'translateY('+myTranslate/2+'px)');
$(this).find('.scrollWrap').css('-webkit-transform', 'translateY('+myTranslate/5+'px)');
}
});
});
I've tried locking scroll functions to only fire every 100ms and transition in between, adding hardware acceleration to every animated element, but nothing seems to do it! Any help would be appreciated!
One of the things that I've found that adds smoothness to my CSS transformations, is to add the CSS Transformations
https://www.w3schools.com/css/css3_transitions.asp
Another thing you can do is look at skrollr and how that project works. It does math based easing for its smooth scrolling.
EDIT
On the page you posted, try changing the following functions:
$(window).scroll(function(){
scrollLogic();
console.log($(window).scrollTop());
closeNav();
});
change to:
$(window).scroll(function(){
//scrollLogic();
console.log($(window).scrollTop());
closeNav();
});
var scrollInterval = setInterval(function() {
scrollLogic();
}, 1000/30);
Then change the myTranslate part of scrollLogic. Play with different values to make the change more/less gradual.
Related
So I have two sections of content near the top of my page and I’d like for users who have scrolled down to near the top of the second section to get “scroll snapped” to the top of the second one once they have stopped scrolling.
I think it should be possible using jQuery but I haven’t been able to figure it out. Here are my examples:
Without my attempt: http://codepen.io/jifarris/pen/gaVgBp
With my broken attempt: http://codepen.io/jifarris/pen/gaVgQp
Basically I can’t figure out how to make it try scrolling to the spot only once, after scrolling has stopped. It’s kind of just freaking out.
I love how the recently introduced scroll snap points CSS feature handles scroll snapping and I’d almost prefer to use it – for the browsers that support it, at least – but it seems like it only works for items that take up 100% of the viewport height or width, and it seems like it’s for scrolling within an element, not the page itself.
The top section has a fixed height, so this really can be handled with pixel numbers.
And for reference, here’s the heart of the code from my attempt:
$(function() {
$(document).on('scroll', function() {
var top = $(document).scrollTop();
if (top > 255 && top < 455) {
$('html, body').animate({scrollTop: '356'}, 500);
$('body').addClass('hotzone');
} else {
$('body').removeClass('hotzone');
}
});
});
KQI's answer contains most of the steps required to create a well functioning section-scroll for use in your application/webpage.
However, if you'd just want to experiment yourself, developing your script further, the first thing you'll have to do is add a timeout handler. Otherwise your logic, and therefor scrollAnimation, will trigger every single pixel scrolled and create a buggy bouncing effect.
I have provided a working example based on your script here:
http://codepen.io/anon/pen/QjepRZ?editors=001
$(function() {
var timeout;
$(document).on('scroll', function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
var top = $(document).scrollTop();
if (top > 255 && top < 455) {
$('body').animate({
scrollTop: '356'
}, 500);
$('body').addClass('hotzone');
} else {
$('body').removeClass('hotzone');
}
}, 50);
});
});
Good luck!
All right, there are couple of things you gonna have to deal with to get a good result: which are performance, call stack queue, easing.
Performance wise you should drop jQuery animate and use VelocityJs which gives a smoother transition, better frame per second (fps) to avoid screen glitches especially on mobiles.
Call stack: you should wrap whatever logic you have to animate the scrolltop with 'debounce' function, set the delay for let say 500mm and check the scrolling behavior. Just so you know, the 'scroll' listener your using is firing on each pixel change and your script will go crazy and erratic. (It is just gonna be a moment of so many calc at the same time. Debounce will fix that for you)
Easing: make the transition looks cool not just dry snappy movement.
Remember, 'easing' with Velocity starts with 'mina.' i.e.
'Mina.easingFnName'
Finally, your logic could be right, i am in my phone now cannot debug it but try to simplify it and work with a single problem at once, be like i.e.
If ( top > 380 ) // debounce(...)
anyone have a clue how to make a sroll effect like this?
http://www.eurekasoft.com
I know the content is repeated at the end to create the illusion but i would like to know how to achieve the seemingly never end scroll.
Thanks!
It appears that site is using Skrollr: http://prinzhorn.github.io/skrollr/
Scroll all the way down for links to the Github and more examples.
Deep down, it is using the function window.scrollTo() to set the scroll position, and probably setting DOM around that area so that it looks the same as where it was scrolled from.
https://github.com/Prinzhorn/skrollr/blob/master/src/skrollr.js#L617
This works for me :)
here is the example: http://www.cancerbero.mx (only enable in Chrome and Safari)
// #loop is the div ID where repetition begins
$(document).ready(function(){
$(window).scroll(function(){
var scroll = $(window).scrollTop();
var limit = $('#loop').position().top;
if(scroll >= limit){
window.scrollTo(0,1); // 1 to avoid conflicts
}
if(scroll == 0){
window.scrollTo(0,limit);
}
});
});
I'm creating a Website that, on Mobile Browsers, zooms out, as it's a fixed width website. Instead of using the viewport meta tags I've taken to the following:
html, body {
zoom: 0.8;
}
This works great, but the problem is with my jQuery. I'm using simple jQuery code for a one-page website smooth scrolling, shown below:
/* Start Navigation */
jQuery('nav ul.menu li').click(function(e) {
if(!scrollingAnim) {
var page = jQuery(this).attr('data-page');
updateMenu(page);
scrollingAnim = true;
jQuery('html, body').stop().animate({
scrollTop: (jQuery(page).offset().top - 70)
}, 2000, 'swing', function() {
scrollingAnim = false;
});
}
e.preventDefault();
return false;
});
/* End Navigation */
This used to work fine, but for obvious reasons will not work with my zoom. I've tried multiplying it by the zoom level, but it doesn't work. Is there anything you'd suggest?
jQuery's .offset().top is changing with the change of the window scroll when you have CSS zoom involved...
Take a look at my answer here https://stackoverflow.com/a/21048208/1090395
Hope it helps
Faced with similar problem related to zoom and offset().Top. Tried to play with values in JS console and found this formula:
var scrollTopAnimateTo = ($(anchor).offset().top - $(".header").height()) * zoom + $(window).scrollTop() * (1 - zoom);
where zoom < 1.
I've created a menu that moves to the current window position by scrolling. When I scroll up and down right after, sometimes a glitch appears on Chrome 30 with OS X 10.9 and Windows 7. After hovering, the anchor tag jumps to the right position (1 pixel up). Is there anything wrong with my code? Is this a known bug?
Check this JSFiddle Demo!
$(document).ready(function(){
$(window).scroll(function(){
var newTop = ($(window).scrollTop() + 40) +'px';
$('#menu').stop().animate({ top: newTop}, 500);
});
});
Edit: It's fixed in Chrome 31.
I'm fairly certain this is a rendering bug since:
Manually triggering a repaint causes the glitch to go away.
The glitch doesn't occur in other browsers I tested.
Fortunately, triggering a repaint is a fairly straight-forward workaround, albeit an annoying one:
I added a callback to the animation:
$('#menu').stop().animate({ top: newTop }, 500, function(){
$('#menu').css('overflow', 'hidden');
setTimeout(function(){
$('#menu').css('overflow', 'auto');
}, 10);
});
jsFiddle Demo
Unfortunately, it seems both the setting and unsetting of some property (here I chose overflow) was necessary. The 10 is a little sketchy, but when you're working around a browser rendering bug, I'm not sure you can do much better.
Best of luck!
I agree with Adam, this is definitely a rendering bug. If you animate the menu using the translate() transform-function instead, it does not happen.
There are other bonuses to using this method as well: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
jQuery core does not allow you to animate using translate() out of the box, but there is a plugin that enables this at http://ricostacruz.com/jquery.transit/ , or you can opt for using .css() and let css transitions do the heavy lifting.
Here is an example using the plugin:
var menu = $("#menu");
$(window).scroll(function(){
var newTop = $(window).scrollTop();
menu.stop().transit({ y: newTop +'px' }, 500);
});
Plugin demo at http://jsfiddle.net/Hb3jS/5/
Here is an example using CSS transitions:
js
var menu = $("#menu");
$(window).scroll(function(){
var newTop = $(window).scrollTop();
menu.css({ transform: 'translateY(' + newTop +'px)' });
});
css
#menu {
transition: all .5s;
}
CSS demo at http://jsfiddle.net/Hb3jS/6/
I am trying to make the elements on my site fly-in and fly-out on scroll.
This is the effect I am looking for.
http://nizoapp.com/
The effect in the nizo site is done with jquery, I think
I have tried many different ways to get this effect working, with Skrollr, scrollorama, and jquery animate and with css transitions etc etc etc
I decided to use css transitions as mad by the "css animation cheat sheet" (google it)
After a lot of effort and some borrowed code, I have got it half working, as in, I can get the elements to fly-in on down scroll, but not to fly back out on up scroll.
This is a jsfiddle with it half working
http://jsfiddle.net/mrcharis/Hjx3Z/4/
The code is......
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function () {
$('.box').each(function (i) {
if (isScrolledIntoView(this)) {
$(this).addClass("slideRight");
}
});
});
// this is the function to check if is scroll down or up, but I cannot get it to trigger the fly in effect,
(function () {
var previousScroll = 0;
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
// i figure to put the fly-in code here
}
else {
// and the fly-out code here
}
previousScroll = currentScroll;
});
}());
I have tried using another function (code chunk) to check if the scrolling is down or up, but i can't get it working with the existing code.
Any help to get this working would be awesome
Have a nice day
I will post the solution one day, if I can figure it out, sure someone else would like to know
The trick to knowing whether you're scrolling up or down is not to ask. Make it relational by using the top offset of the elements in question. Then it's as easy as > or <, for the most part.
Though if you do want to get the current direction you could always record the last scroll position and compare it with the current one.
var before = 0;
$(window).scroll(function(event){
var now = $(this).scrollTop();
if (now > before){
//on down code
} else {
//on up code
}
before = now;
});
Like the answer here suggests.
I like to trigger the events based on the screen size and the element position in the screen, so it doesn't matter whether it's up or down, it follows the same rules forwards and backwards. That way instead of asking up or down, it just asks if it's scrolling and executes it accordingly.
If you need me to make changes to my fiddle for you, just let me know what you want to happen. I only made the fiddle because of the horrible job they did on the tympanus.net example. You don't make a tutorial to accomplish a simple task 2 pages of js, that's unnecessary and it doesn't provide any instruction other than "hey, you want to do this? Then copy and paste these things I put together that have no clear course of action, and way too much code to digest quickly". Which doesn't help anyone learn.
After some code borrowing from tympanus.net and using the modernizer library I came up with this.
I tried different approaches as well but all of them turned out to have some flaws in them so I find best approach to be using the sample code and the already provided modernizer JS library.