jquery each div add remove class infinity - javascript

want to create infinity loop that adds class to each div with some timeout
for know have like this:
$(document).ready(function() {
$('.small-bordered-box').each(function(i) {
var $t = $(this);
setTimeout(function() {
$t.addClass('active');
}, 2000 * i);
});
});
.small-bordered-box {
display: block;
height: 118px;
width: 100px;
border: 2px solid #3e3b38;
border-radius: 5px;
float: left;
margin-right: 35px;
}
.small-bordered-box.active {
animation: shake 0.83s cubic-bezier(.36, .07, .19, .97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
#keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(2px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}
40%,
60% {
transform: translate3d(4px, 0, 0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="small-bordered-box ">
test1
</div>
<div class="small-bordered-box ">
test2
</div>
<div class="small-bordered-box ">
test3
</div>
want to keep effect like this, just that it would go infiny time..
that users would always sees this effect no matter what or where they are on the page..

You can use setInterval to shake it with an interval of element's-length*Timeouts-interval i.e. 3*2000 like,
$(document).ready(function() {
function shakeIt() {
$('.small-bordered-box').each(function(i) {
var $t = $(this);
setTimeout(function() {
$t.addClass('active');
}, 2000 * i);
});
}
shakeIt();
setInterval(function() {
shakeIt();
$('.small-bordered-box').removeClass('active');
}, $('.small-bordered-box').length*2000);
});
.small-bordered-box {
display: block;
height: 118px;
width: 100px;
border: 2px solid #3e3b38;
border-radius: 5px;
float: left;
margin-right: 35px;
}
.small-bordered-box.active {
animation: shake 0.83s cubic-bezier(.36, .07, .19, .97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
#keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(2px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}
40%,
60% {
transform: translate3d(4px, 0, 0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="small-bordered-box ">
test1
</div>
<div class="small-bordered-box ">
test2
</div>
<div class="small-bordered-box ">
test3
</div>

use $t.toggleClass('active'); keep this inside setInterval()
$(document).ready(function() {
$('.small-bordered-box').each(function(i) {
var $t = $(this);
setInterval(function() {
$t.toggleClass('active');
}, 2000 );
});
});
.small-bordered-box {
display: block;
height: 118px;
width: 100px;
border: 2px solid #3e3b38;
border-radius: 5px;
float: left;
margin-right: 35px;
}
.small-bordered-box.active {
animation: shake 0.83s cubic-bezier(.36, .07, .19, .97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
#keyframes shake {
10%,
90% {
transform: translate3d(-1px, 0, 0);
}
20%,
80% {
transform: translate3d(2px, 0, 0);
}
30%,
50%,
70% {
transform: translate3d(-4px, 0, 0);
}
40%,
60% {
transform: translate3d(4px, 0, 0);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="small-bordered-box ">
test1
</div>
<div class="small-bordered-box ">
test2
</div>
<div class="small-bordered-box ">
test3
</div>

Change your CSS into:
.small-bordered-box.active {
animation: shake 0.83s cubic-bezier(.36, .07, .19, .97) both infinite;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}

Related

How to make bouncy text carousel CSS

The animation that I am trying to replicate:
Here it is at normal speed:
Here it is at slower speed, so you can see the animation more clearly (I hope)
Essentially, it bounces off once at text4, and once at text5.
I am new with animations, so if anyone has any recommendation on how to approach this, it would greatly be appreciated.
Here is what I have so far: Fiddle
You can make a gravity-like cubic-bezier to imitate the bounce effect. You will apply this cubic-bezier per keyframe to mimic acceleration/deceleration like real-life gravity. You can use this cubic-bezier generator to create the acceleration/deceleration you like.
Here's a runnable solution with the compiled CSS. Here's the link with the SCSS code.
.loading {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
background-color: #000;
color: white;
font-weight: bold;
text-align: center;
transition: all .35s ease-in-out;
}
.loading_carousel {
font-size: 55.02px;
line-height: 55.02px;
position: relative;
width: 100%;
text-align: center;
}
.loading_options {
position: relative;
}
.loading_options.rotate {
animation: 2s linear 1s infinite rotate;
animation-delay: 2s;
}
.loading_element {
display: block;
font-weight: 700;
}
.loading_shuffle {
text-align: center;
height: 55.02px;
overflow: hidden;
mask: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, black 25%, black 75%, rgba(0, 0, 0, 0) 100%);
}
#keyframes rotate {
0% {
transform: translateY(0px);
animation-timing-function: cubic-bezier(0.5, 0.36, 0.9, 0.83); /*Accelerate*/
}
30% {
transform: translateY(-240.08px);
animation-timing-function: cubic-bezier(0.17, 0.4, 0.33, 0.94); /*Decelerate*/
}
46.667% {
transform: translateY(-165.06px);
animation-timing-function: cubic-bezier(0.5, 0.36, 0.9, 0.83);
}
62% {
transform: translateY(-220.08px);
animation-timing-function: cubic-bezier(0.17, 0.4, 0.33, 0.94);
}
78% {
transform: translateY(-198.072px);
animation-timing-function: cubic-bezier(0.5, 0.36, 0.9, 0.83);
}
88%, 100% {
transform: translateY(-220.08px);
}
}
<div id="loading" class="loading">
<div class="loading_carousel">
<div class="loading_shuffle">
<div class="loading_options rotate">
<div class="loading_element">text1</div>
<div class="loading_element">text2</div>
<div class="loading_element">text3</div>
<div class="loading_element">text4</div>
<div class="loading_element">text5</div>
</div>
</div>
</div>
</div>
Not perfect but close :)
Overall the animation goes like this: Text1 -> Text 5 -> Text 4 -> Text 5 -> Inbetween 4 and 5 -> Text 5
And that's basically your keyframes also I've added the same translate for 50% and 52% which would make it stop for a while at "Text 4"
The rest is mostly adjusting the numbers. (For example I've changed the animation time from 2s to 3s)
.loading {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: fixed;
display: -webkit-box;
display: flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
opacity: 1;
background-color: rebeccapurple;
color: white;
font-weight: bold;
z-index: 13000;
text-align: center;
-webkit-transform-origin: left;
transform-origin: left;
-webkit-transition: all .35s ease-in-out;
transition: all .35s ease-in-out;
}
.loading_carousel {
font-size: 55.02px;
line-height: 55.02px;
height: 55.02px;
position: relative;
width: 100%;
text-align: center;
}
.loading_options {
position: relative;
}
.loading_options.rotate {
animation: rotate 3s 1s linear infinite;
}
.loading_element {
display: block;
font-weight: 700;
}
.loading_shuffle {
position: absolute;
top: 0;
left: 52%;
text-align: left;
height: 55.02px;
overflow: hidden;
margin-left: -25px;
opacity: 1;
}
.loading_shuffle:before, .loading_shuffle:after {
content: '';
background: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0)), to(#482078));
background: linear-gradient(to top, rgba(0, 0, 0, 0), #482078);
width: 100%;
height: 15px;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.loading_shuffle:after {
top: auto;
bottom: -3px;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(#482078));
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), #482078);
}
#keyframes rotate {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
25% {
-webkit-transform: translateY(-220.08px);
transform: translateY(-220.08px);
}
50%, 52% {
-webkit-transform: translateY(-165px);
transform: translateY(-165px);
}
80% {
-webkit-transform: translateY(-195px);
transform: translateY(-195px);
}
70%, 100% {
-webkit-transform: translateY(-220.08px);
transform: translateY(-220.08px);
}
}
<div id="loading" class="loading">
<div class="loading_carousel">
<div class="loading_shuffle">
<div class="loading_options rotate">
<div class="loading_element">text1</div>
<div class="loading_element">text2</div>
<div class="loading_element">text3</div>
<div class="loading_element">text4</div>
<div class="loading_element">text5</div>
</div>
</div>
</div>
</div>

Animations and animation delay behaving randomly on Safari

I am trying to animate a certain page where there are three main components, two tables and one chart.
Please refer the JSFiddle to replicate the same on your Safari browser.
Link to JSFiddle
Two rows of the first table are shown one after the another i.e. the green row slides in then slides out cueing the yellow row to slide in. After a couple of seconds the yellow row slides out and then green comes back. After green comes back to the original position.
Two divs below slide in simultaneously. Now, what is happening is I make the green row absolute after it slides out so that the yellow row shifts up on the same position but on Safari, the 'position: absolute' in the green row is not applying.
#-webkit-keyframes slideRightDisappear {
0% {
opacity: 1;
}
75% {
opacity: 0;
}
99% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
position: absolute;
}
}
#keyframes slideRightDisappear {
0% {
opacity: 1;
}
75% {
opacity: 0;
}
99% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
position: absolute;
}
}
The yellow row also when slides out does not take absolute position to pull the lower two division up.
#-webkit-keyframes slideLeftDisappear {
0% {
display: inline;
opacity: 1;
}
99% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
100% {
position: absolute;
opacity: 0;
}
}
#keyframes slideLeftDisappear {
0% {
display: inline;
opacity: 1;
}
99% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
100% {
position: absolute;
opacity: 0;
}
}
Also, the two divisions at the bottom do not animate and just suddenly appear.
Check the fiddle on Chrome, that is how ideally it should work and then check it on Safari for the main issue.
Do not be confused by the way I am injecting the animation, my requirement is that I want to chain multiple animations and start and stop them on demand so what I do is, I pass a list of animation properties and join them individually and add it to the DOM style. I was earlier concatenating the shorthand but apparently Safari does not consider the shorthand so I went further and split each animation into its properties.
Also, one more issue which I am not able to replicate is when I click on the animate button, all my animations run simultaneously ignoring the delay that I give.
function animator () {
addAnimationToElement('row-1', ['fadeInLeftBig', 'slideRightDisappear', 'slideLeftAppear'], ['0.5s', '0.3s', '0.5s'], ['linear', 'linear', 'linear'], ['0.6s', '3s', '7.5s'], ['1', '1', '1'], ['normal', 'normal', 'normal'], ['forwards', 'forwards', 'forwards'], ['running', 'running', 'running'])
addAnimationToElement('row-2', ['slideInLeft', 'slideLeftDisappear'], ['0.5s', '0.5s'], ['linear', 'linear'], ['4s', '6.5s'], ['1', '1'], ['normal', 'normal'], ['forwards', 'forwards'], ['running', 'running'])
addAnimationToElement('table', ['fadeInLeftBig'], ['1.5s'], ['cubic-bezier(0.215, 0.61, 0.355, 1)'], ['9s'], ['1'], ['normal'], ['forwards'], ['running'])
addAnimationToElement('chart', ['fadeInRightBig'], ['1.5s'], ['cubic-bezier(0.215, 0.61, 0.355, 1)'], ['9s'], ['1'], ['normal'], ['forwards'], ['running'])
}
function pause () {
document.getElementById('portfolio').style.opacity = 0;
}
function addAnimationToElement (elementID, animationName, animationDuration, animationTimingFunction, animationDelay, animationIterationCount, animationDirection, animationFillMode, animationPlayState) {
// Animation for Safari
document.getElementById(elementID).style.WebkitAnimationName = animationName.join(', ')
document.getElementById(elementID).style.WebkitAnimationDuration = animationDuration.join(', ')
document.getElementById(elementID).style.WebkitAnimationTimingFunction = animationTimingFunction.join(', ')
document.getElementById(elementID).style.WebkitAnimationDelay = animationDelay.join(', ')
document.getElementById(elementID).style.WebkitAnimationIterationCount = animationIterationCount.join(', ')
document.getElementById(elementID).style.WebkitAnimationDirection = animationDirection.join(', ')
document.getElementById(elementID).style.WebkitAnimationFillMode = animationFillMode.join(', ')
document.getElementById(elementID).style.WebkitAnimationPlayState = animationPlayState.join(', ')
// Animation for other browsers
document.getElementById(elementID).style.animationName = animationName.join(', ')
document.getElementById(elementID).style.animationDuration = animationDuration.join(', ')
document.getElementById(elementID).style.animationTimingFunction = animationTimingFunction.join(', ')
document.getElementById(elementID).style.animationDelay = animationDelay.join(', ')
document.getElementById(elementID).style.animationIterationCount = animationIterationCount.join(', ')
document.getElementById(elementID).style.animationDirection = animationDirection.join(', ')
document.getElementById(elementID).style.animationFillMode = animationFillMode.join(', ')
document.getElementById(elementID).style.animationPlayState = animationPlayState.join(', ')
}
.transparent_element {
opacity: 0;
}
#row-1 {
width: 300px;
height: 100px;
display: block;
background-color: green;
}
#row-2 {
width: 300px;
height: 100px;
display: block;
background-color: yellow;
}
#table {
width: 150px;
height: 150px;
background-color: red;
display: inline-block;
}
#chart {
width: 150px;
height: 150px;
background-color: blue;
position: absolute;
right: 0;
display: inline-block;
}
#-webkit-keyframes slideLeftAppear {
0% {
opacity: 0;
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
100% {
transform: translate3d(0, 0,);
-webkit-transform: translate3d(0);
position: relative;
display: block;
opacity: 1;
}
}
#keyframes slideLeftAppear {
0% {
opacity: 0;
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
transform: translateX(0);
-webkit-transform: translateX(0);
position: relative;
display: block;
opacity: 1;
}
}
#-webkit-keyframes slideRightDisappear {
0% {
opacity: 1;
}
75% {
opacity: 0;
}
99% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
position: absolute;
}
}
#keyframes slideRightDisappear {
0% {
opacity: 1;
}
75% {
opacity: 0;
}
99% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
position: absolute;
}
}
#-webkit-keyframes fadeInLeftBig {
0% {
opacity: 0;
-webkit-transform: translateX(-400px);
transform: translateX(-400px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes fadeInLeftBig {
0% {
opacity: 0;
-webkit-transform: translateX(-400px);
transform: translateX(-400px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#-webkit-keyframes fadeInRightBig {
0% {
opacity: 0;
-webkit-transform: translate3d(400px, 0, 0);
transform: translate3d(400px, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
#keyframes fadeInRightBig {
0% {
opacity: 0;
-webkit-transform: translate3d(400px, 0, 0);
transform: translate3d(400px, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
#-webkit-keyframes slideInLeft {
0% {
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
#keyframes slideInLeft {
0% {
opacity: 0;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
#-webkit-keyframes slideLeftDisappear {
0% {
display: inline;
opacity: 1;
}
99% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
100% {
position: absolute;
opacity: 0;
}
}
#keyframes slideLeftDisappear {
0% {
display: inline;
opacity: 1;
}
99% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
100% {
position: absolute;
opacity: 0;
}
}
<div>
<button onclick="animator()">
Animate
</button>
<button onclick="pause()">
Pause
</button>
<table>
<tr id="row-1" class="transparent_element" style="-webkit-box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); -moz-box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); height: 90px;">
</tr>
<tr id="row-2" class="transparent_element" style="-webkit-box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); -moz-box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); box-shadow: 6px 4px 11px 1px rgba(0,0,0,0.75); height: 90px;">
</tr>
</table>
<div id="table" class="transparent_element"></div>
<div id="chart" class="transparent_element"></div>
</div>
</div>
Any idea or suggestion will be highly appreciated.
Thank you in advance!

gmail-like loading with css animation and keyframes

I'm trying to reproduce the gmail loading animation. I'm starting from the current loading element, that it's done via a CSS animation and HTML only.
The logo is neither a SVG path and it makes a clever use of animation and keyframes. How the CSS animation code was assembled? I argue that it's difficult to understand if this was done programmatically or by some tooling.
$('#loading').show()
body {
margin: 0;
width: 100%;
height: 100%
}
body,
td,
input,
textarea,
select,
#loading {
font-family: arial, sans-serif
}
input,
textarea,
select {
font-size: 100%
}
#loading {
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
background-color: #fff
}
.msg {
color: #757575;
font-size: 20px;
letter-spacing: .2px;
line-height: 20px;
text-align: center
}
#nlpt {
animation: a-s .5s 2.5s 1 forwards;
background-color: #f1f1f1;
height: 4px;
margin: 56px auto 20px;
opacity: 0;
overflow: hidden;
position: relative;
width: 300px
}
#nlpt::before {
animation: a-lb 20s 3s linear forwards;
background-color: #db4437;
content: '';
display: block;
height: 100%;
position: absolute;
transform: translateX(-300px);
width: 100%
}
#keyframes a-lb {
0% {
transform: translateX(-300px)
}
5% {
transform: translateX(-240px)
}
15% {
transform: translateX(-30px)
}
25% {
transform: translateX(-30px)
}
30% {
transform: translateX(-20px)
}
45% {
transform: translateX(-20px)
}
50% {
transform: translateX(-15px)
}
65% {
transform: translateX(-15px)
}
70% {
transform: translateX(-10px)
}
95% {
transform: translateX(-10px)
}
100% {
transform: translateX(-5px)
}
}
#keyframes a-s {
100% {
opacity: 1
}
}
#keyframes a-h {
100% {
opacity: 0
}
}
#keyframes a-nt {
100% {
transform: none
}
}
#keyframes a-e {
43% {
animation-timing-function: cubic-bezier(.8, 0, .2, 1);
transform: scale(.75)
}
60% {
animation-timing-function: cubic-bezier(.8, 0, 1, 1);
transform: translateY(-16px)
}
77% {
animation-timing-function: cubic-bezier(.16, 0, .2, 1);
transform: none
}
89% {
animation-timing-function: cubic-bezier(.8, 0, 1, 1);
transform: translateY(-5px)
}
100% {
transform: none
}
}
#keyframes a-ef {
24% {
animation-timing-function: cubic-bezier(.8, 0, .6, 1);
transform: scaleY(.42)
}
52% {
animation-timing-function: cubic-bezier(.63, 0, .2, 1);
transform: scaleY(.98)
}
83% {
animation-timing-function: cubic-bezier(.8, 0, .84, 1);
transform: scaleY(.96)
}
100% {
transform: none
}
}
#keyframes a-efs {
24% {
animation-timing-function: cubic-bezier(.8, 0, .6, 1);
opacity: .3
}
52% {
animation-timing-function: cubic-bezier(.63, 0, .2, 1);
opacity: .03
}
83% {
animation-timing-function: cubic-bezier(.8, 0, .84, 1);
opacity: .05
}
100% {
opacity: 0
}
}
#keyframes a-es {
24% {
animation-timing-function: cubic-bezier(.8, 0, .6, 1);
transform: rotate(-25deg)
}
52% {
animation-timing-function: cubic-bezier(.63, 0, .2, 1);
transform: rotate(-42.5deg)
}
83% {
animation-timing-function: cubic-bezier(.8, 0, .84, 1);
transform: rotate(-42deg)
}
100% {
transform: rotate(-43deg)
}
}
.invfr {
position: absolute;
left: 0;
top: 0;
z-index: -1;
width: 0;
height: 0;
border: 0
}
.msgb {
position: absolute;
right: 0;
font-size: 12px;
font-weight: normal;
color: #000;
padding: 20px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loading" style="display:none">
<div style="bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0">
<div style="animation:a-h .5s 1.25s 1 linear forwards,a-nt .6s 1.25s 1 cubic-bezier(0,0,.2,1);background:#eee;border-radius:50%;height:800px;left:50%;margin:-448px -400px 0;position:absolute;top:50%;transform:scale(0);width:800px"></div>
</div>
<div style="height:100%;text-align:center">
<div style="height:50%;margin:0 0 -140px"></div>
<div style="height:128px;margin:0 auto;position:relative;width:176px">
<div style="animation:a-s .5s .5s 1 linear forwards,a-e 1.75s .5s 1 cubic-bezier(0,0,.67,1) forwards;opacity:0;transform:scale(.68)">
<div style="background:#ddd;border-radius:12px;box-shadow:0 15px 15px -15px rgba(0,0,0,.3);height:128px;left:0;overflow:hidden;position:absolute;top:0;transform:scale(1);width:176px">
<div style="animation:a-nt .667s 1.5s 1 cubic-bezier(.4,0,.2,1) forwards;background:#d23f31;border-radius:50%;height:270px;left:88px;margin:-135px;position:absolute;top:25px;transform:scale(.5);width:270px"></div>
<div style="height:128px;left:20px;overflow:hidden;position:absolute;top:0;transform:scale(1);width:136px">
<div style="background:#e1e1e1;height:128px;left:0;position:absolute;top:0;width:68px">
<div style="animation:a-h .25s 1.25s 1 forwards;background:#eee;height:128px;left:0;opacity:1;position:absolute;top:0;width:68px"></div>
</div>
<div style="background:#eee;height:100px;left:1px;position:absolute;top:56px;transform:scaleY(.73)rotate(135deg);width:200px"></div>
</div>
<div style="background:#bbb;height:176px;left:0;position:absolute;top:-100px;transform:scaleY(.73)rotate(135deg);width:176px">
<div style="background:#eee;border-radius:12px 12px 0 0;bottom:117px;height:12px;left:55px;position:absolute;transform:rotate(-135deg)scaleY(1.37);width:136px"></div>
<div style="background:#eee;height:96px;position:absolute;right:0;top:0;width:96px"></div>
<div style="box-shadow:inset 0 0 10px #888;height:155px;position:absolute;right:0;top:0;width:155px"></div>
</div>
<div style="animation:a-s .167s 1.283s 1 linear forwards,a-es 1.184s 1.283s 1 cubic-bezier(.4,0,.2,1) forwards;background:linear-gradient(0,rgba(38,38,38,0),rgba(38,38,38,.2));height:225px;left:0;opacity:0;position:absolute;top:0;transform:rotate(-43deg);transform-origin:0 13px;width:176px"></div>
</div>
<div style="animation:a-ef 1.184s 1.283s 1 cubic-bezier(.4,0,.2,1) forwards;border-radius:12px;height:100px;left:0;overflow:hidden;position:absolute;top:0;transform:scaleY(1);transform-origin:top;width:176px">
<div style="height:176px;left:0;position:absolute;top:-100px;transform:scaleY(.73)rotate(135deg);width:176px">
<div style="animation:a-s .167s 1.283s 1 linear forwards;box-shadow:-5px 0 12px rgba(0,0,0,.5);height:176px;left:0;opacity:0;position:absolute;top:0;width:176px"></div>
<div style="background:#ddd;height:176px;left:0;overflow:hidden;position:absolute;top:0;width:176px">
<div style="animation:a-nt .667s 1.25s 1 cubic-bezier(.4,0,.2,1) forwards;background:#db4437;border-radius:50%;bottom:41px;height:225px;left:41px;position:absolute;transform:scale(0);width:225px"></div>
<div style="background:#f1f1f1;height:128px;left:24px;position:absolute;top:24px;transform:rotate(90deg);width:128px"></div>
<div style="animation:a-efs 1.184s 1.283s 1 cubic-bezier(.4,0,.2,1) forwards;background:#fff;height:176px;opacity:0;transform:rotate(90deg);width:176px"></div>
</div>
</div>
</div>
</div>
</div>
<div id="nlpt"></div>
<div style="animation:a-s .25s 1.25s 1 forwards;opacity:0" class="msg">Loading Gmail…</div>
</div>
</div>
This is a jsFiddle that reproduces it.

css Synchronise keyframe animations

I'm looking to synchronise the keyframe animation of three different elements.
They are basically three hearts and I want them to follow a heartbeat animation when they are clicked.
When two or more are clicked, I want them to "beat" in sync.
You can check a JSbin here
What I have so far is :
.rating {
position: relative;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 140px;
height: 50px;
padding: 5px 10px;
margin: auto;
border-radius: 30px;
background: #FFF;
display: block;
overflow: hidden;
unicode-bidi: bidi-override;
direction: rtl;
}
.rating:not(:checked)>input {
display: none;
}
/* - - - - - LIKE */
#like {
bottom: -65px;
}
#like:not(:checked)>label {
cursor: pointer;
float: right;
width: 30px;
height: 30px;
display: block;
margin-right: 7.5px;
color: rgba(233, 54, 40, .4);
line-height: 42px;
text-align: center;
transition: color 0.2s;
}
#like:not(:checked)>label:hover,
#like:not(:checked)>label:hover~label {
color: rgba(233, 54, 40, .6);
}
#like>input:checked+label:hover,
#like>input:checked+label:hover~label,
#like>input:checked~label:hover,
#like>input:checked~label:hover~label,
#like>label:hover~input:checked~label {
color: rgb(233, 54, 40);
}
#like>input:checked~label {
color: rgb(233, 54, 40);
animation: 1s heartbeat infinite;
}
#keyframes heartbeat {
from {
transform: scale(1);
transform-origin: center center;
animation-timing-function: ease-out;
}
10% {
transform: scale(1.2);
animation-timing-function: ease-in;
}
15% {
transform: scale(1);
animation-timing-function: ease-out;
}
25% {
transform: scale(1.15);
animation-timing-function: ease-in;
}
35% {
transform: scale(1);
animation-timing-function: ease-out;
}
}
<section id="like" class="rating">
<!-- THIRD HEART -->
<input type="radio" id="heart_3" name="like" value="3" />
<label for="heart_3" class="heart-slider">♥</label>
<!-- SECOND HEART -->
<input type="radio" id="heart_2" name="like" value="2" />
<label for="heart_2" class="heart-slider">♥</label>
<!-- FIRST HEART -->
<input type="radio" id="heart_1" name="like" value="1" />
<label for="heart_1" class="heart-slider">♥</label>
</section>
What is the good way to achieve sync ?
Thank you
EDIT
Following Rounin's answer, here's the updated CSS that gets the job done :
#like {
}
#like:not(:checked) > label {
cursor:pointer;
float: right;
width: 30px;
height: 30px;
display: inline-block;
color: (255, 255, 255);
transition: color 0.2s;
}
#like:not(:checked) > label:hover,
#like:not(:checked) > label:hover ~ label {
color: rgba(252, 108, 133, 1);
}
#like > input:checked + label:hover,
#like > input:checked + label:hover ~ label,
#like > input:checked ~ label:hover,
#like > input:checked ~ label:hover ~ label,
#like > label:hover ~ input:checked ~ label {
color: rgb(252, 108, 133);
}
#like > input:checked ~ label {
color: rgb(252, 108, 133);
}
#heart_1:checked ~ label {
animation: heartbeat1 1s infinite;
}
#heart_2:checked ~ label {
animation: heartbeat2 1s infinite;
}
#heart_3:checked ~ label {
animation: heartbeat3 1s infinite;
}
#keyframes heartbeat1 {
from {
transform: scale(1);
transform-origin: center center;
animation-timing-function: ease-out;
}
10% {
transform: scale(1.2);
animation-timing-function: ease-in;
}
15% {
transform: scale(1);
animation-timing-function: ease-out;
}
25% {
transform: scale(1.15);
animation-timing-function: ease-in;
}
35% {
transform: scale(1);
animation-timing-function: ease-out;
}
}
#keyframes heartbeat2 {
from {
transform: scale(1);
transform-origin: center center;
animation-timing-function: ease-out;
}
10% {
transform: scale(1.2);
animation-timing-function: ease-in;
}
15% {
transform: scale(1);
animation-timing-function: ease-out;
}
25% {
transform: scale(1.15);
animation-timing-function: ease-in;
}
35% {
transform: scale(1);
animation-timing-function: ease-out;
}
}
#keyframes heartbeat3 {
from {
transform: scale(1);
transform-origin: center center;
animation-timing-function: ease-out;
}
10% {
transform: scale(1.2);
animation-timing-function: ease-in;
}
15% {
transform: scale(1);
animation-timing-function: ease-out;
}
25% {
transform: scale(1.15);
animation-timing-function: ease-in;
}
35% {
transform: scale(1);
animation-timing-function: ease-out;
}
}
You can set up 3 identical animations and style your inputs and labels such that when a new radio button is selected, the old animation stops and the new one begins. That way the hearts will always be in sync:
Working Example:
div {
display: block;
position: relative;
width: 125px;
height: 60px;
box-shadow: 3px 3px 3px rgba(127, 127, 127, 0.4);
}
input {
display: none;
}
label {
position: absolute;
display: inline-block;
top: 0;
font-size: 40px;
line-height: 60px;
color: rgba(255, 127, 127, 0.75);
}
label:hover,
label:hover ~ label {
color: rgba(255, 0, 0, 0.75);
}
.like1 {
left: 10px;
}
.like2 {
left: 50px;
}
.like3 {
left: 90px;
}
#like1:checked ~ label {
animation: heartbeat1 0.8s infinite;
}
#like2:checked ~ label {
animation: heartbeat2 0.8s infinite;
}
#like3:checked ~ label {
animation: heartbeat3 0.8s infinite;
}
#keyframes heartbeat1 {
0% {
color: rgba(255, 0, 0, 0.5);
}
50% {
color: rgba(255, 0, 0, 1);
}
}
#keyframes heartbeat2 {
0% {
color: rgba(255, 0, 0, 0.5);
}
50% {
color: rgba(255, 0, 0, 1);
}
}
#keyframes heartbeat3 {
0% {
color: rgba(255, 0, 0, 0.5);
}
50% {
color: rgba(255, 0, 0, 1);
}
}
<div>
<input type="radio" id="like3" name="likes" value="3" />
<label class="like3" for="like3">♥</label>
<input type="radio" id="like2" name="likes" value="2" />
<label class="like2" for="like2">♥</label>
<input type="radio" id="like1" name="likes" value="1" />
<label class="like1" for="like1">♥</label>
</div>
Modified #Rounin's answer to give you the output you require.
div {
display: block;
position: relative;
width: 125px;
height: 60px;
box-shadow: 3px 3px 3px rgba(127, 127, 127, 0.4);
}
input {
display: none;
}
label {
position: absolute;
display: inline-block;
top: 0;
font-size: 40px;
line-height: 60px;
color: rgba(255, 127, 127, 0.75);
}
label:hover,
label:hover~label {
color: rgba(255, 0, 0, 0.75);
}
.like1 {
left: 10px;
}
.like2 {
left: 50px;
}
.like3 {
left: 90px;
}
#like1:checked~label {
animation: heartbeat1 0.8s infinite;
}
#like2:checked~label {
animation: heartbeat2 0.8s infinite;
}
#like3:checked~label {
animation: heartbeat3 0.8s infinite;
}
#keyframes heartbeat1 {
0% {
transform: scale( .75);
}
20% {
transform: scale( 1);
}
40% {
transform: scale( .75);
}
60% {
transform: scale( 1);
}
80% {
transform: scale( .75);
}
100% {
transform: scale( .75);
}
}
#keyframes heartbeat2 {
0% {
transform: scale( .75);
}
20% {
transform: scale( 1);
}
40% {
transform: scale( .75);
}
60% {
transform: scale( 1);
}
80% {
transform: scale( .75);
}
100% {
transform: scale( .75);
}
}
#keyframes heartbeat3 {
0% {
transform: scale( .75);
}
20% {
transform: scale( 1);
}
40% {
transform: scale( .75);
}
60% {
transform: scale( 1);
}
80% {
transform: scale( .75);
}
100% {
transform: scale( .75);
}
}
<div>
<input type="radio" id="like3" name="likes" value="3" />
<label class="like3" for="like3">♥</label>
<input type="radio" id="like2" name="likes" value="2" />
<label class="like2" for="like2">♥</label>
<input type="radio" id="like1" name="likes" value="1" />
<label class="like1" for="like1">♥</label>
</div>

Open and close modal windows not working

What am trying to do is when a user clicks the ".inner" element it finds the modal window that is inside of it and removes the "slideOutLeft" class if there is one and then adds the "slideInLeft" class and fades in the overlay element. This works fine.
But what doesn't work is when you click the .closeBtn element it doesn't remove the "slideInLeft" and then add the "slideOutLeft" class. But when you click the black overlay behind the modal window it does function properly.
I'm obviously missing something but I can't figure it out.
Here is a fiddle with all my code
$(document).ready(function() {
$('.inner').click(function() {
$(this).find('.modalWindow').removeClass('slideOutLeft').addClass('slideInLeft').css('display', 'block');
$('.overlay').fadeToggle(500);
});
$('.closeBtn, .overlay').click(function() {
$('.modalWindow').removeClass('slideInLeft').addClass('slideOutLeft');
$('.overlay').fadeToggle(500);
});
});
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
width: 50%;
float: left;
text-align: center;
padding: 20px;
}
.modalBtn {
padding: 15px 30px;
border: 1px solid #333;
border-radius: 5px;
text-transform: uppercase;
}
.overlay {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
position: fixed;
top: 0;
left: 0;
z-index: 999997;
display: none;
}
.modalWindow {
width: 80%;
right: 0;
left: 0;
top: 50%;
margin: 0 auto;
height: auto;
position: fixed;
display: none;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
z-index: 999998;
background-color: white;
padding: 20px;
}
.closeBtn {
font-size: 32px;
color: #333;
position: absolute;
right: 20px;
top: 5px;
}
.inner:hover {
cursor: pointer;
}
/* Animations */
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
/*the animation definition*/
#-webkit-keyframes slideInLeft {
0% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible
}
100% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0)
}
}
#keyframes slideInLeft {
0% {
-webkit-transform: translate3d(-125%, 0, 0);
-ms-transform: translate3d(-125%, 0, 0);
transform: translate3d(-125%, 0, 0);
visibility: visible
}
100% {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0)
}
}
.slideInLeft {
-webkit-animation-name: slideInLeft;
animation-name: slideInLeft
}
#-webkit-keyframes slideOutLeft {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0)
}
100% {
visibility: hidden;
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0)
}
}
#keyframes slideOutLeft {
0% {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0)
}
100% {
visibility: hidden;
-webkit-transform: translate3d(-125%, 0, 0);
-ms-transform: translate3d(-125%, 0, 0);
transform: translate3d(-125%, 0, 0)
}
}
.slideOutLeft {
-webkit-animation-name: slideOutLeft;
animation-name: slideOutLeft
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="overlay" class="overlay"></div>
<div class="wrapper">
<div class="inner">
<div class="modalBtn">click for modal 1</div>
<div class="modalWindow animated">
<div class="closeBtn">X</div>
<span>This is modal window 1</span>
</div>
</div>
</div>
<div class="wrapper">
<div class="inner">
<div class="modalBtn">click for modal 2</div>
<div class="modalWindow animated">
<div class="closeBtn">X</div>
<span>This is modal window 2</span>
</div>
</div>
</div>
Problem is in your html structure, so when you click on close button you are clicking on .inner div, too:
Fix:
$('.closeBtn, .overlay').click(function(e){
e.stopPropagation();
$('.modalWindow').removeClass('slideInLeft').addClass('slideOutLeft');
$('.overlay').fadeToggle(500);
});
Demo: https://jsfiddle.net/ssjfu611/24/
The issue is your <div class="inner"> is still clickable please change your HTML mark up:
<div class="wrapper">
<div class="inner">
<div class="modalBtn">click for modal 1</div>
</div>
//KEEP THIS OUT OF THE INNER DIV
<div class="modalWindow animated">
<div class="closeBtn">X</div>
<span>This is modal window 1</span>
</div>
</div>
Then your JavaScript too:
$('.inner').click(function() {
$(this).parent().find('.modalWindow').removeClass('slideOutLeft').addClass('slideInLeft').css('display', 'block');
$('.overlay').fadeToggle(500);
});

Categories