I'm working on a project with a push menu. When the content div slides over, the menu buttons have a little animation as they enter the screen. It doesn't take long or anything but the issue I'm having is if the user opens and closes the menu quickly a bunch of times in a row, the items on the list begin disappearing and reappearing in the wrong order. I think this is because the new animation calls are canceling out old ones and in general screwing up the order of things.
Ideally, I'd like the animations to always behave properly (i.e. if the menu is opening, clear all previous animations and play the opening animation only).
But I'd be satisfied if I could at least get each element to queue its animations properly so that the elements in the menu don't randomly disappear upon opening the menu.
Here is a fiddle of the problem:
http://jsfiddle.net/9t10zr6m/1/
The top div is transparent because it normally has a background image. And also because I thought it might be easier to see the problem with the menu if you could see what was going on underneath the top div.
here is the relevant jQuery code:
$(document).ready(function() {
$(".expandable-content").on('click', function(){
$(this).children(".internal-content").slideToggle();
});
$(".menu-button").on('click', function(){
var position = $(".blue-box").css("left");
if( position == "0px") {
$(".blue-box").velocity({left: "250px"}, 500);
$('.side-nav-link').finish();
$('.side-nav-link').velocity('transition.slideUpIn', { stagger: 50 });
} else {
$(".blue-box").velocity({left: "0px"}, 500);
$('.side-nav-link').finish();
$('.side-nav-link').velocity('transition.slideDownOut', { stagger: 50 });
}
});
});
and the relevant html:
<div class="blue-box">
<h1>Julian Ptak</h1>
<h2>Kempis Coder. Simplicity. Purity.</h2>
<div class="menu-button"><img class="button-icon" src="img/menu-icon.png"><p class="button-text">Menu</p></div>
</div>
<div class="red-box">
<ul class="side-nav">
<li class="side-nav-link">Home</li>
<li class="side-nav-link">Work</li>
<li class="side-nav-link">Hobbies</li>
<li class="side-nav-link">Writings</li>
<li class="side-nav-link">Code</li>
<li class="side-nav-link">Contact</li>
</ul>
</div>
How do you make jQuery enqueue animations? Or only play the right animation for the right click and skipping all previous ones?
I tried .finish() and .stop() but neither seemed to fix my problem. Any ideas? Do those not work with velocity.js?
Very long question!!
I don't get what you want, but according to some keywords in your question i will give you some Velocity features:
Velocity add animations to its queue by default!
$elm.velocity({ /* 1 */ },{});
$elm.velocity({ /* 2 */ },{});
in this example at the end of first animation second animation will start.
$elm.velocity({ /* 1 */ },{});
$elm.velocity({ /* 2 */ },{queue: false});
in this example both animations start together.
$elm.velocity('stop', true).velocity({ /* 1 */ },{});
in this example velocity('stop', true) clear the $elm queue then next animation immediately start.
Be careful to use the delay param for velocity
for example :
jQuery(function($){
var $pen = jQuery('#pen');
$arrow1 = jQuery('#arrow1');
$arrow2 = jQuery('#arrow2');
$pdf = jQuery('#pdf');
$screen = jQuery('#screen');
$pen
.velocity("fadeIn", {
duration: 1500,
complete:function(elements){
$arrow1.velocity("fadeIn", { duration: 1500});
}
});
});
The callback start after the end of the animation
in the meantime
$pen.velocity("fadeIn", { duration: 1500 });
$arrow1.velocity("fadeIn", { duration: 1500});
});
the two animations start at the same time, so if you want a timeline, write a delay for start after the end of the first animation
$pen.velocity("fadeIn", {
duration: 1500
});
$arrow1.velocity("fadeIn", { duration: 1500,delay:1500});
});
Nevermind with the ui Pack you've a great explanation here
Ui pack sequence
But for make the same thing, you can't use "fadeIn" directly
here we go
var $pen = jQuery('#pen');
$arrow1 = jQuery('#arrow1');
$psd = jQuery('#psd');
$arrow2 = jQuery('#arrow2');
$screen = jQuery('#screen');
var sequenceFade = [
{ e: $pen, p: { opacity: 1 , display: "block"}, o:{duration :1500}},
{ e: $arrow1, p: { opacity: 1 , display: "block"}, o: {duration: 1500}},
{ e: $psd, p: { opacity: 1 , display: "block"}, o: {duration: 1500}},
{ e: $arrow2, p: { opacity: 1 , display: "block"}, o: {duration: 1500}},
{ e: $screen, p: { opacity: 1 , display: "block"}, o: {duration: 1500}}
];
$.Velocity.RunSequence(sequenceFade);
Related
I am creating a pulsating effect with velocity.js as fallback for IE9, (see box2 for CSS animation )
When mouse leaves the box before the animation has finished ( stay until pulse grows than move out ) the pulsating element stays visible. https://jsfiddle.net/02vu80kc/1/
$(".box").hover(function () {
$(this).find('.effect-holder').velocity({
scale: [1.2, 0.9],
opacity: [1, 0]
}, {
easing: 'ease-out',
duration: 800,
loop: true
}, {
queue: false
}).velocity("reverse");
}, function () {
$(this).find('.effect-holder').velocity("stop");
});
How do I stop the animation on mouseout after the effect has finished ?
I am trying to stay away from .removeAttr('style') and would like the animation to finish and than stop. Any help is appreciated.
If I use this
$(this).find('.effect-holder').velocity('reverse').velocity("stop");
and you move the mouse fast the animation begins again and sometimes pauses in between.
Either use .velocity("finish") instead of .velocity("stop"), or have a different on and off animation, with both animations calling "stop" (ie, catch when the mouse moves properly).
Also note that the {... loop:true ...} means that the first animation never ends, and hence the "stop" will have the "reverse" happen immediately after stopping (call .velocity("stop", true) to prevent that)
edit: Open issue on the "finish" bug - https://github.com/julianshapiro/velocity/issues/495
edit2: Add simple example:
$("box").hover(function() {
// over
this.velocity("stop", true).velocity({
scale: [1.2, 0.9]
}, {
duration: 800,
loop: true
})
}, function() {
// out
this.velocity("stop", true).velocity({
scale: 0.9
}, {
easing: "ease-out",
duration: 800
})
});
I have a simple wrapper div that I animate in using velocity.js UI pack. In the complete callback function, I am using a combination of UI pack and blast.js to animate three sentences.
The problem is that my sentences are initially shown, and only after that they are animated. They shouldn't be visible after the wrapper div is animated into view.
Everything is working fine if I don't animate the wrapper div, guess the opacity settings during animation are messing with child elements.
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated")
.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
Here is the fiddle to see the problem : http://jsfiddle.net/vcsr6aqj/1/
The problem is that your p tags aren't at opacity: 0, but only their characters, which are inside a span having as class blast. Since your invisible characters are only created when you call $(".animated").blast({ delimiter: "character" }), which means once your wrapper has completed its apparition, the sentences will be visible until then. So you have two possibilities that I can think of.
Create your span characters with blast at the page load, instead at the wrapper velocity complete and then call velocity on your created spans:
$(document).ready(function() {
$(".animated").blast({ delimiter: "character" });
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated .blast").velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
});
JSFiddle example
Add a class to your p tags having opacity: 0:
<p class="animated no-opacity">Sentence number one.</p>
<p class="animated no-opacity">Sentence number two.</p>
<p class="animated no-opacity">Just one sentence more.</p>
CSS:
.no-opacity {
opacity: 0;
}
When your wrapper has completed the velocity, remove the class from your p tags. Also, remove delay: 400 from your velocity attributes, otherwise the sentences will show for 400 milliseconds:
$(document).ready(function() {
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$animated = $(".animated");
$animated.removeClass("no-opacity");
$animated.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60
});
}
})
});
JSFiddle example
Here you go (fiddle). I'm sure there are more elegant solutions.
It appears that the slideUpIn animates opacity from 0 to 1, including the opacity of .animated which is probably 'inherited'. Setting it to 0 to hide it fixes it, but then .blast() doesn't work, so we enable it again.
How would one make a slide and fade in animation like in seen in the green and pink boxes on sharethis.com? In particular I like the one in the blue box with the arrows. Are there a set of JavaScript codes or CSS effects?
The easiest would probably be to use a library like this:
http://janpaepke.github.io/ScrollMagic/
I see that for the arrows effect the css-height property is animated when you scroll. This is done in javascript. But you can also achieve this effect through CSS3-transitions.
Update: Slide and wipe effects from the demo page:
// ani
var pinani = new TimelineMax()
// wipe
.add(TweenMax.to("#wipe", 1, {
width: "100%"
}))
// slide
.add(TweenMax.to("#slide", 1, {
top: "0%",
ease: Bounce.easeOut,
delay: 0.2
}));
// pin
new ScrollScene({
triggerElement: "section#pin",
duration: 1100
})
.on("progress", function () {
// keep centered even though width changes
$("#wipe h3").width($("#pin>h3").width());
})
.setTween(pinani)
.setPin("section#pin")
.addTo(controller);
I customize a collapsible sidebar from this article
(http://devheart.org/articles/jquery-collapsible-sidebar-layout/) for my own project But it looks a bit funky and not right.
Please take a look at the project here:
http://jsbin.com/oliluz/45
The sidebar seems animating properly, but the #mainContent isn't animating along with the sidebar. It's toggling in stiffly and harsh.
Also advice if the way i added my code are optimize.
Thanks!
The new width of the #mainContent is determined by CSS; which is why it isn't animated. To animate the width of the mainContent as well, try the following:
Remove the following line from the CSS:
#wrap.sidebar #mainContent { margin-right: 270px; }
Modify the JavaScript to add the appropriate animations:
// Variables
var objMain = $('#wrap'), objSidebar = $('#sidebar');
var objContent = $('#mainContent'); // << ADDED
// Show sidebar
function showSidebar(){
objMain.removeClass('nosidebar');
objMain.addClass('sidebar');
objSidebar.animate({ 'right' : '0'},'slow');
objContent.animate({ 'margin-right': 270}, 'slow'); // << ADDED
$.cookie('sidebar-pref2', 'use-sidebar', { expires: 30 });
}
// Hide sidebar
function hideSidebar(){
objMain.removeClass('sidebar');
objMain.addClass('nosidebar');
objSidebar.animate({ 'right' : '-254px'},'slow');
objContent.animate({ 'margin-right': 0}, 'slow'); // << ADDED
$.cookie('sidebar-pref2', null, { expires: 30 });
}
http://jsfiddle.net/E6cUF/
The idea is that after the page finished loading the grey box slides left from behind the green box, if possible bounce a little.
Edit: made a new version based on changes people made to the jsfiddle and the comment from Nicola
http://jsfiddle.net/RBD3K/
However the grey one should be behind the green one and slide from right to left so it appears
To have it bounce you are missing two things i think:
1) you need to load jquery UI.
2) put the bounce effect after the animate effect:
$('#test').click(function() {
var $marginLefty = $('.left');
$marginLefty.animate({
marginLeft: parseInt($marginLefty.css('marginLeft'),10) == 0 ?
$marginLefty.outerWidth() :
0
}).effect("bounce", { times:5 }, 300);
});
updated fiddle: http://jsfiddle.net/nicolapeluchetti/E6cUF/4/
Try this . Not sure if this is what you want.
$('#test').click(function() {
var $marginLefty = $('.left');
var $marginRight = $('.right');
$marginLefty.animate({
marginLeft: 0
},{ duration: 200, queue: false });
$marginRight.animate({
marginLeft: 100
},{ duration: 200, queue: false });
});
Update: from your updated fiddle,add for .right position :absolute;z-index:1000 as css
http://jsfiddle.net/E6cUF/11/