実際に動作を確認したい人向け
https://jsfiddle.net/junya_5102/y8v713e4/2/
html
<div class="bomb black">
<span class="ledge"></span>
<div class="fuse"></div>
<div class="dust">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<p class="msg orange">Boooooom!</p>
</div>
</div>
CSS
.bomb{
position: fixed;
top: 50%;
left: 50%;
display: block;
width: 100px;
height: 100px;
border-radius: 100%;
transform: translate(-50%,-50%) rotate(5deg);
}
.bomb:before{
content: "";
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 100px;
height: 100px;
border-radius: 100%;
background-color: currentColor;
box-shadow: 0 0 1px 1px black inset;
transform: translate(-50%,-50%);
z-index: 1;
}
.bomb:after{
content: "";
position: absolute;
top: 15%;
left: 8%;
width: 50%;
height: 50%;
border-radius: 45%;
border: 5px solid transparent;
border-left: 5px dotted white;
transform: rotate(30deg);
box-sizing: border-box;
z-index: 2;
}
/* 出っ張り */
.bomb .ledge{
position: absolute;
left: 50%;
display: inline-block;
width: 30%;
height: 20%;
border-radius: 15% 15% 100% 100%;
background-color: currentColor;
transform: translate(-50%,-25%);
z-index: 2;
}
/* 導火線 */
.bomb .fuse{
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 99%;
height: 99%;
border: 3px solid transparent;
border-top-color: #D0BAA5;
border-right-color: #D0BAA5;
border-radius: 100%;
box-sizing: border-box;
transform: translate(-15%,-75%) rotate(-20deg);
z-index: -1;
}
.bomb .fuse:before,
.bomb .fuse:after{
content: "*";
position: absolute;
right: -.55em;
bottom: 0;
display: inline-block;
font-size: 1.5em;
}
.bomb .fuse:before{
color: red;
transform: translate(-50%,0) rotate(0);
}
.bomb .fuse:after{
color: orange;
transform: translate(-50%,0) rotate(30deg);
}
.bomb .dust{
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate(-50%,-50%);
}
/* 画面がちらつく場合はshadowの指定数を減らすと良い */
.dust span{
position: absolute;
top: 50%;
left: 50%;
display: inline-block;
width: 25px;
height: 25px;
border-radius: 100%;
background-color: blue;
box-shadow:
+30px -30px 0 0 green,
-30px +30px 0 0 purple,
+60px +60px 0 0 pink,
-60px -60px 0 0 red;
backface-visibility: hidden;
transform: translate(-50%,-50%) rotate(var(--angle)) translateY(0);
opacity: 0;
z-index: 2;
}
.dust span:nth-of-type(1){ --angle: 00deg; }
.dust span:nth-of-type(2){ --angle: 30deg; }
.dust span:nth-of-type(3){ --angle: 60deg; }
.dust span:nth-of-type(4){ --angle: 90deg; }
.dust span:nth-of-type(5){ --angle: 120deg; }
.dust span:nth-of-type(6){ --angle: 150deg; }
.dust span:nth-of-type(7){ --angle: 180deg; }
.dust span:nth-of-type(8){ --angle: 210deg; }
.dust span:nth-of-type(9){ --angle: 240deg; }
.dust span:nth-of-type(10){ --angle: 270deg; }
.dust span:nth-of-type(11){ --angle: 300deg; }
.dust span:nth-of-type(12){ --angle: 330deg; }
.dust .msg{
position: absolute;
top: 50%;
left: 50%;
display: inline-block;
margin: 0;
text-shadow: 2px 2px 0 black;
opacity: 0;
transform: translate(-50%,-50%);
z-index: 3;
}
.orange{
color: orange;
}
.black{
color: black;
}
/* animation */
.bomb:before,.bomb:after,
.bomb .ledge{ animation: after_exp 1s 3s steps(1,start) forwards; }
.bomb .fuse{ animation:
fuse_anim 3s linear,
after_exp 1s 3s steps(1,start) forwards;
}
.bomb .fuse:before{ animation: burning 3s linear; }
.bomb .fuse:after { animation: burning 3s linear reverse;}
.dust span{ animation: explosion 3s 3s linear; }
.dust .msg{ animation: message 3s 3s linear; }
@keyframes fuse_anim{
49%{
border-top-color: #D0BAA5;
}
50%{
border-top-color: transparent;
}
100%{
border-top-color: transparent;
transform: translate(-15%,-75%) rotate(-200deg);
}
}
@keyframes burning{
to{
transform: translate(-50%,0) rotate(360deg);
}
}
@keyframes explosion{
from{
opacity: 1;
transform: translate(-50%,-50%) rotate(var(--angle)) translateY(50px);
}
to{
opacity: 0;
transform: translate(-50%,-50%) rotate(var(--angle)) translateY(-200px) scale(.5);
}
}
/* 爆発後 */
@keyframes after_exp{
to{
opacity: 0;
}
}
@keyframes message{
from{
opacity: 1;
}
to{
font-size: 4.5em;
}
}
Variables(変数)を使ったアニメーション
transformは値を維持できない
回転度数が違う要素があり回転を維持しつつアニメーションさせる場合
度数別にアニメーションを作る必要があります
E1{ transform: translate(-50%,-50%) rotate(30deg) translateX(0);
animation: anim1 3s linear infinite;
}
E2{ transform: translate(-50%,-50%) rotate(60deg) translateX(0);
animation: anim2 3s linear infinite;
}
E3{ transform: translate(-50%,-50%) rotate(90deg) translateX(0);
animation: anim3 3s linear infinite;
}
@keyframes anim1{
from{
translate(-50%,-50%) rotate(30deg) translateY(50px);
}
to{
translate(-50%,-50%) rotate(30deg) translateY(-100px);
}
}
@keyframes anim2{
from{
translate(-50%,-50%) rotate(60deg) translateY(50px);
}
to{
translate(-50%,-50%) rotate(60deg) translateY(-100px);
}
}
@keyframes anim3{
from{
translate(-50%,-50%) rotate(90deg) translateY(50px);
}
to{
translate(-50%,-50%) rotate(90deg) translateY(-100px);
}
}
とても長くなりますし管理が大変になります。
変数を使う
変数を使えばアニメーション1つで度数別に対応が可能です
E1{ --angle: 30deg; }
E2{ --angle: 60deg; }
E3{ --angle: 90deg; }
E1,E2,E3{
transform: translate(-50%,-50%) rotate(var(--angle)) translateX(0);
animation: anim 3s linear infinite;
}
@keyframes anim{
from{
translate(-50%,-50%) rotate(var(--angle)) translateY(50px);
}
to{
translate(-50%,-50%) rotate(var(--angle)) translateY(-100px);
}
}
対応ブラウザ
※最新版で試しています。
Google Chrome, Safari , Firefox
CSS Variables を使っているので非対応だとアニメーションがうまく動作しない。
http://caniuse.com/#feat=css-variables