Been working on implementing a scrolling news ticker into my site. Controlling the scrolling function with JS. The code I am using is below, can anyone advise me on how to set and scrolling the speed at which the ticker will scroll?
$(function() {
//cache the ticker to improve the performance of the page.
var ticker = $("#ticker");
//wrap dt:dd pairs in divs to allow us to smooth our the animations
ticker.children().filter("dt").each(function() {
var dt = $(this),
container = $("<div>");
dt.next().appendTo(container);
dt.prependTo(container);
container.appendTo(ticker);
});
//hide the scrollbar
ticker.css("overflow", "hidden");
//animator function
function animator(currentItem) {
//work out new anim duration
var distance = currentItem.height();
duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.025;
//animate the first child of the ticker
currentItem.animate({ marginTop: -distance }, duration, "linear", function() {
//move current item to the bottom
currentItem.appendTo(currentItem.parent()).css("marginTop", 0);
//recurse
animator(currentItem.parent().children(":first"));
});
};
// start the news section scrolling
animator(ticker.children(":first"));
// users mouse enters the scrolling view
ticker.mouseenter(function() {
// Im stopping the animation when the mouse enters
ticker.children().stop();
});
// the mouse now leaves the view
ticker.mouseleave(function() {
// begin the animating again of the scroller
animator(ticker.children(":first"));
});
});
Thanks
Just copying and pasting JavaScript code can be dangerous stuff. Make sure you understand it before yanking it from a blog / tutorial. Also, have you tried anything yourself yet? Just reading the code should make the answer obvious:
duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.025;
Changing 0.025 to something else will change the duration of the animation.
Related
I'm pretty new with Jquery. I would like that my animations with Wow.js could run more than once time. For instance: i scroll to the bottom of my page and see all the animations, and if i scroll back to the top i see again the animations like when you scroll down. I hope that I explained myself. I have already seen many websites that repeats the animations on theirs pages but unfortunately I don't remember them and I can't provide a link.
I have already tried this:
$(window).scroll(function(){
new WOW().init();
}
But it repeat the animations also if you scroll a little and it's pretty ugly to see. I try to explain me better: I have a with my animation and if it is focused the animation is triggered, then i scroll down to another div and the previous div is no more visible(not in the window viewport), then again i scroll back to my div with animation and the animation is triggered again.
I'm sorry for this messy question but I really don't know how to explain it.
Thanks in advance!
This example by BenoƮt Boucart shows how the animation can be "reset" when the user scrolls out of view and back in. The key here is the second function that removes the animation css class when the element scrolls out of view. I wish WOW.js would implement this, but they've indicated that they don't plan to.
http://codepen.io/benske/pen/yJoqz
Snippet:
// Showed...
$(".revealOnScroll:not(.animated)").each(function () {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded > offsetTop) {
if ($this.data('timeout')) {
window.setTimeout(function(){
$this.addClass('animated ' + $this.data('animation'));
}, parseInt($this.data('timeout'),10));
} else {
$this.addClass('animated ' + $this.data('animation'));
}
}
});
// Hidden...
$(".revealOnScroll.animated").each(function (index) {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded < offsetTop) {
$(this).removeClass('animated fadeInUp flipInX lightSpeedIn')
}
});
If a user wants to repeat the animation on both the events i.e.
onScrollUp
onScrollDown
then this will be a good solution for it:
First create an addBox function, it will help to push new elements into the WOW boxes array.
WOW.prototype.addBox = function(element){
this.boxes.push(element);
};
Then use jQuery and scrollspy plugin that helps to detect which element is out of the view and then push WOW as:
$('.wow').on('scrollSpy:exit',function(){
var element = $(this);
element.css({
'visibility' : 'hidden',
'animation-name' : 'none'
}).removeClass('animated');
wow.addBox(this);
});
Solution Courtesy: ugurerkan
Answer by #vivekk is correct I m just adding a working example so that people can easily get this
see the Demo fiddle
<script>
// Repeat demo content
var $body = $('body');
var $box = $('.box');
for (var i = 0; i < 20; i++) {
$box.clone().appendTo($body);
}
// Helper function for add element box list in WOW
WOW.prototype.addBox = function(element) {
this.boxes.push(element);
};
// Init WOW.js and get instance
var wow = new WOW();
wow.init();
// Attach scrollSpy to .wow elements for detect view exit events,
// then reset elements and add again for animation
$('.wow').on('scrollSpy:exit', function() {
$(this).css({
'visibility': 'hidden',
'animation-name': 'none'
}).removeClass('animated');
wow.addBox(this);
}).scrollSpy();
</script>
I'm trying to make a long page of images scroll up and down infinitely (for an exhibition).
This is what I've been working with (code I found here, so helpful!):
https://jsfiddle.net/p7r73tke/
It's mostly working ok for what I want, but I need more control over speed and pause.
How can I make the pause at the top longer?
is there a way to make it pause randomly for ~1 second ?
does anyone know of an easier way to do what I'm thinking of? maybe as samuel-liew suggests, javascript is not the best solution for the problem
thank u thank u!
function scrollpage() {
function f() {
window.scrollTo(0, i); //idk
if (status == 0) {
i = i + 50; //scroll speed top to bottom?
if (i >= Height) {
status = 30; //idk?
}
} else {
i = i - 10; //scroll speed bottom to top?
if (i <= 1) { // if you don't want continue scroll then remove this if condition
status = 0; //idk
}
}
setTimeout(f, 0.01); //idk
}
f();
}
var Height = 15000; //doc height input manually
var i = 1, //idk
j = Height,
status = 0; //idk
scrollpage();
(I'm new and tender to JavaScript, as you can see in the comments)
Thanks for any help!
jQuery solution:
var speed = 10000; // 10000 = 10 seconds
var doScroll = function() {
var direction = $(window).scrollTop() != 0 ? 0 : $(document).height() - $(window).height();
$('html, body').animate({ scrollTop: direction }, speed, 'linear');
}
doScroll(); // once on page load
setInterval(doScroll, speed + 10); // once every X ms
DEMO: http://jsfiddle.net/samliew/k35tbgau/
JavaScript:
Sorry, I do not recommend pure JavaScript for this as you have to take into account:
Cross-browser issues with getting window height, document height, and current scroll position
Recalculating the scroll speed based on content height every time the browser is resized
Programming an animation function
Keeping track of intervals and timeouts, and when you need to clear them
Direction/state of scroll
Taking into consideration if user manually scrolls the scrollbar
Probably lots more...
Trying to accomplish something like on this website:
http://www.strangelove.nl/cases/kpmg-meijburg
The part where the responsive design is showcased, the image inside the devices start to scroll when a visitor scrolls past that point. I've tried to replicate it and I see a .js in the footer which is probably contributing. For now I have the css and html working on my test page.
Any help is gladly appreciated.
Strangelove is using their own Kubrick-js, which is available here: Kubrick-js
If you just want to have the 'images scrolling inside of frame while scrolling by'-effect, you can do it like this:
$(window).scroll(function() {
var animStart = 0, // the point where the animation starts
animEnd = 500, // the point, where the animation ends
scrollStartPos = 0, // the position your inside scrolling element starts
scrollEndPos = -300, // the position your inside scrolling element should end
winPosY = window.pageYOffset, // the scroll distance from top of document
scrollElement = $('.picture'); // the element to scroll
if(winPosY > animStart && winPosY < animEnd) {
// how far through the animation are we?
var howFar = (winPosY - animStart) / (animEnd - animStart),
scrollPos = Math.round(scrollStartPos + howFar * (scrollEndPos - scrollStartPos));
scrollElement.css('top', scrollPos + 'px');
$('.show-stats').html('How far: ' + howFar + '<br>scroll Position: ' + scrollPos);
}
});
Here is a fiddle for it: Fiddle
hope that helps.
I am building a full page slider that keeps the native scrollbar and allows the user to either free scroll, use the mouse wheel or navigation dots (on the left) to switch to a slide.
Once the user is on the last slide and tries to scroll down further, the whole slider moves up to reveal a simple scrollable section. If the user scrolls down and then tries to go back up, then this new section moves out of the way again and returns the slider back into view.
Fiddle: http://jsfiddle.net/3odc8zmx/
The parts I'm struggling with:
Only the first two navigation dots work. The third one DOES WORK if you area looking at the first slide. But doesn't do anything, if you are on slide 2. Note: the purple one is a short-cut to the second section of the page and not related to the slider.
When moving to the last slide (via the dots, if you're on the first slide) it causes the code to make the whole slider move upwards as it sees this as the user has slid past the last slide as per the description above. I have tried to combat this using a variable called listen to stop the scroll event listening when using the showSlide method... but it seems to be true even though I set it to false, and only reset it to true again after the animation...
When scrolling down using the mouse wheel, I can get to the second section and back up, but not to the first third section. I'm wondering if I could use the showSlide method to better handle this instead of the current dirty next and prev functions I have implemented.
Note: If the user has free-scrolled, when they use the mouse-wheel, I want the slider to snap to the nearest slide to correct itself... Any suggestions for how I could do this?
Can anyone offer some help?
Here's the JS:
var listen = true;
function nextSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: $('#section1').scrollTop() + $(window).height()
});
}
function prevSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: -$('#section1').scrollTop() + $(window).height()
});
}
function showSlide(index)
{
var offset = $('#section1 div').eq(index).offset();
offset = offset.top;
if(offset){
listen = false;
$('.slide-dot').removeClass('active');
$('.slide-dot').eq(index).addClass('active');
$('#section1').stop(true,false).animate({
scrollTop: offset
}, 500, function(){
listen = true;
});
} else {
alert('error');
}
}
$(document).ready(function(){
var fullHeight = 0;
$('#section1 div').each(function(){
fullHeight = fullHeight + $(this).height();
});
var lastScrollTop1 = 0;
$('#section1').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
if( $('#section1').scrollTop() + $(window).height() == fullHeight) {
if(listen){
$('body').addClass('shifted');
}
}
}
lastScrollTop1 = st;
});
$('#section1').on('mousewheel', function(e){
e.preventDefault();
var st = $(this).scrollTop();
if (st > lastScrollTop1){
nextSlide();
} else {
prevSlide();
}
});
var lastScrollTop2 = 0;
$('#section2').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
} else {
if( st == 0 ){
$('body').removeClass('shifted');
}
}
lastScrollTop1 = st;
});
$('.slide-dots').css({'margin-top':-$('.slide-dots').height() / 2});
$('.slide-dot').first().addClass('active');
$(document).on('click', '.slide-dot', function(e){
e.preventDefault();
showSlide( $(this).index() );
});
$(document).on('click', '.slide-dot-fake', function(e){
e.preventDefault();
$('body').addClass('shifted');
});
});
And for those wondering why I'm not using something like fullPage.js, it's because it can't handle the way I want to transition between the two areas and have two scrollbars (one for each area).
You can use:
e.originalEvent.wheelDelta
instead of:
st > lastScrollTop1
in the mousewheel event for your third problem to check if the user has scrolled up or down. And also change the +/- in prevSlide. I used dm4web's fiddle for your first problem. And I used:
scrollTop: offset - 1
instead of:
scrollTop: offset
for your second problem, because when the scroll reaches to the last pixel of the third element, it automatically goes to the next section, so 1 pixel is enough for it not to.
Here's the fiddle: http://jsfiddle.net/3odc8zmx/3/
As suggested by #chdltest, you could do it by using fullPage.js.
Here's an example. Go to the last section.
Code used for the example:
Javascript
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
scrollOverflow: true,
scrollBar: true,
afterLoad: function (anchor, index) {
//hiding the main scroll bar
if (index == 4) {
$('body, html').css('overflow', 'hidden');
}
//showing the main scroll bar
if (index == 3) {
$('body, html').css('overflow', 'visible');
}
}
});
CSS (in case you prefer to use the normal style for it)
/* Normal style scroll bar
* --------------------------------------- */
.slimScrollBar {
display: none !important;
}
.fp-scrollable {
overflow: auto !important;
}
Advantages of using fullPage.js instead to your own code:
Strongly tested in different devices and browsers. (IE, Opera, Safari, Chrome, Firefox..)
Prevent problems with trackpads, Apple laptops trackpads or Apple Magic Mouse.
Old browser's compatibility, such as IE 8, Opera 12...
Touch devices compatibility (IE Windows Phone, Android, Apple iOS, touch desktops...)
It provides many other useful options and callbacks.
I want to create a webpage that contains several sections. In one of those sections are something like progress bars. These progress bars are 'animated' so that the user sees them loading on the screen as shown in the example.
Example here
Now this is working as it is but my problem is this:
I want the progress bars to start loading when the bars become visible on the screen.
Once the user scrolls down and gets them in the middle of the screen, the 'animation' should start. The way it is now the animation starts on page load, but the bars are not yet visible as in the following fiddle:
Fiddle
A little extra would be that each bar starts loading after the previous is finished.
I found some similar questions on stack but the answer does not suffice to my needs:
Animate progress bar on scroll & Run animation when element is visible on screen
I tried stuff like (it's not the actual code but it's what I remember of it):
var target = $("#third").offset().top;
var interval = setInterval(function() {
if ($(window).scrollTop() >= target) {
//start loading progress bar
}
}, 250);
But without any good results.
Can anyone help me on this matter?
Thanks in advance!
Here is a fiddle: http://jsfiddle.net/rAQev/4/
I've used a comparison of scroll offset and your special section offset to detect a moment when this section becomes visible.
Animations are queued to be processed one after another using jQuery queue function, you can read about it in jQuery docs (http://api.jquery.com/queue/).
Also scroll event is unbinded when the first 'loading' happens, not to run 'loading' again and again on scroll event when section is visible.
Here is an updated fiddle http://jsfiddle.net/9ybUv/
This one allows for all the progress bars to run at the same time. If you were like me and had 5 or more it takes a long time to do one, then the next, then the next.
$(function() {
var $section = $('#third');
function loadDaBars() {
$(".meter > span").each(function() {
$(this)
.data("origWidth", $(this).width())
.width(0)
.animate({
width: $(this).data("origWidth")
}, 1200);
});
}
$(document).bind('scroll', function(ev) {
var scrollOffset = $(document).scrollTop();
var containerOffset = $section.offset().top - window.innerHeight;
if (scrollOffset > containerOffset) {
loadDaBars();
// unbind event not to load scrolsl again
$(document).unbind('scroll');
}
});
});
Let me try something
function startProgressBar() {
$(".meter > span").each(function() {
$(this)
.data("origWidth", $(this).width())
.width(0)
.animate({
width: $(this).data("origWidth")
}, 1200);
});
}
$(window).scroll(function() {
var target = $('#third');
var targetPosTop = target.position().top; // Position in page
var targetHeight = target.height(); // target's height
var $target = targetHeight + targetPosTop; // the whole target position
var $windowst = $(window).scrollTop()-($(window).height()/2); // yes divided by 2 to get middle screen view.
if (($windowst >= $targetPosTop) && ($windowst < $target)){
// start progressbar I guess
startProgressBar();
}
});
Give it a try, let me know.