I want to create a calendar like set of 12 images that appear to flip up when clicked. I know about turn.js but I don't know enough javascript to start from scratch. I do have a programming background and am willing to learn but don't know where to start.
http://pageflip-books.com/index.php#ppp/page/1
is something like what I'm looking for but I want to show the top pages not the bottom ones.
Most of the examples I have found are for books/magazines with two pages side by side.
Thanks for any pointers.
I would look into CSS animations if I were you. An example can be found here: https://codepen.io/ryrocks/pen/zovXWy
HTML
<!-- https://cssdeck.com/labs/pure-css3-page-flip-effect -->
<div id="all">
<div id="page-flip">
<div id="r1">
<div id="p1">
<div>
<div></div>
</div>
</div>
</div>
<div id="p2">
<div></div>
</div>
<div id="r3">
<div id="p3">
<div>
<div></div>
</div>
</div>
</div>
<div class="s">
<div id="s3">
<div id="sp3"></div>
</div>
</div>
<div class="s" id="s4">
<div id="s2">
<div id="sp2"></div>
</div>
</div>
<a id="coke" href="#" title="Pure CSS Coke Can"></a>
<a id="meninas" href="#" title="CSS 3D Meninas"></a>
</div>
</div>
CSS
body {
padding: 0;
margin: 0;
}
#all {
width: 680px;
margin-left: auto;
margin-right: auto;
}
#page-flip {
background-image: url(https://cssdeck.com/uploads/media/items/6/6h4pDpK.jpg);
position: absolute;
padding: 40px 40px 40px 340px;
width: 300px;
height: 400px;
overflow: hidden;
}
#r1 {
position: absolute;
z-index: 2;
-webkit-transform-origin: 1315px 500px;
-webkit-transform: translate(-1030px, -500px) rotate(-32deg);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
}
#p1 {
width: 1285px;
height: 1388px;
overflow: hidden;
}
#p1 > div {
-webkit-transform-origin: 285px 0;
-webkit-transform: translate(1030px, 500px) rotate(32deg);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
width: 285px;
height: 388px;
background-image: url(https://cssdeck.com/uploads/media/items/8/87WOlJH.jpg);
}
#p1 > div > div {
width: 10px;
height: 388px;
background: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .25)), to(rgba(0,0,0,0)));
}
#p2 > div {
width: 285px;
height: 388px;
-webkit-box-shadow: 0 0 11px rgba(0, 0, 0, .5);
position: absolute;
z-index: 1;
background-image: url(https://cssdeck.com/uploads/media/items/4/4FpEEbu.jpg);
}
#r3 {
-webkit-transform-origin: 1315px 500px;
-webkit-transform: translate(-1030px, -500px) rotate(-32deg);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
position: absolute;
z-index: 2;
}
#s3 {
-webkit-transform-origin: 70px 500px;
-webkit-transform: translate(215px, -500px) rotate(-32deg) translate(40px, 0);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
position: absolute;
z-index: 1;
}
#page-flip:hover #s3 {
-webkit-transform-origin: 325px 500px;
-webkit-transform: translate(-40px, -500px) rotate(0deg) translate(40px, 0);
}
#sp3 {
width: 25px;
height: 1000px;
background: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .25)), to(rgba(0,0,0,0)));
-webkit-transition-property: width;
-webkit-transition-duration: 1s;
overflow: hidden;
}
#page-flip:hover #sp3 { width: 11px }
.s {
width: 285px;
height: 388px;
position: absolute;
overflow: hidden;
z-index: 3;
}
#s2 {
-webkit-transform-origin: 45px 500px;
-webkit-transform: translate(240px, -500px) rotate(-32deg);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
position: absolute;
}
#sp2 {
width: 15px;
height: 1000px;
background: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, .18)), to(rgba(0,0,0,0)));
overflow: hidden;
}
#s4 {
opacity: 1;
-webkit-transition-duration: 0.5s;
}
#page-flip:hover #s4 { opacity: 0 }
#page-flip:hover #s2 {
-webkit-transform-origin: 300px 500px;
-webkit-transform: translate(-15px, -500px) rotate(0deg);
}
#p3 {
width: 1285px;
height: 1388px;
overflow: hidden;
}
#p3 > div {
-webkit-transform-origin: 0 0;
-webkit-transform: translate(1255px, 500px) rotate(-32deg);
-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
-webkit-transition-duration: 1s;
-webkit-box-shadow: 0 0 11px rgba(0, 0, 0, .5);
width: 285px;
height: 388px;
background-image: url(https://cssdeck.com/uploads/media/items/6/6S8oF28.jpg);
overflow: hidden;
}
#p3 > div > div {
width: 9px;
height: 500px;
float: right;
background: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0)), to(rgba(0,0,0,.20)));
}
#page-flip:hover #r1 {
-webkit-transform-origin: 1570px 500px;
-webkit-transform: translate(-1285px, -500px) rotate(0deg);
}
#page-flip:hover #p1 > div {
-webkit-transform-origin: 285px 0;
-webkit-transform: translate(1285px, 500px) rotate(0deg);
}
#page-flip:hover #r3 {
-webkit-transform-origin: 1570px 500px;
-webkit-transform: translate(-1285px, -500px) rotate(0deg);
}
#page-flip:hover #p3 > div {
-webkit-transform-origin: 0 0;
-webkit-transform: translate(1000px, 500px) rotate(0deg);
}
a {
display: block;
position: absolute;
margin: -20000px 0 0 0;
padding: 1px;
z-index: 3;
-webkit-transition-property: margin;
-webkit-transition-duration: 0.01s;
}
#coke {
width: 253px;
height: 158px;
}
a:hover {
padding: 0;
border: 1px dotted #92C7C1;
}
#page-flip:hover #coke {
-webkit-transition-delay: .8s;
margin: 33px 0 0 14px;
}
#meninas {
width: 253px;
height: 167px;
}
#page-flip:hover #meninas {
-webkit-transition-delay: .8s;
margin: 203px 0 0 14px;
}
In this example hover triggers the page flip, but you can modify that to be triggered by a Javascript click event and to show the page that you prefer when the event occurs.
Related
I'm using a code snippet from a website for a circular progress bar, but now I am stuck. I can't solve how to stop progress bar at particular point (let's say 73% or 90%). How can I achieve that?
const numb = document.querySelector(".numb");
let counter = 0;
setInterval(() => {
if (counter == 100) {
clearInterval();
} else {
counter += 1;
numb.textContent = counter + "%";
}
}, 80);
.circular {
height: 150px;
width: 150px;
position: relative;
}
.circular .inner,
.circular .outer,
.circular .circle {
position: absolute;
z-index: 6;
height: 100%;
width: 100%;
border-radius: 100%;
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .inner {
top: 36%;
left: 37%;
height: 117px;
width: 117px;
margin: -40px 0 0 -40px;
background-color: #ffffff;
border-radius: 100%;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
.circular .circle {
z-index: 1;
box-shadow: none;
}
.circular .numb {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
font-size: 18px;
font-weight: 500;
color: #4158d0;
}
.circular .bar {
position: absolute;
height: 100%;
width: 100%;
background: #F2F5F5;
-webkit-border-radius: 100%;
clip: rect(0px, 150px, 150px, 75px);
}
.circle .bar .progress {
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 75px, 150px, 0px);
}
.circle .bar .progress,
.dot span {
background: #4158d0;
}
.circle .left .progress {
z-index: 1;
animation: left 4s linear both;
}
#keyframes left {
100% {
transform: rotate(180deg);
}
}
.circle .right {
z-index: 3;
transform: rotate(180deg);
}
.circle .right .progress {
animation: right 4s linear both;
animation-delay: 4s;
}
#keyframes right {
100% {
transform: rotate(180deg);
}
}
.circle .dot {
z-index: 2;
position: absolute;
left: 50%;
top: 50%;
width: 50%;
height: 10px;
margin-top: -5px;
animation: dot 8s linear both;
transform-origin: 0% 50%;
}
.circle .dot span {
position: absolute;
right: 0;
width: 16px;
height: 16px;
border-radius: 100%;
}
#keyframes dot {
0% {
transform: rotate(-90deg);
}
50% {
transform: rotate(90deg);
z-index: 4;
}
100% {
transform: rotate(270deg);
z-index: 4;
}
}
<div class="circular">
<div class="inner"></div>
<div class="outer"></div>
<div class="numb">
0%
</div>
<div class="circle">
<div class="dot">
<span></span>
</div>
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>
Maybe you could say if(counter == 73) { animation.pause() }
const numb = document.querySelector(".numb");
let counter = 0;
setInterval(()=>{
if(counter == 73){
clearInterval();
}else{
counter+=1;
numb.textContent = counter + "%";
}
}, 80);
.circular{
height: 150px;
width: 150px;
position: relative;
}
.circular .inner, .circular .outer, .circular .circle{
position: absolute;
z-index: 6;
height: 100%;
width: 100%;
border-radius: 100%;
box-shadow: inset 0 1px 0 rgba(0,0,0,0.2);
}
.circular .inner{
top: 36%;
left: 37%;
height: 117px;
width: 117px;
margin: -40px 0 0 -40px;
background-color: #ffffff;
border-radius: 100%;
box-shadow: 0 1px 0 rgba(0,0,0,0.2);
}
.circular .circle{
z-index: 1;
box-shadow: none;
}
.circular .numb{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
font-size: 18px;
font-weight: 500;
color: #4158d0;
}
.circular .bar{
position: absolute;
height: 100%;
width: 100%;
background: #F2F5F5;
-webkit-border-radius: 100%;
clip: rect(0px, 150px, 150px, 75px);
}
.circle .bar .progress{
position: absolute;
height: 100%;
width: 100%;
-webkit-border-radius: 100%;
clip: rect(0px, 75px, 150px, 0px);
}
.circle .bar .progress, .dot span{
background: #4158d0;
}
.circle .left .progress{
z-index: 1;
animation: left 4s linear both;
}
#keyframes left {
100%{
transform: rotate(180deg);
}
}
.circle .right{
z-index: 3;
transform: rotate(180deg);
}
.circle .right .progress{
animation: right 4s linear both;
animation-delay: 4s;
}
#keyframes right {
100%{
transform: rotate(80deg);
}
}
.circle .dot{
position: absolute;
left: 50%;
top: 50%;
width: 50%;
height: 10px;
margin-top: -5px;
animation: dot 8s linear both;
transform-origin: 0% 50%;
}
.circle .dot span {
position: absolute;
right: 0;
width: 16px;
height: 16px;
border-radius: 100%;
}
#keyframes dot{
0% {
transform: rotate(-90deg);
}
50% {
transform: rotate(90deg);
z-index: 4;
}
100% {
transform: rotate(270deg);
z-index: 4;
}
}
<div class="circular">
<div class="inner"></div>
<div class="outer"></div>
<div class="numb">
0%
</div>
<div class="circle">
<div class="bar left">
<div class="progress"></div>
</div>
<div class="bar right">
<div class="progress"></div>
</div>
</div>
</div>
Goal: finished product as picture attached with only the bubbles rising inside the glass.
Hey, I am working on this CSS /JS code and I need the final version of filled glass only with bubbles and foam on top (ignoring all the delays and fillings in animations). I tried but somehow unsuccessful, any suggestions where to edit the code? thanks
$(document).ready(function() {
$('.pour')
.delay(2000)
.animate({
height: '360px'
}, 1500)
.delay(1600)
.slideUp(500);
$('#liquid')
.delay(3400)
.animate({
height: '170px'
}, 2500);
$('.beer-foam')
.delay(3400)
.animate({
bottom: '200px'
}, 2500);
});
body { background-color: #0065bd }
h2 {
margin: 0 auto;
width: 400px;
font-size: 36px;
text-align: center;
font-family: 'Lato', Arial, sans-serif;
color: whiteSmoke;
}
#container {
height: 370px;
margin: 0 auto;
overflow: hidden;
position: relative;
top: -20px;
width: 248px;
}
#container div { position: absolute; }
.pour {
position: absolute;
left: 45%;
width: 20px;
height: 0px;
background-color: #0065bd;
border-radius: 10px
}
#beaker {
border: 10px solid #FFF;
border-top: 0;
border-radius: 0 0 30px 30px;
height: 200px;
left: 14px;
bottom: 0;
width: 200px;
}
#beaker:before,
#beaker:after {
border: 00px solid #FFF;
border-bottom: 0;
border-radius: 30px 30px 0 0;
content: '';
height: 30px;
position: absolute;
top: -40px;
width: 30px;
}
#beaker:before { left: -50px; }
#beaker:after { right: -50px; }
#liquid {
background-color: #0065bd;
border: 10px solid #0065bd;
border-radius: 0 0 20px 20px;
bottom: 0;
height: 0px;
overflow: hidden;
width: 180px;
}
#liquid:after {
background-color: rgba(255, 255, 255, 0.25);
bottom: -10px;
content: '';
height: 200px;
left: -40px;
position: absolute;
transform: rotate(30deg);
-webkit-transform: rotate(15deg);
width: 110px;
}
#liquid .bubble {
-webkit-animation-name: bubble;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
background-color: rgba(255, 255, 255, 0.2);
bottom: 0;
border-radius: 10px;
height: 20px;
width: 20px;
}
#-webkit-keyframes bubble {
0% { bottom: 0; }
50% {
background-color: rgba(255, 255, 255, 0.2);
bottom: 80px;
}
100% {
background-color: rgba(255, 255, 255, 0);
bottom: 160px;
}
}
.bubble1 {
left: 10px;
-webkit-animation-delay: 1000ms;
-webkit-animation-duration: 1000ms;
}
.bubble2 {
left: 50px;
-webkit-animation-delay: 700ms;
-webkit-animation-duration: 1100ms;
}
.bubble3 {
left: 100px;
-webkit-animation-delay: 1200ms;
-webkit-animation-duration: 1300ms;
}
.bubble4 {
left: 130px;
-webkit-animation-delay: 1100ms;
-webkit-animation-duration: 700ms;
}
.bubble5 {
left: 170px;
-webkit-animation-delay: 1300ms;
-webkit-animation-duration: 800ms;
}
/* Foam */
.beer-foam {
position: absolute;
bottom: 10px;
}
.foam-1, .foam-2, .foam-3, .foam-4,
.foam-5, .foam-6, .foam-7 {
float: left;
position: absolute;
z-index: 999;
width: 50px;
height: 50px;
border-radius: 30px;
background-color: #fefefe;
}
.foam-1 {
top: -30px;
left: -10px;
}
.foam-2 {
top: -35px;
left: 20px;
}
.foam-3 {
top: -25px;
left: 50px;
}
.foam-4 {
top: -35px;
left: 80px;
}
.foam-5 {
top: -30px;
left: 110px;
}
.foam-6 {
top: -20px;
left: 140px;
}
.foam-7 {
top: -30px;
left: 160px;
}
/* Drunk Text */
#-moz-keyframes drunk {
0% {
-moz-transform: rotate(0);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
20%, 60% {
-moz-transform: rotate(80deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
40% {
-moz-transform: rotate(60deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
80% {
-moz-transform: rotate(60deg) translateY(0); opacity: 1;
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
100% {
-moz-transform: translateY(700px);
opacity: 0;
}
}
#keyframes drunk {
0% {
transform: rotate(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
80% {
transform: rotate(60deg) translateY(0);
opacity: 1; transform-origin: top left;
animation-timing-function: ease-in-out;
}
100% {
transform: translateY(700px);
opacity: 0;
}
}
.drunk {
-webkit-animation-name: drunk;
-moz-animation-name: drunk;
animation-name: drunk;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div class="pour"></div>
<div id="beaker">
<div class="beer-foam">
<div class="foam-1"></div>
<div class="foam-2"></div>
<div class="foam-3"></div>
<div class="foam-4"></div>
<div class="foam-5"></div>
<div class="foam-6"></div>
<div class="foam-7"></div>
</div>
<div id="liquid">
<div class="bubble bubble1"></div>
<div class="bubble bubble2"></div>
<div class="bubble bubble3"></div>
<div class="bubble bubble4"></div>
<div class="bubble bubble5"></div>
</div>
</div>
</div>
<h2 class="animated drunk">Please Wait! While you are entered in Game</h2>
Filling the glass instantly, but bubbles moving
To instantly fill the glass, you can remove the delay:
$(document).ready(function() {
/*Look here*/
$('.pour')
.css({
height: '360px'
})
.delay(0)
.slideUp(500);
$('#liquid')
.css({
height: '170px'
});
$('.beer-foam')
.css({
bottom: '200px'
});
});
body { background-color: #0065bd }
h2 {
margin: 0 auto;
width: 400px;
font-size: 36px;
text-align: center;
font-family: 'Lato', Arial, sans-serif;
color: whiteSmoke;
}
#container {
height: 370px;
margin: 0 auto;
overflow: hidden;
position: relative;
top: -20px;
width: 248px;
}
#container div { position: absolute; }
.pour {
position: absolute;
left: 45%;
width: 20px;
height: 0px;
background-color: #0065bd;
border-radius: 10px
}
#beaker {
border: 10px solid #FFF;
border-top: 0;
border-radius: 0 0 30px 30px;
height: 200px;
left: 14px;
bottom: 0;
width: 200px;
}
#beaker:before,
#beaker:after {
border: 00px solid #FFF;
border-bottom: 0;
border-radius: 30px 30px 0 0;
content: '';
height: 30px;
position: absolute;
top: -40px;
width: 30px;
}
#beaker:before { left: -50px; }
#beaker:after { right: -50px; }
#liquid {
background-color: #0065bd;
border: 10px solid #0065bd;
border-radius: 0 0 20px 20px;
bottom: 0;
height: 0px;
overflow: hidden;
width: 180px;
}
#liquid:after {
background-color: rgba(255, 255, 255, 0.25);
bottom: -10px;
content: '';
height: 200px;
left: -40px;
position: absolute;
transform: rotate(30deg);
-webkit-transform: rotate(15deg);
width: 110px;
}
#liquid .bubble {
-webkit-animation-name: bubble;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
background-color: rgba(255, 255, 255, 0.2);
bottom: 0;
border-radius: 10px;
height: 20px;
width: 20px;
}
#-webkit-keyframes bubble {
0% { bottom: 0; }
50% {
background-color: rgba(255, 255, 255, 0.2);
bottom: 80px;
}
100% {
background-color: rgba(255, 255, 255, 0);
bottom: 160px;
}
}
.bubble1 {
left: 10px;
-webkit-animation-delay: 1000ms;
-webkit-animation-duration: 1000ms;
}
.bubble2 {
left: 50px;
-webkit-animation-delay: 700ms;
-webkit-animation-duration: 1100ms;
}
.bubble3 {
left: 100px;
-webkit-animation-delay: 1200ms;
-webkit-animation-duration: 1300ms;
}
.bubble4 {
left: 130px;
-webkit-animation-delay: 1100ms;
-webkit-animation-duration: 700ms;
}
.bubble5 {
left: 170px;
-webkit-animation-delay: 1300ms;
-webkit-animation-duration: 800ms;
}
/* Foam */
.beer-foam {
position: absolute;
bottom: 10px;
}
.foam-1, .foam-2, .foam-3, .foam-4,
.foam-5, .foam-6, .foam-7 {
float: left;
position: absolute;
z-index: 999;
width: 50px;
height: 50px;
border-radius: 30px;
background-color: #fefefe;
}
.foam-1 {
top: -30px;
left: -10px;
}
.foam-2 {
top: -35px;
left: 20px;
}
.foam-3 {
top: -25px;
left: 50px;
}
.foam-4 {
top: -35px;
left: 80px;
}
.foam-5 {
top: -30px;
left: 110px;
}
.foam-6 {
top: -20px;
left: 140px;
}
.foam-7 {
top: -30px;
left: 160px;
}
/* Drunk Text */
#-moz-keyframes drunk {
0% {
-moz-transform: rotate(0);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
20%, 60% {
-moz-transform: rotate(80deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
40% {
-moz-transform: rotate(60deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
80% {
-moz-transform: rotate(60deg) translateY(0); opacity: 1;
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
100% {
-moz-transform: translateY(700px);
opacity: 0;
}
}
#keyframes drunk {
0% {
transform: rotate(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
80% {
transform: rotate(60deg) translateY(0);
opacity: 1; transform-origin: top left;
animation-timing-function: ease-in-out;
}
100% {
tran
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div class="pour"></div>
<div id="beaker">
<div class="beer-foam">
<div class="foam-1"></div>
<div class="foam-2"></div>
<div class="foam-3"></div>
<div class="foam-4"></div>
<div class="foam-5"></div>
<div class="foam-6"></div>
<div class="foam-7"></div>
</div>
<div id="liquid">
<div class="bubble bubble1"></div>
<div class="bubble bubble2"></div>
<div class="bubble bubble3"></div>
<div class="bubble bubble4"></div>
<div class="bubble bubble5"></div>
</div>
</div>
</div>
<h2 class="animated drunk">Please Wait! While you are entered in Game</h2>
Pausing the bubbles
To pause the bubbles, you can use the animation-play-state: paused; property. This particular way would pause your bubbles after 5.7 seconds:
$(document).ready(function() {
/*Look here*/
setTimeout( () => {
$('.bubble').css("animation-play-state", "paused");
}, 5700)
$('.pour')
.delay(2000)
.animate({
height: '360px'
}, 1500)
.delay(1600)
.slideUp(500);
$('#liquid')
.delay(3400)
.animate({
height: '170px'
}, 2500);
$('.beer-foam')
.delay(3400)
.animate({
bottom: '200px'
}, 2500);
});
body { background-color: #0065bd }
h2 {
margin: 0 auto;
width: 400px;
font-size: 36px;
text-align: center;
font-family: 'Lato', Arial, sans-serif;
color: whiteSmoke;
}
#container {
height: 370px;
margin: 0 auto;
overflow: hidden;
position: relative;
top: -20px;
width: 248px;
}
#container div { position: absolute; }
.pour {
position: absolute;
left: 45%;
width: 20px;
height: 0px;
background-color: #0065bd;
border-radius: 10px
}
#beaker {
border: 10px solid #FFF;
border-top: 0;
border-radius: 0 0 30px 30px;
height: 200px;
left: 14px;
bottom: 0;
width: 200px;
}
#beaker:before,
#beaker:after {
border: 00px solid #FFF;
border-bottom: 0;
border-radius: 30px 30px 0 0;
content: '';
height: 30px;
position: absolute;
top: -40px;
width: 30px;
}
#beaker:before { left: -50px; }
#beaker:after { right: -50px; }
#liquid {
background-color: #0065bd;
border: 10px solid #0065bd;
border-radius: 0 0 20px 20px;
bottom: 0;
height: 0px;
overflow: hidden;
width: 180px;
}
#liquid:after {
background-color: rgba(255, 255, 255, 0.25);
bottom: -10px;
content: '';
height: 200px;
left: -40px;
position: absolute;
transform: rotate(30deg);
-webkit-transform: rotate(15deg);
width: 110px;
}
#liquid .bubble {
-webkit-animation-name: bubble;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
background-color: rgba(255, 255, 255, 0.2);
bottom: 0;
border-radius: 10px;
height: 20px;
width: 20px;
}
#-webkit-keyframes bubble {
0% { bottom: 0; }
50% {
background-color: rgba(255, 255, 255, 0.2);
bottom: 80px;
}
100% {
background-color: rgba(255, 255, 255, 0);
bottom: 160px;
}
}
.bubble1 {
left: 10px;
-webkit-animation-delay: 1000ms;
-webkit-animation-duration: 1000ms;
}
.bubble2 {
left: 50px;
-webkit-animation-delay: 700ms;
-webkit-animation-duration: 1100ms;
}
.bubble3 {
left: 100px;
-webkit-animation-delay: 1200ms;
-webkit-animation-duration: 1300ms;
}
.bubble4 {
left: 130px;
-webkit-animation-delay: 1100ms;
-webkit-animation-duration: 700ms;
}
.bubble5 {
left: 170px;
-webkit-animation-delay: 1300ms;
-webkit-animation-duration: 800ms;
}
/* Foam */
.beer-foam {
position: absolute;
bottom: 10px;
}
.foam-1, .foam-2, .foam-3, .foam-4,
.foam-5, .foam-6, .foam-7 {
float: left;
position: absolute;
z-index: 999;
width: 50px;
height: 50px;
border-radius: 30px;
background-color: #fefefe;
}
.foam-1 {
top: -30px;
left: -10px;
}
.foam-2 {
top: -35px;
left: 20px;
}
.foam-3 {
top: -25px;
left: 50px;
}
.foam-4 {
top: -35px;
left: 80px;
}
.foam-5 {
top: -30px;
left: 110px;
}
.foam-6 {
top: -20px;
left: 140px;
}
.foam-7 {
top: -30px;
left: 160px;
}
/* Drunk Text */
#-moz-keyframes drunk {
0% {
-moz-transform: rotate(0);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
20%, 60% {
-moz-transform: rotate(80deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
40% {
-moz-transform: rotate(60deg);
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
80% {
-moz-transform: rotate(60deg) translateY(0); opacity: 1;
-moz-transform-origin: top left;
-moz-animation-timing-function: ease-in-out;
}
100% {
-moz-transform: translateY(700px);
opacity: 0;
}
}
#keyframes drunk {
0% {
transform: rotate(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
80% {
transform: rotate(60deg) translateY(0);
opacity: 1; transform-origin: top left;
animation-timing-function: ease-in-out;
}
100% {
tran
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div class="pour"></div>
<div id="beaker">
<div class="beer-foam">
<div class="foam-1"></div>
<div class="foam-2"></div>
<div class="foam-3"></div>
<div class="foam-4"></div>
<div class="foam-5"></div>
<div class="foam-6"></div>
<div class="foam-7"></div>
</div>
<div id="liquid">
<div class="bubble bubble1"></div>
<div class="bubble bubble2"></div>
<div class="bubble bubble3"></div>
<div class="bubble bubble4"></div>
<div class="bubble bubble5"></div>
</div>
</div>
</div>
<h2 class="animated drunk">Please Wait! While you are entered in Game</h2>
If you setthe timeout to 5700, you'll end up with something like this, which is pretty close to your image.
Stopping the bubbles (previous solution)
You could also fiddle with the iteration count and visibility of your bubbles, to kill them after some time, maybe like so:
#liquid .bubble {
visibility: hidden; /*Look here*/
-webkit-animation-name: bubble;
-webkit-animation-iteration-count: 3; /*Look here*/
-webkit-animation-timing-function: linear;
background-color: rgba(255, 255, 255, 0.2);
bottom: 0;
border-radius: 10px;
height: 20px;
width: 20px;
}
#-webkit-keyframes bubble {
0% { visibility: visible; /*Look here*/
bottom: 0; }
50% {
background-color: rgba(255, 255, 255, 0.2);
bottom: 80px;
}
100% {
background-color: rgba(255, 255, 255, 0);
bottom: 160px;
}
}
The numbers depend on the exact effect you'll want, but this would be the way I'd do it. This particular set would send some bubbles and then end the bubbling.
I'm fairly new to front-end dev so please spare me...Anyway, for this codepen project I'm trying to get the animation where a stack of pancakes falls to the plate to activate when you click the button. It should be just an empty plate until the button is clicked.
Not sure why my JS code isn't working but if I target the pancake or stack class, the visuals still remain static.
HTML:
<div class="container">
<div class="plate">
<div class="inner-plate">
</div>
</div>
<button onclick="onclick()">Good Morning!</button>
<div class="stack">
<div class="pancake">
<div class="top-p"></div>
</div>
<div class="pancake p2">
<div class="top-p"></div>
</div>
<div class="pancake p3">
<div class="top-p"></div>
</div>
<div class="pancake p4">
<div class="top-p"></div>
</div>
<div class="pancake p5">
<div class="top-p"></div>
</div>
<div class="pancake p6">
<div class="top-p"></div>
<div class="butter">
<div class = "shadow"></div>
<div class = "top-b"></div>
<div class = "shine"></div>
</div>
</div>
</div>
CSS (snippet):
/*------BUTTON------*/
button {
display: inline-block;
border: none;
margin-top: 25%;
padding: 1em 2em;
/*CSS center element trick*/
position: absolute;
/* Gradient */
background: linear-gradient(90deg, #FF5F6D 0%, rgba(255, 195, 113, 0.88) 100%);
box-shadow: 0px 4px 10px rgba(255, 95, 109, 0.25);
border-radius: 40px;
/*text*/
position: relative;
text-transform: uppercase;
font-family: Montserrat, system-ui;
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 15px;
letter-spacing: 0.14px;
color: #fff;
cursor: pointer;
transition: all 0.1s linear;
}
button:hover {
transform: translateY(-6px);
background: linear-gradient(90deg, #FF777C 0%, #FFC487 100%);
box-shadow: 0px 6px 5px rgba(255, 95, 109, 0.25);
}
.plate {
position: relative;
width: 100%;
height: 100%;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
box-shadow: 0px 4px 4px rgba(165, 75, 75, 0.15);
}
.inner-plate {
position: relative;
width: 75%;
height: 30px;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
margin: 5px auto; /*stacked "plates" without flexboxes*/
}
/*------ELEMENTS TO ANIMATE------*/
.pancake {
display: inline-block;
position: absolute;
width: 65%;
height: 25%;
left: 18%;
top: 0;
background: #FFE68E;
border-radius: 50%;
z-index: 1;
}
.top-p {
position: absolute;
width: 95%;
height: 80%;
left: 2.25%;
background: linear-gradient(180deg, rgba(222, 159, 101, 0.75) 0%, #E09148 100%);
border-radius: 50%;
}
.slideIn {
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
}
/*------ KEYFRAMES -----*/
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
JS:
$(function() {
$('button').onclick(function() {
$('.pancake').addClass('slideIn');
});
})
There are a bunch of things are not right, I've fixed them and marked them with FIX
$(function() {
$('button').click(function() {
// FIX: you forgot the dot
$('.pancake').addClass('slideIn');
});
});
#import url('https://fonts.googleapis.com/css?family=Montserrat:600&display=swap');
* {
outline: none;
/*NOTE: removing the blue outline for links and buttons is a terrible UI/UX decision for accessibility! Some folks do not have the motor skills to use a mouse and use the alternative Tab button instead. This is purely just for show and practice :-) */
}
body {
position: relative;
height: 100vh;
padding: 0;
margin: 0;
background: #FDF6D0;
display: flex;
align-items: center;
text-align: center;
}
.container{
position: absolute;
margin-top: auto;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
}
/*------BUTTON------*/
button {
display: inline-block;
border: none;
margin-top: 25%;
padding: 1em 2em;
/*CSS center element trick*/
position: absolute;
/* Gradient */
background: linear-gradient(90deg, #FF5F6D 0%, rgba(255, 195, 113, 0.88) 100%);
box-shadow: 0px 4px 10px rgba(255, 95, 109, 0.25);
border-radius: 40px;
/*text*/
position: relative;
text-transform: uppercase;
font-family: Montserrat, system-ui;
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 15px;
letter-spacing: 0.14px;
color: #fff;
cursor: pointer;
transition: all 0.1s linear;
}
button:hover {
transform: translateY(-6px);
background: linear-gradient(90deg, #FF777C 0%, #FFC487 100%);
box-shadow: 0px 6px 5px rgba(255, 95, 109, 0.25);
}
.plate {
position: relative;
width: 100%;
height: 100%;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
box-shadow: 0px 4px 4px rgba(165, 75, 75, 0.15);
}
.inner-plate {
position: relative;
width: 75%;
height: 30px;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
margin: 5px auto; /*stacked "plates" without flexboxes*/
}
/*------ELEMENTS TO ANIMATE------*/
.pancake {
display: inline-block;
position: absolute;
width: 65%;
height: 25%;
left: 18%;
top: 0;
background: #FFE68E;
border-radius: 50%;
z-index: 1;
/*pancakes falling*/
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
/* FIX: Pause the animation on start */
animation-play-state: paused;
}
/* FIX: Resume the animation when this class is added */
.slideIn {
animation-play-state: running;
}
.top-p {
position: absolute;
width: 95%;
height: 80%;
left: 2.25%;
background: linear-gradient(180deg, rgba(222, 159, 101, 0.75) 0%, #E09148 100%);
border-radius: 50%;
}
.p2 {
z-index: 2;
top: -7%;
left: 18%;
}
.p3 {
z-index: 3;
top: -14%;
left: 18%;
}
.p4 {
z-index: 4;
top: -21%;
left: 18%;
}
.p5 {
z-index: 5;
top: -28%;
left: 18%;
}
.p6 {
z-index: 6;
top: -35%;
left: 18%;
}
/*BUTTER*/
.shadow {
position: absolute;
z-index: 8;
top: -7%;
left: 42%;
height: 30%;
width: 15%;
margin: auto;
background: #FFDE68;
border-radius: 1px;
box-shadow: 1px 2px 2px rgba(202, 133, 65, 0.75);
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.top-b {
position: absolute;
z-index: 9;
top: -10%;
left: 45%;
height: 25%;
width: 10%;
margin: auto;
background: #FFEFB5;
border-radius: 1px;
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.shine{
position: absolute;
z-index: 10;
top: -4%;
left: 49%;
height: 7%;
width: 4%;
margin: auto;
background: #FFF;
border-radius: 1px;
transform: rotate(45deg);
}
.slideIn {
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
}
/*------ KEYFRAMES -----*/
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
<!-- FIX: You forgot to import the jquery in CodePen! -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="container">
<div class="plate">
<div class="inner-plate">
</div>
</div>
<!-- FIX: You don't need to bind function here since you've already done it in js.-->
<button>Good Morning!</button>
<div class="stack">
<div class="pancake">
<div class="top-p"></div>
</div>
<div class="pancake p2">
<div class="top-p"></div>
</div>
<div class="pancake p3">
<div class="top-p"></div>
</div>
<div class="pancake p4">
<div class="top-p"></div>
</div>
<div class="pancake p5">
<div class="top-p"></div>
</div>
<div class="pancake p6">
<div class="top-p"></div>
<div class="butter">
<div class = "shadow"></div>
<div class = "top-b"></div>
<div class = "shine"></div>
</div>
</div>
</div>
the class identifier is wrong it should be $(".pancake")
$(function() {
$('button').onclick(function() {
$('.pancake').addClass('slideIn');
});
})
javascript
You need to add the class identifier . in $(".pancake")
$(function() {
$('button').click(function() {
$('.pancake').addClass('slideIn');
});
})
#import url('https://fonts.googleapis.com/css?family=Montserrat:600&display=swap');
* {
outline: none;
/*NOTE: removing the blue outline for links and buttons is a terrible UI/UX decision for accessibility! Some folks do not have the motor skills to use a mouse and use the alternative Tab button instead. This is purely just for show and practice :-) */
}
body {
position: relative;
height: 100vh;
padding: 0;
margin: 0;
background: #FDF6D0;
display: flex;
align-items: center;
text-align: center;
}
.container{
position: absolute;
margin-top: auto;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
}
/*------BUTTON------*/
button {
display: inline-block;
border: none;
margin-top: 25%;
padding: 1em 2em;
/*CSS center element trick*/
position: absolute;
/* Gradient */
background: linear-gradient(90deg, #FF5F6D 0%, rgba(255, 195, 113, 0.88) 100%);
box-shadow: 0px 4px 10px rgba(255, 95, 109, 0.25);
border-radius: 40px;
/*text*/
position: relative;
text-transform: uppercase;
font-family: Montserrat, system-ui;
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 15px;
letter-spacing: 0.14px;
color: #fff;
cursor: pointer;
transition: all 0.1s linear;
}
button:hover {
transform: translateY(-6px);
background: linear-gradient(90deg, #FF777C 0%, #FFC487 100%);
box-shadow: 0px 6px 5px rgba(255, 95, 109, 0.25);
}
.plate {
position: relative;
width: 100%;
height: 100%;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
box-shadow: 0px 4px 4px rgba(165, 75, 75, 0.15);
}
.inner-plate {
position: relative;
width: 75%;
height: 30px;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
margin: 5px auto; /*stacked "plates" without flexboxes*/
}
/*------ELEMENTS TO ANIMATE------*/
.pancake {
display: inline-block;
position: absolute;
width: 65%;
height: 25%;
left: 18%;
top: 0;
background: #FFE68E;
border-radius: 50%;
z-index: 1;
/*pancakes falling*/
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
}
.top-p {
position: absolute;
width: 95%;
height: 80%;
left: 2.25%;
background: linear-gradient(180deg, rgba(222, 159, 101, 0.75) 0%, #E09148 100%);
border-radius: 50%;
}
.p2 {
z-index: 2;
top: -7%;
left: 18%;
}
.p3 {
z-index: 3;
top: -14%;
left: 18%;
}
.p4 {
z-index: 4;
top: -21%;
left: 18%;
}
.p5 {
z-index: 5;
top: -28%;
left: 18%;
}
.p6 {
z-index: 6;
top: -35%;
left: 18%;
}
/*BUTTER*/
.shadow {
position: absolute;
z-index: 8;
top: -7%;
left: 42%;
height: 30%;
width: 15%;
margin: auto;
background: #FFDE68;
border-radius: 1px;
box-shadow: 1px 2px 2px rgba(202, 133, 65, 0.75);
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.top-b {
position: absolute;
z-index: 9;
top: -10%;
left: 45%;
height: 25%;
width: 10%;
margin: auto;
background: #FFEFB5;
border-radius: 1px;
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.shine{
position: absolute;
z-index: 10;
top: -4%;
left: 49%;
height: 7%;
width: 4%;
margin: auto;
background: #FFF;
border-radius: 1px;
transform: rotate(45deg);
}
.slideIn {
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
}
/*------ KEYFRAMES -----*/
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="plate">
<div class="inner-plate">
</div>
</div>
<button>Good Morning!</button>
<div class="stack">
<div class="pancake">
<div class="top-p"></div>
</div>
<div class="pancake p2">
<div class="top-p"></div>
</div>
<div class="pancake p3">
<div class="top-p"></div>
</div>
<div class="pancake p4">
<div class="top-p"></div>
</div>
<div class="pancake p5">
<div class="top-p"></div>
</div>
<div class="pancake p6">
<div class="top-p"></div>
<div class="butter">
<div class = "shadow"></div>
<div class = "top-b"></div>
<div class = "shine"></div>
</div>
</div>
</div>
Use following js (i remove animation from css .pancake class and add transform: translateY(-1000px); to it)
function onClick() {
[...document.querySelectorAll('.pancake')]
.map(x=> x.classList.add('slideIn'));
}
function onClick() {
[...document.querySelectorAll('.pancake')].map(x=> x.classList.add('slideIn'));
}
#import url('https://fonts.googleapis.com/css?family=Montserrat:600&display=swap');
* {
outline: none;
/*NOTE: removing the blue outline for links and buttons is a terrible UI/UX decision for accessibility! Some folks do not have the motor skills to use a mouse and use the alternative Tab button instead. This is purely just for show and practice :-) */
}
body {
position: relative;
height: 100vh;
padding: 0;
margin: 0;
background: #FDF6D0;
display: flex;
align-items: center;
text-align: center;
}
.container{
position: absolute;
margin-top: auto;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
}
/*------BUTTON------*/
button {
display: inline-block;
border: none;
margin-top: 25%;
padding: 1em 2em;
/*CSS center element trick*/
position: absolute;
/* Gradient */
background: linear-gradient(90deg, #FF5F6D 0%, rgba(255, 195, 113, 0.88) 100%);
box-shadow: 0px 4px 10px rgba(255, 95, 109, 0.25);
border-radius: 40px;
/*text*/
position: relative;
text-transform: uppercase;
font-family: Montserrat, system-ui;
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 15px;
letter-spacing: 0.14px;
color: #fff;
cursor: pointer;
transition: all 0.1s linear;
}
button:hover {
transform: translateY(-6px);
background: linear-gradient(90deg, #FF777C 0%, #FFC487 100%);
box-shadow: 0px 6px 5px rgba(255, 95, 109, 0.25);
}
.plate {
position: relative;
width: 100%;
height: 100%;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
box-shadow: 0px 4px 4px rgba(165, 75, 75, 0.15);
}
.inner-plate {
position: relative;
width: 75%;
height: 30px;
background: #FFFFFF;
/* Stroke */
border: 1.25px solid #F9EADC;
border-radius: 50%;
margin: 5px auto; /*stacked "plates" without flexboxes*/
}
/*------ELEMENTS TO ANIMATE------*/
.pancake {
display: inline-block;
position: absolute;
width: 65%;
height: 25%;
left: 18%;
top: 0;
background: #FFE68E;
border-radius: 50%;
z-index: 1;
/*pancakes falling*/
transform: translateY(-1000px);
}
.top-p {
position: absolute;
width: 95%;
height: 80%;
left: 2.25%;
background: linear-gradient(180deg, rgba(222, 159, 101, 0.75) 0%, #E09148 100%);
border-radius: 50%;
}
.p2 {
z-index: 2;
top: -7%;
left: 18%;
}
.p3 {
z-index: 3;
top: -14%;
left: 18%;
}
.p4 {
z-index: 4;
top: -21%;
left: 18%;
}
.p5 {
z-index: 5;
top: -28%;
left: 18%;
}
.p6 {
z-index: 6;
top: -35%;
left: 18%;
}
/*BUTTER*/
.shadow {
position: absolute;
z-index: 8;
top: -7%;
left: 42%;
height: 30%;
width: 15%;
margin: auto;
background: #FFDE68;
border-radius: 1px;
box-shadow: 1px 2px 2px rgba(202, 133, 65, 0.75);
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.top-b {
position: absolute;
z-index: 9;
top: -10%;
left: 45%;
height: 25%;
width: 10%;
margin: auto;
background: #FFEFB5;
border-radius: 1px;
transform: matrix(0.74, -0.44, 0.98, 0.77, 0, 0);
}
.shine{
position: absolute;
z-index: 10;
top: -4%;
left: 49%;
height: 7%;
width: 4%;
margin: auto;
background: #FFF;
border-radius: 1px;
transform: rotate(45deg);
}
.slideIn {
-webkit-animation: slideIn 1s linear both;
animation: slideIn 1s linear both;
}
/*------ KEYFRAMES -----*/
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#-webkit-keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
#keyframes slideIn {
0% {
-webkit-transform: translateY(-1000px);
transform: translateY(-1000px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
}
<div class="container">
<div class="plate">
<div class="inner-plate">
</div>
</div>
<button onclick="onClick()">Good Morning!</button>
<div class="stack">
<div class="pancake">
<div class="top-p"></div>
</div>
<div class="pancake p2">
<div class="top-p"></div>
</div>
<div class="pancake p3">
<div class="top-p"></div>
</div>
<div class="pancake p4">
<div class="top-p"></div>
</div>
<div class="pancake p5">
<div class="top-p"></div>
</div>
<div class="pancake p6">
<div class="top-p"></div>
<div class="butter">
<div class = "shadow"></div>
<div class = "top-b"></div>
<div class = "shine"></div>
</div>
</div>
</div>
I have this flipcard I put together, and when you hover over it, it flips 180 degrees on it's x-axis, and then expands. When I mouse-off of the element, I would like for this element to flip back the opposite way smoothly, the way it came in. Instead of the sudden change back when you mouseout like it is right now.
Also, it should be noted that I would like the animation to use animation: forwards for as long as the mouse is hovering over the element. (ie. so long as the user is hovering over the element, it should remain flipped, and enlarged.)
Is there any way to do this using just CSS? Or will I need Javascript? If so, I'd like to do this with pure Vanilla JS.
I have been poking around for solutions on Stack Overflow, and can't seem to find a definitive answer, or am not typing in the correct question.
html, body {
background: #f2edea;
height: 100%;
width: 100%;
}
.container {
width: 250px;
height: 320px;
margin: auto;
position: relative;
top: 35%;
}
img {
width: 100%;
max-height: 100%;
}
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
}
#keyframes grow {
from {
transform: rotateY(0) scale(1);
}
to {
transform: rotateY(180deg) scale(2);
}
}
.flipcard:hover {
animation: grow 1s forwards;
}
.front-side {
height: 100%;
width: 100%;
position: relative;
backface-visibility: hidden;
}
.back-side {
width: 100%;
height: 100%;
transform: rotateY(180deg);
position: absolute;
top: 0;
border-radius: 3px;
}
<div class='container'>
<div class='flipcard'>
<div class='front-side'>
<img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
</div>
<div class='back-side'>
<img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
</div>
</div>
</div>
You'd better use transition between normal and hover states.
Note that you have to track hover on .container to avoid jumping and flickering.
html, body {
background: #f2edea;
height: 100%;
width: 100%;
}
.container {
width: 250px;
height: 320px;
margin: auto;
position: relative;
}
img {
width: 100%;
max-height: 100%;
}
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
transition: all .5s ease-in-out;
}
.container:hover .flipcard {
transform: rotateY(180deg) scale(2);
}
.front-side {
height: 100%;
width: 100%;
position: relative;
backface-visibility: hidden;
}
.back-side {
width: 100%;
height: 100%;
transform: rotateY(180deg);
position: absolute;
top: 0;
border-radius: 3px;
}
<div class='container'>
<div class='flipcard'>
<div class='front-side'>
<img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
</div>
<div class='back-side'>
<img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
</div>
</div>
</div>
The reason this happens is because on the default non-hover state there's no animation state to return to. You have two options for this.
Don't use animations and just transition the effect on hover.
This way on out the properties will return to their non-hover state with transition.
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
transform: rotateY(0) scale(1);
transition: all 0.3s ease;
}
.flipcard:hover {
transform: rotateY(180deg) scale(2);
}
https://jsfiddle.net/255mnwxr/5/
To have a out animation property.
This is least desired because on load the animation will play once for it to animate then it acts naturally afterwards.
.flipcard {
animation: return 1s forwards;
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
transition: all 0.3s ease;
}
#keyframes grow {
from {
transform: rotateY(0) scale(1);
}
to {
transform: rotateY(180deg) scale(2);
}
}
#keyframes return {
from {
transform: rotateY(180deg) scale(2);
}
to {
transform: rotateY(0) scale(1);
}
}
https://jsfiddle.net/255mnwxr/2/
You need to add #keyframes on the mouse in and out hover.
html, body {
background: #f2edea;
height: 100%;
width: 100%;
}
.container {
width: 250px;
height: 320px;
margin: auto;
position: relative;
top: 35%;
}
img {
width: 100%;
max-height: 100%;
}
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
}
#-webkit-keyframes in {
from { -webkit-transform: rotate(0deg); }
to {-webkit-transform: rotateY(180deg) scale(2);}
}
#-webkit-keyframes out {
0% { -webkit-transform: rotateY(180deg) scale(2); }
100% { -webkit-transform: rotate(0deg); }
}
.flipcard:hover {
animation: out 1s forwards;
}
.flipcard {
animation: in 1s forwards;
}
.front-side {
height: 100%;
width: 100%;
position: relative;
backface-visibility: hidden;
}
.back-side {
width: 100%;
height: 100%;
transform: rotateY(180deg);
position: absolute;
top: 0;
border-radius: 3px;
}
<div class='container'>
<div class='flipcard'>
<div class='front-side'>
<img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
</div>
<div class='back-side'>
<img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
</div>
</div>
</div>
You don't need a keyframe animation for this, you could just use basic CSS transitions for this, they'll rewind on mouseout with the transition property:
.flipcard {
transform: rotateY(0) scale(1);
transition: 1s all ease-out;
}
.flipcard:hover {
transform: rotateY(180deg) scale(2);
}
However, if you do want to use animations (for more complex interactions) I have a snippet for that at the bottom, just know this can be a little harder to maintain, and just reversing it on the default element won't work.
Also note that you may want a mouse-container that doesn't rotate but controls the hover state otherwise the mouse may fall off part way through the transition, like:
.flipcard-container:hover .flipcard {
transform: rotateY(180deg) scale(2);
}
html, body {
background: #f2edea;
height: 100%;
width: 100%;
}
.container {
width: 250px;
height: 320px;
margin: auto;
position: relative;
top: 35%;
}
img {
width: 100%;
max-height: 100%;
}
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
transform: rotateY(0) scale(1);
transition: 1s all ease-out;
}
.flipcard:hover {
transform: rotateY(180deg) scale(2);
}
.front-side {
height: 100%;
width: 100%;
position: relative;
backface-visibility: hidden;
}
.back-side {
width: 100%;
height: 100%;
transform: rotateY(180deg);
position: absolute;
top: 0;
border-radius: 3px;
}
<div class='container'>
<div class='flipcard'>
<div class='front-side'>
<img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
</div>
<div class='back-side'>
<img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
</div>
</div>
</div>
html, body {
background: #f2edea;
height: 100%;
width: 100%;
}
.container {
width: 250px;
height: 320px;
margin: auto;
position: relative;
top: 35%;
}
img {
width: 100%;
max-height: 100%;
}
#keyframes grow {
from {
transform: rotateY(0) scale(1);
}
to {
transform: rotateY(180deg) scale(2);
}
}
#keyframes shrink {
from {
transform: rotateY(180deg) scale(2);
}
to {
transform: rotateY(0) scale(1);
}
}
.flipcard {
height: 100%;
width: 100%;
margin: auto;
top: 20%;
position: relative;
box-shadow: 5px 5px 20px #94989e;
border: 3px solid #b8b8ba;
border-radius: 5px;
background: pink;
transform-style: preserve-3d;
transform: rotateY(0) scale(1);
animation: shrink 1s forwards;
}
.flipcard:hover {
animation: grow 1s forwards;
}
.front-side {
height: 100%;
width: 100%;
position: relative;
backface-visibility: hidden;
}
.back-side {
width: 100%;
height: 100%;
transform: rotateY(180deg);
position: absolute;
top: 0;
border-radius: 3px;
}
<div class='container'>
<div class='flipcard'>
<div class='front-side'>
<img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
</div>
<div class='back-side'>
<img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
</div>
</div>
</div>
I am very new to this CSS animation things and I have followed a tutorial making 3D rotating elements from this site http://www.the-art-of-web.com/css/3d-transforms/
This is my rotating 4 sided 3D square: https://jsfiddle.net/k0u8kn4w/
Now I want to use JS to make the side of the square to only rotate once to the second side when I clicked on it. So let's say the initial side is side A (not moving), when I click on it, I want it to rotate to show side B (rotate once 90 deg), when I click on it again, turn to side C, click again then turn to side D, another click turn to side A and so on.
Have tried manipulating the animation-play-state with running and paused, doesn't work, tried also manipulating the rotateY and TranslateZ degree, not sure how to manipulate the keyframes, couldn't find it anywhere.
#-webkit-keyframes spinner {
from {
-webkit-transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(0deg);
}
}
#keyframes spinner {
from {
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
transform: rotateY(-360deg);
}
}
#stage {
margin: 1em auto;
-webkit-perspective: 1200px;
-moz-perspective: 1200px;
-ms-perspective: 1200px;
perspective: 1200px;
}
#spinner {
-webkit-animation-name: spinner;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 6s;
-webkit-animation-play-state: running;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 6s;
animation-play-state: running;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
}
#spinner div,
#spinner img {
position: absolute;
border: 1px solid #ccc;
background: rgba(255, 255, 255, 0.8);
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
}
<div id='stage' style='height: 160px; width: 180px;'>
<div id='spinner'>
<div style='-webkit-transform: rotateY(90deg) translateZ(90px); padding: 0 0px; background: red; width: 180px; height: 160px; display: inline-block;' class='rotating'>A</div>
<div style='-webkit-transform: rotateY(180deg) translateZ(90px); padding: 0 0; background: blue; width: 180px; height: 160px; display: inline-block;'>B</div>
<div style='-webkit-transform: rotateY(270deg) translateZ(90px); padding: 0 0; background: green; width: 180px; height: 160px; display: inline-block;'>C</div>
<div style='-webkit-transform: rotateY(360deg) translateZ(90px); padding: 0 0; background: yellow; width: 180px; height: 160px; display: inline-block;' class='rotating'>D</div>
</div>
</div>
You just need to resume animation and wait for 1/4 of animation duration.
Simplified your code (removed vendor prefixes, most of browsers work OK without them, but reapply them if needed). Demo:
var spinner = document.querySelector("#spinner");
// get animation duration in ms
var animationDuration = parseFloat(window.getComputedStyle(spinner)["animation-duration"]) * 1000;
spinner.addEventListener("click", function() {
// run animation
spinner.style["animation-play-state"] = "running";
// pause animation after animationDuration / 4
setTimeout(function() {
spinner.style["animation-play-state"] = "paused";
}, animationDuration / 4);
});
#keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
#stage {
margin: 1em auto;
perspective: 1200px;
}
#spinner {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 6s;
animation-play-state: paused; /* new */
transform-style: preserve-3d;
}
#spinner div,
#spinner img {
position: absolute;
border: 1px solid #ccc;
background: rgba(255, 255, 255, 0.8);
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
}
<div id='stage' style='height: 160px; width: 180px;'>
<div id='spinner'>
<div style='transform: rotateY(90deg) translateZ(90px); padding: 0 0px; background: red; width: 180px; height: 160px; display: inline-block;' class='rotating'>A</div>
<div style='transform: rotateY(180deg) translateZ(90px); padding: 0 0; background: blue; width: 180px; height: 160px; display: inline-block;'>B</div>
<div style='transform: rotateY(270deg) translateZ(90px); padding: 0 0; background: green; width: 180px; height: 160px; display: inline-block;'>C</div>
<div style='transform: rotateY(360deg) translateZ(90px); padding: 0 0; background: yellow; width: 180px; height: 160px; display: inline-block;' class='rotating'>D</div>
</div>
</div>