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.
Related
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?
I'm looking for a way to slow down scrolling between two specific pixels, for example 1 to 100 from the top. Would that be possible in any way?
Here's a link to a website that have that feature I'm looking for.
http://goo.gl/isH5o0
When you start scrolling the dark blue overlay div disappears using CSS3 Translate3d, but then the scroll seems to stop or go really slow, which makes the underlying div not scroll to far at the same time the overlay div slides up.
Can someone please give me a hint of what technique to use to accomplish this or maybe help me with some code.
I think that there's nothing special with the scroll on that page, just the divs moving using 3d transforms. But if you want to achieve special effects with scroll, you can use the jQuery animate function:
$('html').animate({scrollTop: position-to-scroll}, 300, 'ease-in');
More about animate.
It may be using disable scrolling. I noticed that if i drag the scroller on the right hand side of the window it is uneffected by the "slowing" however the mouse scroll is. This is similar to the effect of the demo described here How to disable scrolling temporarily? .. at a point you can temporarily disable the scroll and then re enable it to stop them going too far down
I am looking for a scroller which auto scrolls to the end and stops and switches to manual navigation. I tried googling, there are thousands of scrollers but I need one with both autoplay and manual scroll functionality. Where user can also switch to manual scroll with a single click while it is auto scrolling, something like this.
But it must stop auto scrolling when it has reached end and then switch to manual scrolling.
jQuery Easy Slider 1.7 (Demo here) has both manual scrolling and automatic scrolling, which automatically turns off as soon as the user clicks on the slider. It's also really easy to customize and extend - and I've done so in a few past projects.
As for the autoscrolling to stop at the last slide, you could manually add the functionality using a timer that turns off autoscrolling after all the slides are done. Or you could play with it and just add an event that gets fired whenever the last slide is reached.
Edit:
Using SmoothDivScroll is even better, because it allows the user (you) to add a number of callbacks. So you can just turn off autosliding when the last slide is reached:
$("#makeMeScrollable").smoothDivScroll({
autoScrollingRightLimitReached: function(eventObj, data) {
$("#makeMeScrollable").smoothDivScroll("option","autoScrollingMode","");
}
});
Edit 2:
Sadly, it seems that callbacks not working are a known issue on their bugtracker. You could try and contact the creator of the script and see whether he's planning on fixing them.
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.
I've made a page with smooth vertical scrolling, and I was wondering if you can somehow "block" so the user can't use his mouse or touchpad to scroll on the page - when they do that the whole idea kinda stops.
you can see the scrolling on my webpage.
enter link description here
So far I've just hidden the scrollbar so they can't do it.
I guess you can say what I'm asking for is, can you "block" manually scrolling?
Thanks.
they are several solutions, but there's none that I found perfect. The simpliest is:
set the css property "overflow" to hidden (if on your body, you must set height and width to 100% on body and html, plus no margins/padding borders).
also you can add a listenner to scroll events, then prevent them with event.prevendDefault().
But they are always undesirable effects that can "scroll" pages(and blocks) without a mousescroll:
first is selection: your layout break here. To try it, select from the upper and go down, then the page will scroll(with chrome). this is unlikely to happen when there is no text and no drag and drops, but once it happens your users are lost since there is no scrollbars.
second is scrollIntoView(). You can call that via javascript, or the browser will do it automatically sometimes ( href to an anchor, input focus, "scroll memory at reload" ). This is were there is most risks, but there is very few control over these.
finally, one "bad" solution I found is to regularly force scrollTop property of elements to 0. But most probably you won't have to get there and the CSS body { overflow: hidden; height: 100% } will be sufficient.
The way you've done it is fine. I don't think you can cancel a scroll event, like you can with other event (keypress, button clicks etc..)
Setting overflow to hidden would be how I'd do it as well, as that completely stops all scrolling. The event doesn't even take place in the background.
The following code will block scrolling with the mousewheel. While this isn't relevant for me as I can't use the mousewheel to scroll anyway, it may block scrolling with your touchpad.
Just add this to one of your included js files...
window.onmousewheel = document.onmousewheel = function(event){
if (event.preventDefault) event.preventDefault();
event.returnValue = false;
}
Here's an example...
http://jsfiddle.net/johncmolyneux/aSw2g/