I am trying out the snow-fall animation. I want to stop it after for e.g. 5 seconds. I have current add the animate between setTimeOut, somehow there's no effect. What am I missing here?
Current code:
function fallingSnow() {
var snowflake;
snowflake = $('<div class="snowflakes"></div>');
$('#snowZone').prepend(snowflake);
snowX = Math.floor(Math.random() * $('#site').width() / 4);
snowSpd = Math.floor(Math.random() + 50000);
snowflake.css({
'left': snowX + 'px'
});
setTimeout(function(){
snowflake.stop().animate({
top: "700px",
opacity: "5",
}, snowSpd, function () {
$(this).remove();
fallingSnow();
})
},5000);
}
timer = Math.floor(Math.random() + 1000);
window.setInterval(function () {
fallingSnow();
}, timer);
UPDATE: AFTER UTILIZING #Kyojimaru's answer.
snowflake.animate({
top: "700px",
opacity: "5",
}, 5000, function () {
$(this).remove();
if(!end) {
fallingSnow();
window.setTimeout(function () {
clearInterval(interval);
end = true;
}, 5000);
}
}
);
updated fiddle
it's because your setInterval never stopped from calling fallingSnow, try changing your code to this
var firstCall = false;
var interval, timeout;
function fallingSnow() {
var snowflake;
snowflake = $('<div class="snowflakes"></div>');
$('#snowZone').prepend(snowflake);
snowX = Math.floor(Math.random() * $('#site').width() / 4);
snowSpd = Math.floor(Math.random() + 50000);
snowflake.css({
'left': snowX + 'px'
});
if(!firstCall) {
timeout = setTimeout(function(){
clearInterval(interval);
},5000);
firstCall = true;
}
}
timer = Math.floor(Math.random() + 1000);
interval = setInterval(function () {
fallingSnow();
}, timer);
basically what you need is clearing the interval that has been set for the function fallingSnow() using clearInterval only on the first time the function is called using setTimeout
here's the other example about it with what you want to do : JSFIDDLE
and here's what probably happen to you now : JSFIDDLE
EDIT
based on your fiddle here ( need to add jQuery and snowflakes css width and height to anything beside 0px )
your problem is you declare in the script as
var firstTime = false;
but checking it with
if (!firstCall)
so you need to change var firstTime = false; to var firstCall = false;
the other problem arise from this code here
snowflake.animate({
top: "700px",
opacity: "5",
}, snowSpd, function () {
$(this).remove();
fallingSnow();
});
which call the fallingSnow(); function again when animate finished, thus the snow is never stop falling, so you need to check if the the setTimeout have already clear the interval or not, you need to change your code to this
snowflake.animate({
top: "700px",
opacity: "5",
}, snowSpd, function () {
$(this).remove();
if(!end) {
fallingSnow();
}
});
if (!firstCall) {
timeout = setTimeout(function () {
clearInterval(interval);
end = true;
}, 5000);
firstCall = true;
}
and add var end = false; in the start with firstCall
here's the working one : JSFIDDLE
Related
I build a jquery carousel. But when I do fast Swiperight or left for interval will interfere and work fastly. How can I fix this?
Here is uploaded project
I have settings variable in setting interval is time for Setinterval and items are my images, Slide is active image to show, Clock is my Setinterval Function.
when slide change I clear clock variable and after then set it with time out to user can view the slide and slide does not change.
var settings = $.extend({
interval: 5000,
element: this.selector,
items: ['images/1.jpg','images/2.jpg','images/3.jpg'],
slide: 0,
clock: 0,
}, options);
// Touch
$(settings.element + ' .primary img').on("swiperight", function () {
nextSlide();
pauseInterval();
setTimeout(function () {
if (!settings.clock)
settings.clock = setInterval(nextSlide, settings.interval)
}, 4000);
}).on("swipeleft", function () {
prevSlide();
pauseInterval();
setTimeout(function () {
if (!settings.clock)
settings.clock = setInterval(prevSlide, settings.interval)
}, 4000);
});
// Next Slide
function nextSlide() {
settings.slide++;
if (settings.slide >= settings.items.length) settings.slide = 0;
$(settings.element + ' .primary img').attr('src', settings.items[settings.slide]).attr('data-slide', settings.slide);
activeThumbnail()
}
// Prev Slide
function prevSlide() {
settings.slide--;
if (settings.slide < 0) settings.slide = settings.items.length;
$(settings.element + ' .primary img').attr('src', settings.items[settings.slide]).attr('data-slide', settings.slide);
activeThumbnail()
}
//Pause Interval
function pauseInterval() {
clearInterval(settings.clock);
settings.clock = 0;
}
You will find it simpler to work with setTimout() exclusively instead of a mix of setTimout() and setInterval().
There's no unique way to write the code. Here's one :
var settings = $.extend({
'delay': {
'long_': 9000, // (4000 + 5000) after swiping
'short_': 5000 // auto
},
'element': this.selector,
'items': ['images/1.jpg', 'images/2.jpg', 'images/3.jpg'], // array of Strings
'slide': 0,
'clock': null
}, options);
$(settings.element + ' .primary img').on('swiperight', nextSlide).on('swipeleft', prevSlide); // nice and simple
// nextSlide() and prevSlide() ...
// in auto: `delay` will be `settings.delay.short_`.
// on manual swipe: `delay` will be `undefined` and will default to `settings.delay.long_`.
function nextSlide(delay) {
delay = (delay === undefined) ? settings.delay.long_ : delay;
settings.slide = (settings.slide + 1) % settings.items.length;
set(nextSlide, delay);
}
function prevSlide(delay) {
delay = (delay === undefined) ? settings.delay.long_ : delay;
settings.slide = (settings.slide + settings.items.length - 1) % settings.items.length;
set(prevSlide, delay);
}
// set() does all the stuff common to nextSlide() and prevSlide().
function set(action, delay) {
$(settings.element + ' .primary img').attr('src', settings.items[settings.slide]).attr('data-slide', settings.slide);
activeThumbnail();
clearTimeout(settings.clock); // relevant only after a manual swipe, but does no harm in auto.
settings.clock = setTimeout(action.bind(null, settings.delay.short_), delay);
}
What I would like to do is set each BannerImg element to display: none one at a time using a timer setup. Then, once I have looped through all BannerImg elements, I want to reset them to display: block. It's basically like a image rotator that I'm trying to make...but right now, I'm not sure how to target each BannerImg element one at a time--I am targeting them all at once, which is not what I want to do.
jQuery.noConflict();
(function($) {
$(document).ready(function() {
var BannerCount = $('BannerImg').length;
var intervalID = window.setInterval(function() {
$('.BannerImg').toggleClass("HideBannerImg");
}, 2000);
});
}(jQuery));
Use .eq(index). You'll probably want to cache your collection to make it faster:
(function($) {
$(document).ready(function() {
var $banners = $('.BannerImg');
var index = 0;
var intervalID = window.setInterval(function() {
$banners.eq(index).toggleClass("HideBannerImg");
index++;
// Check to see if we've hit the end of the collection
// If so, stop the interval.
if (index === $banners.length) {
clearInterval(intervalID);
}
}, 2000);
});
}(jQuery));
I'm kind of guessing you want something like this (correct me if I'm wrong):
setInterval(function () {
if ($('.BannerImg').last().hasClass('HideBannerImg')) {
$('.HideBannerImg').first().removeClass('HideBannerImg');
} else {
$('.BannerImg').not('.HideBannerImg').first().addClass('HideBannerImg');
}
}, 1000);
jQuery.noConflict();
(function($) {
$(document).ready(function() {
var iterator = 0;
var BannerCount = $('BannerImg').length;
var intervalID = window.setInterval(function() {
$('.BannerImg').eq(iterator).toggleClass("HideBannerImg");
iterator += 1;
if (iterator === BannerCount.length - 1) {
clearInterval(intervalID);
$('.BannerImg').removeClass("HideBannerImg");
}
}, 2000);
});
}(jQuery));
try this recursive function
var images = $('.BannerImg').each();
var hideImage = function(index){
images[index].toggleClass("HideBannerImg");
if(index < images.length-1)
setTimeout(function(){
hideImage(index++);
}, 2000);
}
hideImage(0);
After calling $('.BannerImg') you need to use jQuery's each to loop over each of the elements it selected.
jQuery.noConflict();
(function($) {
$(document).ready(function() {
$('.BannerImg').each(function() {
var $this = $(this);
var intervalID = window.setInterval(function() {
$this.toggleClass("HideBannerImg");
}, 2000);
});
});
}(jQuery));
Just note that this will toggle on and off over and over until you clear the interval.
http://jsfiddle.net/9DP2d/
setInterval(toggleredBox, 1000);
setInterval(toggleorangeBox, 1000);
setInterval(toggleyellowBox, 1000);
var toggleredBox = function toggleredBox() {
$(".redBox").slideToggle(1000);
};
var toggleorangeBox = function toggleorangeBox() {
$(".orangeBox").slideToggle(1000);
};
var toggleyellowBox = function toggleyellowBox() {
$(".yellowBox").slideToggle(1000);
};
So the problem is that all 3 boxes are firing all at once: is there any way to get them to go one after another simultaneously?
Can do it like this:
setInterval(toggleredBox, 3000);
var toggleredBox = function toggleredBox() {
$(".redBox").slideToggle(1000);
setTimeout(toggleorangeBox, 1000);
};
var toggleorangeBox = function toggleorangeBox() {
$(".orangeBox").slideToggle(1000);
setTimeout(toggleyellowBox, 1000);
};
var toggleyellowBox = function toggleyellowBox() {
$(".yellowBox").slideToggle(1000);
};
Can also have another setTimeout in the last function and simply call the function where you want the animation to start.
fiddle
You can use setTimeout do delay the start:
setInterval(toggleredBox, 1000);
setTimeout(function(){
setInterval(toggleorangeBox, 1000);
}, 1000):
setTimeout(function(){
setInterval(toggleyellowBox, 1000);
}, 2000):
You can also use a single interval for all three, and use a counter to check when to toggle them the first time:
setInterval(toggleBoxes, 1000);
var cnt = 0;
function toggleBoxes() {
$(".redBox").slideToggle(1000);
if (cnt > 0) $(".orangeBox").slideToggle(1000);
if (cnt > 1) $(".yellowBox").slideToggle(1000);
cnt++;
};
Demo: http://jsfiddle.net/9DP2d/2/
To try to implement the "one after the other simultaneously" (whatever that means):
setInterval(toggleredBox, 1000);
var toggleredBox = function() {
$(".redBox").slideToggle(1000, toggleorangeBox);
};
var toggleorangeBox = function() {
$(".orangeBox").slideToggle(1000, toggleyellowBox);
};
var toggleyellowBox = function() {
$(".yellowBox").slideToggle(1000);
};
I have this code:
function CreateAndAnimateEnemyImg() {
var nh = Math.floor(Math.random() * w + 30);
var enemy = document.createElement('img');
enemy.src = 'enemy.jpg';
enemy.className = 'Enemy';
pane.append(enemy);
enemy.onload = function () {
enemy.style.top = nh + 'px';
}
}
$("#Start").click(function () {
var x = setInterval(function () {
CreateAndAnimateEnemyImg();
$('.Enemy').animate({ 'left': '-=20px' });
time--;
}, 20);
if (time == 0) {
timeElapsed = true;
clearInterval(x);
}
});
And this is the jsfiddle
I know my logic is wrong and I want u to help me to fix my problem on click an new image should be created and animated and a a counter should be initialize when the counter is set to 0 the creation of the new images should be stopped but the created images should still animate to left -20px
i have changed the position of the clear interval and adde some condition check
if (time > 0) {
$('.Enemy').animate({ 'left': '-=20px' });
time--;
console.log(time);
if(time == 0){
timeElapsed = true;
clearInterval(x);
}
}
check here Fiddle
Modified the Start click handler little bit. Enemy animate is moved to its own timer and inside the create new enemies interval added check to see if created time reached max.
Here is the new code, updated fiddle demo
$("#Start").click(function () {
intervalPoint = setInterval(function () {
CreateAndAnimateEnemyImg();
time--;
if (time == 0)
StopTimer();
}, 20);
setInterval(function () {
$('.Enemy').animate({ 'left': '-=20px' });
}, 20);
});
function StopTimer(){
timeElapsed = true;
clearInterval(intervalPoint);
time = 3;
}
I'm trying to write a JS timer that will be triggered by a user click on the button with id="start".
I've got the timer itself working correctly, but when I try to add code to initiate the timer on the button click (id="start") I break it and am not sure why.
Any help would be greatly appreciated!
Here is the JS code:
$(document).ready(function(){
var count = 0;
$('#start').click(function(){
setInterval(function(){
count++;
$('#timer').html(count + ' tacos seconds');
},1000);
});
});
$(document).ready(function() {
$('#start').click((function(container) {
var interval;
return function() {
if(interval) clearInterval(interval);
var count = 0;
interval = setInterval(function() {
count++;
$(container).html(count + ' tacos seconds');
}, 1000);
};
})("#timer"));
});
$(document).ready(function() {
var count = 0;
var myInterval = null;
$('#start').click(function(){
myInterval = setInterval(function(){
count++;
$('#timer').html(count + ' tacos seconds');
},1000);
});
});
When setting your setInterval in the scope of the click handler, try assigning it to a variable to hold the interval declared up a level. This has typically always worked for me.
Not sure exactily what your objective is, but maybe you'd want to try something like this:
var startInterveal;
var timerStarted = false;
var count =0;
$(document).ready(function () {
$('#start').click(function () {
if (!timerStarted) {
timerStarted = true;
count =0;
$(this).attr('disabled', 'disabled');
startInterveal = setInterval('tick();', 1000);
}
});
});
function tick() {
count++;
$('#timer').html(count + ' tacos seconds');
}
Here is a 2nd answer if you really want to go nuts and have something resuable:
$(document).ready(function() {
$('#start').click(overboard("#timer"));
$('#start2').click(overboard("#timer2"));
});
function overboard(container) {
var interval;
return function() {
if (interval) clearInterval(interval);
var count = 0;
interval = setInterval(function() {
count++;
$(container).html(count + ' tacos seconds');
}, 1000);
};
}