I am trying to alternate display between two containers on a page using fadeOut/fadeIn & slideUp/slideDown. I would like the transition from the first container to the second to look the same as the transition from the second to the first; they fade in/out respectively, the current container slides up and away, and the other slides up from below it, all simultaneously. The first button triggers the animation described, but when I use the second button to transition to the first element the first element suddenly pops into existence while fading in jerking the page down, the second fades out, but no slide occurs. Thanks for your help, and let me know if I can clarify for you!
var main = function () {
$('.button-1').click(function () {
$('.container-1').fadeOut({ duration: 1400, queue: false }).slideUp(1400);
$('.container-2').fadeIn({ duration: 1400, queue: false }).slideDown(1400);
});
$('.button-2').click(function () {
$('.container-2').stop(true, true).fadeOut({ duration: 1400, queue: true }).slideUp(1400);
$('.container-1').fadeIn({ duration: 1400, queue: false }).slideDown(1400);
});
$(document).ready(main);
you actually only need 1 button to do this if you animate the height and opacity with toggle. ive added it twice since your use case was for 2 buttons
js fiddle here
js
var main = function () {
$('.button-1').click(function () {
$('.container-1')
.stop(true, true)
.animate({
height: "toggle",
opacity: "toggle"
}, 1400);
$('.container-2')
.stop(true, true)
.animate({
height: "toggle",
opacity: "toggle"
}, 1400);
});
$('.button-2').click(function () {
$('.container-2')
.stop(true, true)
.animate({
height: "toggle",
opacity: "toggle"
}, 1400);
$('.container-1')
.stop(true, true)
.animate({
height: "toggle",
opacity: "toggle"
}, 1400);
});
}
$(document).ready(main);
html
<div class=container-1>container1</div>
<div class=container-2>container2</div>
<input type=button class=button-1 value=button1>
<input type=button class=button-2 value=button2>
css
.button-1 {
color: red;
}
.button-2 {
color: blue;
}
.container-1, .container-2 {
width: 100px;
height: 100px;
}
.container-1 {
background-color: green;
}
.container-2 {
display: none;
background-color: orange;
}
Not sure if this is what you want. But here is one way to switch between two containers with slide and fade at the same time:
HTML:
<input type="button" class="redclick" value="Red"></input>
<input type="button" class="blueclick" value="Blue"></input>
<div class="red"></div>
<div class="blue"></div>
CSS:
.red, .blue{
width:200px;
height:200px;
position: absolute;
}
.red{ background:red; }
.blue{ background:blue; }
Javascript:
$(function() {
$('.red').hide();
$('.blue').show();
$(".blueclick").click(function() {
if($('.red').css('opacity') == '1'){
$('.red').fadeOut({ duration: 1400, queue: false }).slideUp(1400);
$('.blue').slideDown({ duration: 1400, queue: false }).fadeIn(1400);
}
});
$(".redclick").click(function() {
if($('.blue').css('opacity') == '1'){
$('.blue').fadeOut({ duration: 1400, queue: false }).slideUp(1400);
$('.red').slideDown({ duration: 1400, queue: false }).fadeIn(1400);
}
});
});
JSFiddle Demo
Hope this helps.
Related
New to js and could use some help. I have been trying to change the color of the box after clicking the button blue. Can I just use js to change the box color or do I need some css magic?
$("#btn1").on("click", function() {
$("#box").animate({
height: "+=35px",
width: "+=35px"
}, "fast");
})
$("#btn2").on("click", function() {
$("box")({
backgroundColor: "blue"
});
})
$("#btn3").on("click", function() {
$("#box").fadeOut();
})
$("#btn4").on("click", function() {
$("#box").animate({
height: "150px",
width: "150px"
}, "fast");
$("#box").fadeIn(), "fast";
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
<div id="box" style="height:150px; width:150px; background-color:pink; margin:25px;"></div>
<button id="btn1">Grow</button>
<button id="btn2">Blue</button>
<button id="btn3">Fade</button>
<button id="btn4">Reset</button>
Your jquery function should be:
$("box").css({backgroundColor:"blue"});
http://api.jquery.com/css/
As Heretic Monkey hinted at missing code, as Guzz mentioned you are missing the method .css() and as Rafv mentioned, your selector is wrong is it should be $('#box'). I'll go one step further in the spirit of the code and animate the color change:
$("#box").animate().css({
backgroundColor: "blue"
}, 2500);
and more importantly add this to the CSS:
#box {
transition: background-color 2.5s ease-out
}
As a bonus, the reset function is rewritten so that the methods are chained and arranged so that each animation can be seen in reverse.
...
$("#box").fadeIn("fast").animate({
height: "150px",
width: "150px"
}, "fast").css({
backgroundColor: "pink"
}, 1500);
...
Demo
$("#btn1").on("click", function() {
$("#box").animate({
height: "+=35px",
width: "+=35px"
}, "fast");
});
$("#btn2").on("click", function() {
$("#box").animate().css({
backgroundColor: "blue"
}, 2500);
});
$("#btn3").on("click", function() {
$("#box").fadeOut();
});
$("#btn4").on("click", function() {
$("#box").fadeIn("fast").animate({
height: "150px",
width: "150px"
}, "fast").css({
backgroundColor: "pink"
}, 1500);
});
#box {
transition: background-color 2.5s ease-out
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
<div id="box" style="height:150px; width:150px; background-color:pink; margin:25px;"></div>
<button id="btn1">Grow</button>
<button id="btn2">Blue</button>
<button id="btn3">Fade</button>
<button id="btn4">Reset</button>
You missing # in box section and for non-multiple css, better use
$("#box").css("background-color", "blue");
css("propertyname","value");
More about this here.
I've recently started working with Anime.js to animate my designs and I´ve been stuck in this for a while now, bet for many this is very simple!
I have a button that enlarges my div and would like to have the div in its initial state if the icon is clicked again.
My HTML:
var boxGetsLarger = anime({
targets: '.agent-button',
width: {
value: '+=300',
duration: 200,
easing: 'linear'
},
borderRadius: {
value: 83
},
duration: 200,
height: {
value: '+=20'
},
easing: 'linear',
autoplay: false
});
document.querySelector('.agent-button').onclick = boxGetsLarger.play;
.agent-button {
display: flex;
justify-content: space-between;
border-radius: 100px;
background: #ffffff;
box-shadow: 0pt 2pt 10pt #0000001f;
height: 91px;
width: 91px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="agent-button close">
<img src="img/audio-bars.svg">
</div>
It is shame there is no built-in toggle function but there is a reverse function what this does is toggle the internal attribute reversed which, in turn, controls what the play function does.
In theory, you can just call reverse after play like so
var boxGetsLarger = anime({
targets: '.agent-button',
width: {
value: '+=300',
duration: 200,
easing: 'linear'
},
borderRadius: {
value: 83
},
duration: 200,
height: {
value: '+=20'
},
easing: 'linear',
autoplay: false
});
document.querySelector('.agent-button').onclick = function() {
boxGetsLarger.play();
boxGetsLarger.reverse();
}
.agent-button {
display: flex;
justify-content: space-between;
border-radius: 100px;
background: #ffffff;
box-shadow: 0pt 2pt 10pt #0000001f;
height: 91px;
width: 91px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="agent-button close">
<img src="img/audio-bars.svg">
</div>
Only I found reverse was running before play was finished leading to some strange behaviour, I'd recommend taking advantage of the 'finished' promise built-in like so
var boxGetsLarger = anime({
targets: '.agent-button',
width: {
value: '+=300',
duration: 200,
easing: 'linear'
},
borderRadius: {
value: 83
},
duration: 200,
height: {
value: '+=20'
},
easing: 'linear',
autoplay: false
});
document.querySelector('.agent-button').onclick = function() {
boxGetsLarger.play();
boxGetsLarger.finished.then(() => {
boxGetsLarger.reverse();
})
}
.agent-button {
display: flex;
justify-content: space-between;
border-radius: 100px;
background: #ffffff;
box-shadow: 0pt 2pt 10pt #0000001f;
height: 91px;
width: 91px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="agent-button close">
<img src="img/audio-bars.svg">
</div>
This will now only reverse the direction when play is finished.
I hope you find this helpful.
I use this to toggle anime.js animations on a single button.
To initiate reverse() the animation must have run once. You can check this by evaluating the property: 'began'. The first time your animation runs this property will be set 'true'.
console.log(boxGetsLarger); // began: false
document.querySelector('.agent-button').onclick = function() {
boxGetsLarger.play();
if (boxGetsLarger.began) {
boxGetsLarger.reverse();
}
console.log(boxGetsLarger); // began: true
}
What fixed it for me was juliangarnier/anime#577 (comment):
I encountered this issue today, here is my solution as a pen.
I think the confusion arises from when animations are paused, and how the reverse() method works:
Non-looped animations are automatically paused when they reach the end (or beginning when reversed).
The reverse() method only changes the playback direction, and doesn't unpause a paused animation.
Doing reverse() on an animation while it is in progress means it will continue to play in the opposite direction, but if the animation is at the beginning/end (i.e. paused), you will also need to do play() to get it started again.
From his linked CodePen:
function toggle() {
if (anim.began) {
anim.reverse()
if (anim.progress === 100 && anim.direction === 'reverse') {
anim.completed = false
}
}
if (anim.paused) {
anim.play()
}
}
Give this a try: (from docs)
boxGetsLarger.reverse();
I used this to toggle back and forth between an "open" state and a "closed" state.
const toggle = (animation, open) => {
if (open) {
animation.play();
if (animation.reversed) {
animation.reverse();
}
} else {
animation.play();
if (!animation.reversed) {
animation.reverse();
}
}
}
I am trying to make a div slide to the left and THEN disappear. I am using this code.
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
});
document.getElementById(current_my).style.display = "none";
}
if I remove the last line of code the div slides nicely to the left over 750ms. But when I add the last line the div just disappears.
I tired adding:
wait(750);
before the last line, where the 'wait' function was defined as :
function wait(ms)
{
var d = new Date();
var d2 = null;
do { d2 = new Date(); }
while(d2-d < ms);
}
but that just made the div sit there for 750ms and then disappear. Again, what I want is for the 'current_my' div to slide / animate and THEN disappear (display:none). Any ideas? Thank you.
You need to use the complete option of jQuery animate. Also since you already have the object, there is no point in going to find it again. In your complete method, you can just use the this keyword and apply the hiding or any other animation directly to the object again.
$("#" + current_my).animate({ left: "510" }, { duration: 750 }, function() {
$(this).hide();
});
You should hide the div in complete callback
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, 750, function() {
document.getElementById(current_my).style.display = "none";
});
}
Doc reference
Animate takes a callback when finished.
You could
function slide_in(current_my) {
$("#" + current_my).animate({
left: "510"
}, {
duration: 750
}, function () {
document.getElementById(current_my).style.display = "none";
});
}
An alternative using animate.css, you would need to adjust the animation duration on the css file.
$(document).ready(function() {
$('button.btn').click(function() {
$('div.box').addClass('animated fadeOutLeftBig');
});
});
.box {
width: 50px;
height: 50px;
margin-left: 200px;
background-color: red;
}
.box p {
text-align: center;
font-size: 1em;
}
div.box {
-webkit-animation-duration: 5s;
-webkit-animation-delay: 0s;
-moz-animation-duration: 5s;
-moz-animation-delay: 0s;
-ms-animation-duration: 5s;
-ms-animation-delay: 0s;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<p>Test</p>
</div>
<button class="btn">Fade Left</button>
This is slightly more than asked but lets make it fun. Toss in an event to trigger the animation instead of a function, passing the location and duration numbers just for fun:
$(document).on('slidehide', '.myanimate', function(event, requstedduration, whereto, shouldhide) {
var p = $(this).position();
$(this).animate({
left: whereto
}, {
duration: requstedduration,
start: function() {$('.silly').toggle(shouldhide);},
complete: function() {
$(this).toggle(!shouldhide);
}
});
});
$('.myanimate').on('click', function() {
console.log('moving');
$(this).trigger('slidehide', [750, 510, true]);
});
// just so we can restart/see again
$(document).on('click', '.silly', function() {
console.log('restart');
$('.myanimate').show().trigger('slidehide', [750, 10, false]);;
});
.myanimate {
position: absolute;
left: 100px;
}
.silly {
display: none;
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myanimate">howdy there (click to trigger)</div>
<div class='silly'>Animation complete. (click to restart)</div>
I want to align the jQuery Dialog box Center to a DIV and not to the full window.
Here is my code:
HTML
<div id="Box1"><input id="openDialogButton" type="button" value="Open Dialog"></div>
<div id="Box2"></div>
<div id="Box3"></div>
<div id="dialogbox" title="Dialog Heading">
<p>Test Message</p>
</div>
CSS
div {
display:inline-block;
height:400px;
padding:10px;
border:1px solid #ff0000;
width:50%;
vertical-align:top;
}
#Box1 {
width:90px;
}
#Box2 {
width:150px;
}
jQuery
$(document).ready(function () {
$("#openDialogButton").click(function () {
$("#dialogbox").dialog({
width: 300,
autoOpen: false,
modal: false,
position: {
my: "center",
at: "center",
of: $('#Box3')
},
buttons: {
"Submit": function () {
$(this).dialog("close");
}
}
});
});
});
Here is the Fiddle: http://jsfiddle.net/Hftm3/ (for some reason my Dialog Box is not working in this fiddle. Not sure why)
Let me know if you need any other information.
Please suggest.
I think the issue is because the element is not visible in the viewport, in this case you can scrollTo the element then fire the dialog.
Code:
$(document).ready(function () {
$("#openDialogButton").click(function () {
$('html, body').animate({
scrollTop: $("#Box3").offset().top
}, 1000, function () {
$("#dialogbox").dialog({
width: 300,
modal: false,
position: {
my: "center",
at: "center",
of: $('#Box3')
},
buttons: {
"Submit": function () {
$(this).dialog("close");
}
}
});
});
});
});
Demo: http://jsfiddle.net/8cjk6/
In click the button event you are setting the dialog. If you set the autoOpen to true it will be shown as soon as you click the button. I've tested it here in you jsfiddle. You only have to resize it:
$(document).ready(function () {
$("#openDialogButton").click(function () {
$("#dialogbox").dialog({
width: 300,
height: 200, //try this
autoOpen: true, //try this too
modal: false,
position: {
my: "center",
at: "center",
of: $('#Box3')
},
buttons: {
"Submit": function () {
$(this).dialog("close");
}
}
});
});
});
Also, change you CSS to match only what you need:
#box1, #box2, #box3 {
display:inline-block;
height:400px;
padding:10px;
border:1px solid #ff0000;
width:50%;
vertical-align:top;
}
Using only div{ as you are using will break all your divs (including the ones generated by jquery to show your dialog).
I was looking around SO and couldn't really find a good concrete answer. My problem is that when the .mouseenter(function(){ }) is fired and the .mouseleave(function(){ }) is fired right after it completes both animation, instead I want the .mouseleave(function(){ }) to stop the .mouseenter(function(){ }) from finishing it's animation.
Here' a jsfiddle of how I currently have it.
HtML:
<div id="header">
<div id="header-align">
</div>
</div>
CSS:
#header {
width: 100%;
height: 200px;
position: fixed;
top: -170px;
}
#header #header-align {
width: 400px;
height: 100%;
border: 1px dotted #000;
margin: 0 auto 0;
}
jQuery
$("#header").mouseenter(function(){
$(this).animate({ top: -20 }, {
duration: 'slow',
easing: 'easeOutBack'
})
});
$("#header").mouseleave(function(){
$(this).animate({ top: -170 }, {
duration: 'slow',
easing: 'easeOutBack'
})
});
I was thinking something like bind(function(){ }) or something like .stopPropagation() but couldn't find a good answer
Did you try adding in a .stop()?
$(this).stop().animate({ top: -170 }, {
duration: 'slow',
easing: 'easeOutBack'
})
jsFiddle
You may also consider using .hover().
$("#header").hover(function(){
$(this).stop().animate({ top: -20 }, {
duration: 'slow',
easing: 'easeOutBack'
})
},
function(){
$(this).stop().animate({ top: -170 }, {
duration: 'slow',
easing: 'easeOutBack'
})
});