Method of Achieving sliding images effect on window scroll - javascript

I am attempting to recreate something similar to the pencil effect on:
http://www.fiftythree.com/pencil
Not exactly but similar. About halfway down the current page, the pencil sort of pulls apart with a description on each part as the user scrolls down the window.
I am attempting to use the jquery .animate function to pull multiple div's apart in the same fashion.
IE: (image1) behind that (image2) behind that (image3).
Sort of a vertical accordion effect.
I am basing everything off scrollTop variable. And at certain points it will move the div's in a different fashion. All the events are contained in this loop.
$(window).scroll(function (event) {
var scroll = $(window).scrollTop();
// doing stuff
}
My issue is that the scrolling function is not executing fast enough. If I scroll slowly it works, if I scroll quickly it sort of tries to play catch up and is either off location or too jerky.
Do you all think this is a decent way to achieve this effect, and if so - any suggestions on setting the refresh time to check for where the user has scrolled on the page?

Related

How to stop user input interrupting "ScrollIntoView" whilst in progress

Context
I am creating a site where there are sections stacked in rows, and each row takes up the full viewport.
I don't want the site to be scrollable normally, and would instead like the site to "snap" to the bottom of each section, so that I can then play out the animations taking up the full view port.
Issue
I took the approach of listening to scroll events, and then triggering a nextsection.ScrollIntoView when the user had scrolled far enough to snap to the next view.
This doesn't work well though, as the ScrollIntoView is interupted by user scroll activity, including the latent scrolling of the mouse that hangs around for about 300ms after you've scrolled.
I managed to get it sort of working by using a setTimeout(scrollIntoView(), 400), but this takes too much time and relies on the user not interacting with the site after scrolling.
I made a CodePen (here) showing the type of setup I'm working with, however to see the issue you need to open it as a webpage itself, as CodePen doesn't perform a smooth animation when using ScrollIntoView and just jumps there.
I need a smooth and uninterruptable animation as the site switches from one section to another, but as of yet I've found no working ways to implement this.
Thanks for any answers.

Stopping jquery animate. Building a Carousel

Im learning javascript and jquery and im trying to create my own carousel.
The current problem i have stumbled over is the following. When the user stop scrolling in the carousel, i have a function that runs and centers my targeted Carousel item to my desired point. I have illustrated this with a black line in my fiddle. Here is my function that centers that item:
jQuery.fn.CenterToPoint = function(){
return this.each(function(){
Offset = $(this).offset().left;
Width = $(this).width();
Illuminate_Point = 0.45 * $(window).width();
ScrollLeft = Illuminate_Point - (Offset+Width/2);
$Container.animate({scrollLeft: "-=" + ScrollLeft},450);
});
}
However, i want the user to be able to scroll even though the animation is running. How can i kill this animation when its running but the user either clicks, mousescroll or trackpad is used on my carousel?
Here is my jFiddle:
http://jsfiddle.net/ptp05jvo/
From what I understand, your problem are:
The box is twitching after the it reach to desired point (black line).
When animating (box moving towards the black line), user input will cause box to 'jump'. In this case, you would want user input to override animating scrolling.
I didn't solve the whole problem, but here's what I've got so far: http://jsfiddle.net/ptp05jvo/3/
I managed to stop the first problem (twitching) by adding the following option in .animate().
always: function() {
clearTimeout($Container.data('scrollTimeout'));
isSystemScroll = false;
}
When you animate with .animate() to scroll, jQuery scroll the element and it's considered as actually scrolling, so .scroll() event is triggered. This can be good / bad.
In your carousel case, it's sort of bad because you .CenterToPoint() is called within .scroll() event which means it will be called every time jQuery animate the box to center.
This is what causing the twitching problem. The .CenterToPoint() keeps getting called within `.scroll()' event. So, the option I added will stop this.
To separate the concern, I added new jQuery function, scrollStopped to handle scrolling stopped event.
There is also a new variable called isSystemScroll that I introduced to the code. The idea is to recognize whether the scroll is coming from user / animation. With this, we can prioritize user input to override animation scroll.
However, user input can be anything, keyboard arrow, mouse wheel scroll, mouse click on scroll bar, etc. In my example, I only handle keyboard arrow input which is shown in the following code:
$(document).keyup(function () {
isSystemScroll = false;
console.log("key up");
});
Obviously, you can add additional check to only capture left / right arrow keys instead of all keys.
This sort of solve the 2nd problem. But you still need to handle other user inputs, esp mouse moving scroll bar.
From the test, I found that Firefox render the animation better and smoother. In Firefox, user input with keyboard arrow will override animation perfectly. The transition is smooth between the two. However, in Chrome, there's a little bit lag / jump.
Also, in Chrome, horizontal scroll bar doesn't show up while in Firefox, it does.
It's worth to mention that Firefox doesn't show twitching problem. I can't be sure if this is caused by the CSS you have. I didn't modify your CSS.
I came across couple carousel library and did the same test to see how they handle the issue.
Owl Carousel
http://owlgraphic.com/owlcarousel/demos/custom.html
Only allows dragging input. Other user inputs are disabled (scroll bar, keyboard arrow, etc). However, if you try to drag the carousel (in Chrome browser) while it's animating, you will see same jump / lag problem. Again, Firefox shows better and smoother animation with this library.
Slick
http://kenwheeler.github.io/slick/
The 'autoplay' option prevents user input when carousel is animating. No scroll bar and you can only move with keyboard arrow.
Conclusion
As a conclusion from this long answer, few things you can do if you want to build your own carousel:
Limit user input, only allows certain input.
Disable scroll bar.
Or, you can use existing library out there.

How to make the browser stay scrolled at a fixed posistion?

How can I keep the browser from scrolling, or how can I make the browser continually scroll to a fixed posistion?
I am working on a library for the Nintendo 3DS browser. I made the page fit perfectly within the browser, but the up arrow makes it scroll because the bottom screen is the only window recognized as the visible area.
I want to make it so the div #bottomScreen is the only thing in the bottom screen, and disabling scrolling is the only thing I can think that would work.
I have figured out how to scroll it to a said position via
document.body.scrollTop = 220;
How can I make it continually go to this position?
Making a repeating timer with setTimeout and putting the above code in it won't work. I believe it is because this only works prior to the page loading.
Any advice on how to enforce it?
It should work even after page load. Here's the code, although i'm not sure what the intent of the code is, might be annoying to the user.
setInterval( function(){ document.body.scrollTop = 200 }, 500 ); // set your time
A more elegant solution would be to disable scrolling when that method is called (to scroll to the position of 220 from top or whatever), and re-enable it whenever the appropriate action has been taken by the user etc... jQuery example:
$('body').css('overflow', 'hidden'); // removes scrollbars entirely
$('body').css('overflow', 'auto'); // re-enable scrolling
Otherwise use setInterval() with a very short interval like 10ms to repeatedly fire your scroll function. If you are going to do this it would be wise to add some logic to see if the window is already scrolled to approximately the right position (allow for +/- 10px or something) so it isn't extremely jarring for the user.
The best way I've seen on some sites (like twitter I think or facebook when an image pops up) which is to set the overflow property to hidden on the body element. This prevents any scrolling so all you need to worry about is the position of content when you do that.
I guess you would need to wrap the content in some sort of container element and when you change the overflow of the body element you also set the y-coordinate of the container to reveal the specific area of the page being looked at.
This is by far the best thing I have seen to achieve that effect because it doesn't require timers etc.
You could add a event listener for the scroll event, and then set the position then.

Javascript: don't stop scrolling window if the cursor passes over a scrollable div

I'm building a web app that has a grid of many small scrollable divs (actually, Ace editors), and this grid has enough elements that it is larger than the window. When a user begins scrolling over empty space, I want them to be scrolling the window itself; when a user begins scrolling inside a grid element, I want them to scroll the div contents there. The thing is, if a user begins scrolling over empty space, and then scrolls such that their mouse goes over a grid element, that scrollable div captures all the scrolling events, interrupting the user's flow over the grid and "trapping" them inside the grid element.
I can't manually capture onmousewheel events, since AFAIK there's no way to capture horizontal mouse wheel movement separately from vertical, and I want users on Mac OS X to be able to scroll in all directions. I've thought about using JS to add an invisible div with a very high z-index on the first onscroll event, and removing it as soon as onscroll events aren't triggered for a certain period of time. Haven't yet coded this up, but I'm wondering if there's a better solution, or if there are any potential pitfalls that I haven't thought of. Any help or advice would be great! Thanks!
I think a solution for this would be incredibly difficult due to browser support, and the actual solution, which would probably be something like calculating the scroll, backtracking the div, and applying the scroll to the page.
You could do something like this:
$('div').scroll(function(e){
// figure out how much it has scrolled
window.scrollBy(0,howmuch);
});
I don't recommend this solution in the slightest though, I think the better option would be to set the divs to overflow:hidden; and pick up a solid scroll plugin, and use that to customize the scroll behavior on the divs.

Horizontal scroller with Mootools

I'm working on a site for myself, and I'm using a custom horizontal scroller done with Mootools that I got from another site (and got their permission to use). While I've managed to get the scroller to function the way I want to, there are two issues I'm looking to fixed and don't have the know-how myself to figure out.
I've set up a simple demo page here.
You can scroll with your mousewheel/trackpad up and down or left and right, you can grab the scroller and drag it, and you can click anywhere along the line to jump directly. So all the functionality is okay. My issues are:
If you scroll to the middle (or anywhere except the start position), then resize your browser window, the scroller handle will jump back to the start/left even though the contents stays put. If you then start scrolling again the contents will jump back to align with the scroller handle's position. Ideally the handle would stay put when the window is resized, but I can't figure out how to do this on my own.
At the end/right of the page I'd like to have a back button that smoothly scrolls you back to the start/"top". The best I've managed is what you see there now, where the contents scrolls back smoothly, while the scroller simply jumps back to it's first position. While I could work around that by simply have it jump straight back to the start, it would certainly look much nicer if the scroller would smoothly scroll its way back like the contents does.
Any help with this would be greatly appreciated!
Your first issue is occurring because positionIt() is being called every time the window resizes. Looking into that function, you can see that the bottomSlider is being initialized every time. I would break positionIt() into a initializing function and positioning function, and ensure that only the positioning function is called when the window resizes.
The second issue could probably be fixed by creating a separate step() function for the bottomSlider and calling that within onChange, rather than using an inline anonymous function. You could then create a timer or tween that calls step() to move the scrollbar back to its original position (and subsequently move the viewport in accordance with it.)
Hopefully that makes some sense!

Categories