jQuery How to Animate Repeatadly [duplicate] - javascript

I am working with a single div with an image inside. I need the animation to scroll from right-left of the page and then comeback to the right and continue in a loop. I have looked over many posts on here but am not able to get the script working properly.
'$(document).ready(function(){
function loop() {
$('#clouds').animate({left: '+=1400',},50000, 'linear', function(){
loop();
});
HTML
< div id="clouds">< img border="0" alt="animated clouds" src="/images/clouds.png" />< /div>
CSS
#clouds {
position:absolute;
z-index:500;
right:0px;
top:10px;
}

Try this:
JSFiddle http://jsfiddle.net/2YqH2/
You're not moving the clouds back to the right side. Inside the loop function, I added
$('#clouds').css({right:0});
and the loop will continue from there. I also changed your animation to animate the "right" property since you said you wanted the clouds to move from right to left.
Also, your javascript was not well-formed. Make sure you get those closing braces and parentheses! Here's the fixed javascript.
$(document).ready(function() {
function loop() {
$('#clouds').css({right:0});
$('#clouds').animate ({
right: '+=1400',
}, 5000, 'linear', function() {
loop();
});
}
loop();
});

All the above answers are somewhat 'hack' solutions.
According to the jQuery documentation for animate(), the second paramter is an options object which has a parameter complete; a function that is called when the animation completes.
In OP's case, this option object would be configured as follows:
function loop() {
$('#clouds').css({right:0});
$('#clouds').animate({
right: '+=1400',
}, {
duration: 5000,
easing: 'linear',
complete: loop
});
}
loop();

Just to add some info to others, if you're not going to use animate() you should use some setTimeout() to prevent the error Uncaught RangeError: Maximum call stack size exceeded
Example(Using jQuery):
.js
function looping() {
$('.loader').fadeOut(1000);
$('.loader').fadeIn(1000);
setTimeout(function(){
looping();
}, 10);
}
.html
<div class='loader'>Loading...</div>

JAVASCRIPT:
$(document).ready(function() {
$('#clouds').click(function() {
loop();
});
function loop(){
alert('a');
$('#clouds').animate({
opacity: 0.25,
left: '+=1400',
height: 'toggle'
}, 5000, 'linear', function() {
loop();
});
}
});
HTML:
<div id="clouds"><img border="0" alt="animated clouds" src="../img/image.png" /></div>
your error is that you are not calling the function loop never. look how it works, you can remove the alert('a') because it's just a flag to know that the cycle start over. now you need to make the reverse movement (like reset the div, to start over the movement cycle).

Related

Rearranging js to accommodate more flexibility

How can I make this js affect only the child elements of the original hovered element without giving all of the individual .g_scroll or .left/.right tags id's?
function loopRight(){
$('.g_scroll').stop().animate({scrollLeft:'+=20'}, 'fast', 'linear', loopRight);
}
function loopLeft(){
$('.g_scroll').stop().animate({scrollLeft:'-=20'}, 'fast', 'linear', loopLeft);
}
function stop(){
$('.g_scroll').stop();
}
$('#right').hover(function () {
loopRight().children();
},function () {
stop();
});
$('#left').hover(function () {
loopLeft();
},function () {
stop();
});
JSfiddle for (confusing, but necessary) html structure: https://jsfiddle.net/6rbn18cL/
To demonstrate how it would have to be renamed: https://jsfiddle.net/z9u3azqy/
So here, I "merged" both arrow handlers.
Then, there is a calculation needed to determine the "scroll" speed, based on width to be scrolled, which may no always be 100% of the element's width.
This script allows you to easily determine a speed for 100% scrolling.
Then, it calculates the speed if there is already a distance scrolled.
$(document).ready(function(){
function moveit(arrow){
// Adjust you delay here
var delay = 2000; // delay to scroll 100%
var animationDelay;
var slider = arrow.siblings(".g_scroll");
var distance = slider.width();
var scrolled = slider.scrollLeft()+1; // +1 is to avoid infinity in the math below
if(arrow.hasClass("scroller_l")){
distance = -distance;
animationDelay = -distance * (-distance/delay)*(-distance+scrolled);
}else{
animationDelay = distance * (distance/delay)*(distance-scrolled);
}
slider.stop().animate({scrollLeft:distance}, animationDelay, 'linear');
}
function stop(arrow){
arrow.siblings(".g_scroll").stop();
}
$('.scroller_l, .scroller_r').hover(function(){
moveit($(this));
},function() {
stop($(this));
});
}); // ready
CodePen
--First answer--
First, you can't use the same id more than once.
So I removed id="left" and id="right" from your HTML.
Now the trick is to pass which arrow is hovered to your functions, using $(this).
And find the .g_scroll element which is a sibling of it.
$(document).ready(function(){
function loopRight(arrow){
arrow.siblings(".g_scroll").stop().animate({scrollLeft:'+=20'}, 'fast', 'linear', loopRight);
}
function loopLeft(arrow){
arrow.siblings(".g_scroll").stop().animate({scrollLeft:'-=20'}, 'fast', 'linear', loopLeft);
}
function stop(arrow){
arrow.siblings(".g_scroll").stop();
}
$('.scroller_r').hover(function(){
loopRight($(this));
},function() {
stop($(this));
});
$('.scroller_l').hover(function(){
loopLeft($(this));
},function() {
stop($(this));
});
});
CodePen
You can pass the event object and find the proper container from there.
$('.scroller_l').hover(loopRight, stop);
$('.scroller_r').hover(loopLeft, stop);
This is done automatically if you pass functions as parameters like the above.
To find the scrolling container dynamically for each instance you can use the classes to find the container relative to the current target:
var el = $(ev.currentTarget),
parent = el.closest('.country_holder'),
container = parent.find('.g_scroll');
See a working example here.
At this point you can ask yourself whether loopRight and loopLeft can be combined in one function. The only difference is the '-=20' and '+=20'.
With polymorphism you can refactor this even further.

unable to setTimout on .animate

Currently im trying to set a page so that on click of a button one div .animates up and another .animates down in the place the old div was which has been successful. The problem is they both do this at the same time making the animation a bit messy. What I want to do is have the animation pause for about 2 seconds just after the first div has moved up and then bring down the second div. Here is my code so far:
$(document).ready(function() {
$('.aboutcontainer,.contactcontainer,.homecontainer,.portfoliocontainer,.musiccontainer').hide();
});
$(document).ready(function() {
$(".homecontainer").show();
});
$(document).ready(function() {
$('#about').click(function go() {
$('.homecontainer,.musiccontainer, .portfoliocontainer, .contactcontainer').fadeOut({
queue: false,
duration: 'slow'
});
$('.homecontainer, .musiccontainer, .portfoliocontainer, .contactcontainer').animate({
'margin-Top': "-1000px" //moves left
});
$('.aboutcontainer ').fadeIn({
queue: false,
duration: 'slow'
});
$('.aboutcontainer').animate({
'margin-Top': "115px" //moves left
});
});
});
I have tried inserting a .delay(2000)just before the .fadeIn here:
$('.aboutcontainer ').fadeIn
and another one before the .animate here:
$('.aboutcontainer').animate
.delay does not seem to work at all (im using the lates jQuery version)
The weird thing is I have tried using a setTimeout() function like so:
setTimeout(function() {
$('.aboutcontainer ').fadeIn({
queue: false,
duration: 'slow'
});
$('.aboutcontainer').animate({
'margin-Top': '115px' //moves left
});
}, 2000);
When I do the .fadeIn pauses for the 2 seconds but the .animate does not. Can someone please let me know what im doing wrong here?
At your site .aboutcontainer has margin-top: 115px; at main.css:131.
So animation from margin-top: 115px; to margin-top: 115px; actually does nothing.
You can set, for example, margin-top: -1000px for .aboutcontainer and see the animation in action.
You are missing the time paramater for animation,
Try to add the timing for animation like below.
setTimeout(function() {
$('.aboutcontainer ').fadeIn({
queue: false,
duration: 'slow'
});
$(".aboutcontainer").animate({
marginTop: "115px",
}, 750);//Look at here..
}, 2000 );
here is the jsfiddle, check it http://jsfiddle.net/ganeshgaxy/d6g1empb/

How to replace a CSS3 transition

I'm trying to apply a CSS transition to an element, but at some point before it completes, remove the transition entirely and start another one.
This question answers how to stop a transition in its tracks, but I modified the jsFiddle there to illustrate the issue:
http://jsfiddle.net/zXVLd/
var $div = $('div');
$div.click(function(){
$div.css({
left: 0,
transition: 'none'
});
$div.transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
What I want to happen is for the box to reset its position and move down when clicked, and for the completed handler on the first transition to not fire.
What does happen is the box resets its position when clicked, but doesn't move down until the first transition completes (even though the motion from the first transition is no longer happening). The completed handler still fires on the first transition as well.
I've updated your fiddle with the clearQueue method: http://jsfiddle.net/zXVLd/1/
var $div = $('div');
$div.click(function(){
$div.clearQueue().css('left', $div.css('left')).transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
That does the trick. See http://api.jquery.com/clearQueue/ for more information on the clearQueue method.
To do this kind of animations, you can try to use GSAP's TweenLite. It's incredible what you can achieve with it. http://www.greensock.com/jump-start-js/ If you include this on your page and add the following code:
div.bind('click', function(e) {
// note that you can animate two directions, from and to
TweenLite.from(div /*element*/, 0.2 /*easing in seconds*/, {
// the css, but for positioning elements you can also use x and y.
x: 600,
easing: linear,
onStart: function() {
Stuff you want to do before the animation
},
onComplete: function() {
Stuff you want to do after animationg
}
});
});
The plugin which you use is using queue. So, it is just enough to call $div.dequeue(); I.e.
var $div = $('div');
$div.click(function(){
$div.dequeue();
$div.css({
left: 0,
top: 0,
transition: 'none'
});
$div.transit({
top: 600,
},5000);
});
function complete(){
$div.css('backgroundColor', 'blue');
}
$div.transit({left: 600}, 5000, 'linear', complete);
fiddle -> http://jsfiddle.net/krasimir/zXVLd/2/

Jquery animate isn't animating

I'm working on a web site that uses the jquery animate function to expand the web site from the top left corner when it is loaded. I wasn't actually the one who wrote the code for that feature so I'm not overly familiar with it. It did work at one point but at the moment it doesn't seem to be working at all. I know the .js file is being loaded and is running because the first bit of code in it is a time delay that shows a "Page is being loaded" message. But then it just shows the page already loaded instead of animating the page appearing from the top left and sliding in. I included the CSS and mark up also although I don't believe that's where the problem lies. Any help would be appreciated! Thanks!
Note: We're using Jquery version 1.7.2
The CSS:
#builder
{
position:relative;
min-height:100%;
min-width:100%;
z-index:999;
}
The JavaScript:
function hideIt() {
document.getElementById("wait").style.display = "none";
}
setTimeout("hideIt()", 1000);
function showIt() {
document.getElementById("builder").style.display = "block";
}
setTimeout("showIt()", 2500);
function build() {
$(document).ready(function () {
$("#builder").animate({ height: '0%', width: '0%' }, 1);
$("#builder").animate({ height: '100%', width: '100%' }, 2000);
});
}
The mark up:
<body onLoad="build()">
<img src="wait.gif" id="wait" style="display:block;" />
wait.gif is just a picture that says "page is loading"...
And the page is wrapped in these:
<div id="builder" align=center style="display:none;">
If the #builder element is hidden for 2.5 seconds before it's shown, the animation will be completed by the time the element is shown. Remove the inline function on body onLoad and try:
function hideIt() {
$("#wait").hide();
}
function showIt() {
$("#builder").show(2000); //should do somewhat the same as animating from the top left
}
$(function() {
setTimeout(hideIt, 1000); //no need to quote the functions and eval them
setTimeout(showIt, 2500);
});
or just
$("#wait").delay(1000).hide(10);
$("#builder").delay(2500).show(2000)
Likely that it's being animated long before your show() is invoked. So by the time it's displayed, the animation is done.
Try adjusting your code like so:
$(document).ready(function() {
$('#wait').hide(1000, function(){ // hide the #wait
$("#builder").show().animate({ // then show, then animate #builder
height: '100%',
width: '100%'
}, 2000);
});
});
Side Note: Remember that when you're using percentages and the element containing #builder, also needs to have it's height and width set.

jQuery rebind function

I want to have a div that animates the currently active image out of the view and instead animates in another image. There are several of these divs, and each one should have the same basic functionality but linked to different images. The problem I'm having is that you can click many of the divs before the animation is complete, which fires the other animations at the same time. My goal is to only be able to fire one animation at a time, and when the animation finishes you're able to fire the next animation. I've tried using unbind which works OK but then I'd have to rebind it later and I don't know how to do this. I'm really a jQuery noob so I would greatly apreciate an answer. Thanks!
My code:
$('.div1').click(function clickevent() {
$('.img2, .img3').animate({
opacity: 0.1,
left: 600
}, 1000, function() {
$('.img1').animate({
opacity: 1,
left: 0
}, 500, function() {
$('.div2, .div3').bind('click', clickevent); /* Here I want to rebind the function */
});
});
$(this).addClass("active");
$('.div2, div3').removeClass("active");
$('div2, .div3').unbind('click', clickevent);
});
I have two other codeblocks for .div2 and .div3 which look the same but with different classes in different places. Is there any way to make the images finish their animation before being able to animate again? Thanks.
Is this what you need:
var canAnimate = true;
$('.div1').click(function clickevent() {
// these 4 lines have to be in all code blocks (ie. for .div2 and .div3)
if (! canAnimate) {
return;
}
canAnimate = false;
$('.img2, .img3').animate({
opacity: 0.1,
left: 600
}, 1000, function() {
$('.img1').animate({
opacity: 1,
left: 0
}, 500, function() {
canAnimate = true; // this should also be included for .div2 and .div3 code blocks
});
});
$(this).addClass("active");
$('.div2, div3').removeClass("active");
});
I think queue() will append the animations but not stop them, so if you click 10 times on the images, the click handler will animate it 10 times but one after another. I guess you want only animate the images when no image is currenty animated so you can use:
$('.div1').click(function clickevent() {
// When no image is currently animated then perform the animation
if($j('.img1, .img2, .img3').is(':animated') == false)
{
$('.img2, .img3').animate({
opacity: 0.1,
left: 600
}, 1000, function() {
$('.img1').animate({
opacity: 1,
left: 0
}, 500);
});
$(this).addClass("active");
$('.div2, div3').removeClass("active");
} else {
// There is currently an animation runnig, do nothing
}
});
See this for more information: http://api.jquery.com/animated-selector/
You should also get some information about caching of selection results.

Categories

Resources