so i have tried making myself an infinite carousel using html, css & jQuery and everything is working apart from the back button will not loop, i've spent quite a while doing this now and i'm wondering if anyone has any insight? http://jsfiddle.net/e2SKk/ is where you can see the code! i'm only really doing this because i thought it would give me a chance to learn a lot more, but any criticisms of code layout or technique would be helpful!
specifically its this code thats seems not to work
else if(loopPrev==true){
sliderActive=true
$('.item-holder').css({
'left':clonePos
});
$('.item-holder').animate({
'left':holderPos+$('.slider').width()+'px'
},function(){
sliderActive=false;
});
};
that is only a snippet btw and won't make much sense without the rest!
jQuery is cool to write short scripts.
Your slider code in short:
var width = $('.slider').width();
$('.item').css({width:width});
var $holder = $('.item-holder').css({left:-width}).prepend($('.item:last'));
$('.prev').click(function(){
$holder.not(':animated').css({left:-2*width}).prepend($('.item:last')).animate({left:-width});
});
$('.next').click(function(){
$holder.not(':animated').css({left:0}).append($('.item:first')).animate({left:-width});
});
That's the complete code.
See this in action on http://jsfiddle.net/creativecouple/YPU2d/
Pretty cool little slider you have going here! You say you are a beginner? I'd say you've picked up on jQuery quite well! Also before I forget, addressing your comment: if you post something on stackoverflow...it WILL be viewed, likely by many people :). It's rare to come here and receive no help (albeit you may not always get an answer).
Fortunately for you, I've found your problem! It's right here:
else if(loopPrev==true){
sliderActive=true
$('.item-holder').css({
'left':clonePos
});
$('.item-holder').animate({
'left':holderPos+$('.slider').width()+'px'
},function(){
sliderActive=false;
});
};
You are checking whether or not to loop, setting the slider to active, setting the next slide to the last slide in the index (and subsequently pushing it to that at the same time), then you animate as you normally would. This results in two movements: first to the back of the index, then to the value of holderPos+$('.slider').width()+'px'...hence your strange behaviour. This should help:
else if(loopPrev==true){
sliderActive=true;
$('.item-holder').animate({
'left':"-1800px"
}, function(){
sliderActive=false;
})
};
The value "-1800px" is just the last slide in your buffer that I precalculated...you should be able to replace it with your clonePos variable without trouble.
*EDIT: You should also change your variable clonePos to look like this:
var clonePos = '-'+($('.item').index()-1)*($('.slider').width());
It will eliminate a bug when you swap between the last slide in the index and the first slide (a "smooth transition" if you will).
**
Part II
**
In order to achieve the illusion of infinite scrollability you will need to embed a callback "push back" function inside the "left pressed" animation call. It's late here so I haven't tested the code I am about to write but I'm fairly confident it will work for you.
else if(loopPrev==true){
sliderActive=true;
$('.item-holder').animate({
'left':clonePos
}, function(){
$(this).css('left':holderPos+$('.slider').width()+'px');
sliderActive=false;
})
};
If you take a look this isn't much different from the original answer I offered. All we have done is take the callback function for animate, and added a call to slip the position to the original index position. Again, untested, but the idea is that .animate() will slide to the clone, once that is done your callback will swap the clone with the original, and then deactivate the slider.
You weren't very far off! Here's a semantic rule of the animate function (to attempt to help your understanding of the way a callback works):
animate( params, [duration], [easing], [callback] )
params is our left call (to the cloned slide in this case)
duration is ignored here
easing is ignored here
callback is our function() call that does our little david copperfield swap
Hope this helps!
Related
is a more efficient way of writing this?
I am not great with js and trying to learn how to run multiple effects on a single element after each effect is complete. ie increase div height then fade out after a delay.
I would also be interested to see how the code changes if i wanted to run multiple effects at the same time but one thing at a time.
Below code runs fine but I am not sure if I should be doing it that way.
Here is a fiddle im playing with http://jsfiddle.net/kaigan/qr2BJ/
var el = $('system-message-container');
(function(){
el.tween('height', [20, 200]);
})
.delay(2000);
(function(){
el.fade('out').get('tween', {duration: 'long'})
})
.delay(4000);
I'm trying to call for a jQuery function when my Flash Canvas animation ends. I can't seem to figure out what code I need to add on that last keyframe in order to do that. I found something like this but it's not working:
this.stop();
ExternalInterface.call("javascript:start_website();");
Thanks in advance!
I managed to find a solution from browsing a few other websites. Basically at the end of my animation on the very last keyframe I added this bit of code:
this.animation_tracker = function() {
start_website();
return false; // prevent the function from being run over and over again
}
exportRoot.animation_tracker();
And within my website I created a jQuery function called start_website(); where I placed all the actions that I wanted to have happen once my animation was over.
in flash canvas you are already programming in javascript (and other js libraries flash uses), so you can't use and don't need the ExternalInterface.call and such.
You can and should call straight to the javascript function:
this.stop();
start_website();
Good luck!
I made an animation, and i want to add a callback function at the end of the animation loop.
Do you know how I can do that ?
Thx.
Glad to read you found your solution :)
You can find a complete example on the cgscenegraph website:
http://gwennaelbuchet.github.com/cgSceneGraph/examples/03_Animation/animation_01_SRT/index.html
There are other examples related to animation also: http://gwennaelbuchet.github.com/cgSceneGraph/examples.html
What you have to understand with the animation engine is that a timeline is generated for each couple node+property you want to animate. And it is this timeline that provides events related to the animation.
Here is an example to get the onAnimationEnd of a timeline:
this.sceneGraph.getTimeline(myNode, "rotation.angle").onAnimationEnd = function (event) {
console.log("animation ended");
};
To get onAnimationStart or onAnimate events, it's exactly the same :)
Hope this can help.
okay i found what i want,
there is a property named "onAnimationEnd" into the CGSGTimeline class that is fired at the end of the animation, so i've got my callback function ;)
for information, there are other callback functions like "onAnimate" & "onAnimationStart" in the cgSceneGraph framework.
link to http://gwennaelbuchet.github.com/cgSceneGraph/api.html
best regards.
How can I possibly delay the disappearance of the menu by some miliseconds/seconds?
going ahead and editing this fadesettings: {overduration: 350, outduration: 2000}in the js only changes the animation speed. But THAT IS NOT what I want =).
Please check this JSFiddle to see the JS, CSS, and HTML.
Thanks for the help guys
P.S:- about the top:80px gap that you see, I intentionally put it there cuz that's the way I'm styling my site so I want the gap there.
You can user the setTimeout function to add a delay before you call a function.
In your case, if you want to delay the fadeout of the menu, instead of just doing :
$this.children("ul:eq(0)").fadeOut(jquerycssmenu.fadesettings.outduration);
You could do
setTimeout(function() { $this.children("ul:eq(0)").fadeOut(jquerycssmenu.fadesettings.outduration)
}, 2000);
to delay the call by 2 seconds.
Note that I cached the $(this) selector in your fiddle to still be able to access the variable.
http://jsfiddle.net/KB5Ve/
EDIT :
Added comments on the fiddle : http://jsfiddle.net/DBvq7/
I am using Mootools extensively for a site which I am developing. But recently I noticed a problem that the animations slow down alot when I zoom (using the browsers Zoom In) in into the site. What could be a possible reason for this problem ? Or is this problem inherit in Mootools itself. This happens in Chrome 6.0.472 as well as Firefox 3.6.8.
Thanks,
Nitin
many things are wrong here with regards to speed optimisations.
lets take a look at this mouseover code that seems to slow down:
this.childNodes.item(1).style.left="0px";
this.getElements('div').setStyles({'opacity':'1'});
this.getElements('div').set('morph', {duration:'normal',transition: 'sine:out'});
this.getElements('span').set('morph', {duration:'normal',transition: 'sine:out'});
this.getElements('div').morph({'left':'-28px'});
this.getElements('span').morph({'left':'-30px','color':'#FFF'});
obviously this will work as it does but it's so very wrong i don't know where to begin.
the idea is to abstract and setup the repetitive tasks so they are done as a one off.
consider line by line the code above:
this.childNodes.item(1).style.left="0px";
this is wrong for a mootools app anyway, it would need to be this.getFirst().setStyle("left", 0);
the this.getFirst() is a lookup, it should be cached - although that's not a slow one.
then comes the bad part.
you select all child divs 3 times and all spans twice, where NO SELECTION should be applicable. VERY EXPENSIVE
you reset the Fx.morph options every mouseover event where there are no changes (although you seem to have a different duration for mouseenter and mouseleave - this is expensive)
consider this code:
[document.id("menu1"), document.id("menu2")].each(function(el) {
// use element storage to save lookups during events
el.store("first", el.getFirst());
el.store("divs", el.getElements("div"));
el.store("spans", el.getElements("span"));
// store the fx.morph options once and for all, no need to do so
// on every event unless you are changing something
el.retrieve("divs").set("morph", {
duration: 'normal',
transition: 'sine:out',
link: 'cancel'
});
el.retrieve("spans").set("morph", {
duration: 'normal',
transition: 'sine:out',
link: 'cancel'
});
// add the events
el.addEvents({
mouseenter: function(e) {
// retrieve the saved selectors from storage and do effects
this.retrieve("first").setStyle("left", 0);
this.retrieve("divs").morph({
"left": -28
});
this.retrieve("spans").morph({
'left': '-30px',
'color': '#FFF'
});
}
});
});
it will save a lot of processing on the events.
similarly, there are plenty of places where you are not really using the mootools api.
document.getElementById(curr).style.cursor="pointer";
$(this).removeEvents -> no need for $, this is not jquery.
document.getElementById("lightbox").style.visibility="hidden";
m=setTimeout('gallery()',5000); --> use the mootools var timer = (function() { ... }).delay(5000);, don't use strings with setTimeout/interval as it forces eval and reflows but pure anon functions
etc etc.
you really can make a day out of refactoring all this and making it 'nice' but it's going to be worth it.
also, learn about chaining
$("ribbon").set('morph', {duration:'long',transition: 'bounce:out'});
$("ribbon").morph({'top':'-10px'});
$("ribbon").addEvents({
this is calling up a selector 3 times. instead you can:
store it. var ribbon = $("ribbon"); ribbon.set...
chain it. $("ribbon").set("morph", {duration: 500}).morph({top:-10}).addEvents() - mootools element methods tend to return the original element so you can take the response of the last function and apply more to it.
1 is better for readibility, 2 is faster to do.
also. you have way too many global variables which makes your scope chain lookups more expensive, this will affect many call ups and places. try to namespace properly, if you need to access real global vars from functions and closures, use window.varname etc etc.
Another possible improvement here would be the use of event delegation (event bubbling will cause events to fire up the dom tree to the parents, mootools has an api to deal with it so you can add singular events to parent elements and not have to attach nnn events to all children) - look it up.
P.S. please don't take this in the wrong way - it's not meant to rubbish your work and it's just some constructive (i hope) advice that can help you bring it to the next level. good luck :)
I haven't seen any specific code in MooTools or any other library that checks if browser is zooming during animation, so I think that animation slows down, since browser using more CPU for computing zooming process.