Reputation: 3075
I am working on an animation, I want 4 elements to appear to float independently of each other, to accomplish that I am using the same animation for all 4 elements but using animation-delay
to make sure they are floating independently. The problem with this is that these animations are happening within an element that is hidden on page load, and when that element becomes visible, you can see the animation delay taking place. Is it possible to have the animation begin while the containing element is still hidden so that the delay can't be seen? Otherwise, what is the best way to make them float independently of each other without complicating the CSS too much?
$(function() {
$('button').click(function(e) {
e.preventDefault();
$('.scene.one').hide();
$('.scene.two').fadeIn(500);
});
});
.scenes {
height:150px;
width:300px;
border:1px solid black;
}
h1 {
margin:0;
}
p {
margin-bottom:0;
font-size:12px;
}
.scene {
position:relative;
height:100%;
width:100%;
text-align:center;
display:none;
}
.scene-container {
position:absolute;
top:50%;
left:50%;
transform:translateX(-50%) translateY(-50%);
}
.scene.one {
display:block;
}
.float {
display:inline-block;
width:25px;
height:25px;
background:black;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
.animated .float {
animation-name:floating;
}
.float:nth-child(2) {
animation-delay:.5s;
}
.float:nth-child(3) {
animation-delay:1.5s;
}
.float:nth-child(4) {
animation-delay:1s;
}
@keyframes floating {
from { transform: translate(0, 0px); }
65% { transform: translate(0, 15px); }
to { transform: translate(0, -0px); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scenes">
<div class="scene one">
<div class="scene-container">
<h1>WELCOME</h1>
<button>Next scene</button>
<p>(Animation delay is still visible even if you wait 2 seconds before clicking)</p>
</div>
</div>
<div class="scene two">
<div class="scene-container">
<div class="float-container animated">
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
</div>
</div>
</div>
</div>
Upvotes: 1
Views: 51
Reputation: 64174
You can use negative delays to achieve this.
I have set them using calc to make the logic clear, but you can use the calculated value as well.
Any value that once divided by the animation duration gives the same reminder will keep the visual effect unaltered
$(function() {
$('button').click(function(e) {
e.preventDefault();
$('.scene.one').hide();
$('.scene.two').fadeIn(500);
});
});
.scenes {
height:150px;
width:300px;
border:1px solid black;
}
h1 {
margin:0;
}
p {
margin-bottom:0;
font-size:12px;
}
.scene {
position:relative;
height:100%;
width:100%;
text-align:center;
display:none;
}
.scene-container {
position:absolute;
top:50%;
left:50%;
transform:translateX(-50%) translateY(-50%);
}
.scene.one {
display:block;
}
.float {
display:inline-block;
width:25px;
height:25px;
background:black;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
.animated .float {
animation-name:floating;
}
.float:nth-child(2) {
animation-delay:calc(.5s - 3s);
}
.float:nth-child(3) {
animation-delay:calc(1.5s - 3s);
}
.float:nth-child(4) {
animation-delay:calc(1s - 3s);
}
@keyframes floating {
from { transform: translate(0, 0px); }
65% { transform: translate(0, 15px); }
to { transform: translate(0, -0px); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scenes">
<div class="scene one">
<div class="scene-container">
<h1>WELCOME</h1>
<button>Next scene</button>
<p>(Animation delay is still visible even if you wait 2 seconds before clicking)</p>
</div>
</div>
<div class="scene two">
<div class="scene-container">
<div class="float-container animated">
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 42304
If you opt for making use of visibility: visible
and visibility: hidden
instead of display
then you can animate the elements before they are seen by the user. Unfortunately this means that you won't be able to have the fade effect (as that specifically works off of display
), but if that is optional, this may be a viable solution for you:
$(function() {
$('button').click(function(e) {
e.preventDefault();
$('.scene.one').css('display', 'none');
$('.scene.two').css('visibility', 'visible');
});
});
.scenes {
height: 150px;
width: 300px;
border: 1px solid black;
}
h1 {
margin: 0;
}
p {
margin-bottom: 0;
font-size: 12px;
}
.scene {
position: relative;
height: 100%;
width: 100%;
text-align: center;
visibility: hidden;
}
.scene-container {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.scene.one {
visibility: visible;
}
.float {
display: inline-block;
width: 25px;
height: 25px;
background: black;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
.animated .float {
animation-name: floating;
}
.float:nth-child(2) {
animation-delay: .5s;
}
.float:nth-child(3) {
animation-delay: 1.5s;
}
.float:nth-child(4) {
animation-delay: 1s;
}
@keyframes floating {
from {
transform: translate(0, 0px);
}
65% {
transform: translate(0, 15px);
}
to {
transform: translate(0, -0px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scenes">
<div class="scene one">
<div class="scene-container">
<h1>WELCOME</h1>
<button>Next scene</button>
<p>(Wait 2 seconds before clicking)</p>
</div>
</div>
<div class="scene two">
<div class="scene-container">
<div class="float-container animated">
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
<div class="float"></div>
</div>
</div>
</div>
</div>
Upvotes: 1