ソースコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Bubble</title>
<link rel="stylesheet" href="bubble.css">
<script src="bubble.js"></script>
</head>
<body>
<div class="bubble-area"></div>
</body>
</html>
html,body{
width:100%;
height:100%;
padding:0;
margin:0;
}
.bubble-area{
background: linear-gradient(to bottom, #6ca4e4 0%, #0c2b84 100%);
width:100%;
height:100%;
position:relative;
overflow:hidden;
}
.bubble-move{
position:absolute;
width:50px;
height:50px;
transition-delay : 0s;
transition-duration : 10s;
transition-property : top;
transition-timing-function : linear;
}
.bubble-move[data-mode="1"]{
transition-timing-function : linear;
}
.bubble-move[data-mode="2"]{
transition-timing-function : ease;
}
.bubble-move[data-mode="3"]{
transition-timing-function : ease-in-out;
}
.bubble-shake{
position:absolute;
width:100%;
height:100%;
border:1px solid rgba(255,255,255,0.5);
border-radius:50%;
box-shadow: 0px 0px 15px 0px rgba(255, 255, 255, 0.6) inset;
animation-delay : 0s;
animation-timing-function: ease;
animation-iteration-count: infinite;
animation-direction : normal;
}
.bubble-shake[data-shake="1"]{
animation-name : shake-1;
animation-duration : 2.0s;
}
.bubble-shake[data-shake="2"]{
animation-name : shake-2;
animation-duration : 2.5s;
}
.bubble-shake[data-shake="3"]{
animation-name : shake-3;
animation-duration : 3.0s;
}
.bubble-shake[data-shake="4"]{
animation-name : shake-4;
animation-duration : 3.5s;
}
.bubble-shake:after {
content: "";
display: block;
width: 20%;
height: 20%;
border-radius: 100%;
background: rgba(255, 255, 255, 0.8);
position: absolute;
right: 15%;
top: 15%;
filter: blur(2px);
transform: rotateZ(45deg) scaleY(0.8);
}
@keyframes shake {
0% {transform : translateX( 10px)}
50% {transform : translateX(-10px)}
100% {transform : translateX( 10px)}
}
@keyframes shake-1 {
0% {transform : translateX( 10px)}
50% {transform : translateX(-10px)}
100% {transform : translateX( 10px)}
}
@keyframes shake-2 {
0% {transform : translateX(-15px)}
50% {transform : translateX( 15px)}
100% {transform : translateX(-15px)}
}
@keyframes shake-3 {
0% {transform : translateX( 20px)}
50% {transform : translateX(-20px)}
100% {transform : translateX( 20px)}
}
@keyframes shake-4 {
0% {transform : translateX(-25px)}
50% {transform : translateX( 25px)}
100% {transform : translateX(-25px)}
}
(function(){
var MAIN = function(){
this.area = document.querySelector(".bubble-area");
if(!this.area){return;}
this.borns();
};
MAIN.prototype.borns = function(){
var num = this.get_rand(20,40);
for(var i=0; i<num; i++){
this.set_item();
}
};
MAIN.prototype.set_item = function(){
if(!this.area){return;}
var item = document.createElement("div");
var shake = document.createElement("div");
shake.className = "bubble-shake";
var shake_num = this.get_rand(1,4);
shake.setAttribute("data-shake" , shake_num);
item.appendChild(shake);
var pos = this.get_random_pos();
item.className = "bubble-move";
var move_num = this.get_rand(1,3);
shake.setAttribute("data-move" , move_num);
var id = (+new Date());
item.setAttribute("data-id" , id);
item.style.setProperty("top" , pos.top +"px");
item.style.setProperty("left" , pos.left+"px");
var scale = this.get_scale(0.3,1.0);
item.style.setProperty("transform" , "scale("+scale+")");
var duration = scale * 10000 /2;
item.style.setProperty("transition-duration" , duration +"ms" , "important");
item.ontransitionend = (function(e){
var elm = e.target;
elm.parentNode.removeChild(elm);
this.set_item();
}).bind(this);
this.area.appendChild(item);
var rand_time = this.get_rand(0,10000);
setTimeout((function(item){
item.style.setProperty("top" , "-60px" , "");
}).bind(this , item) , rand_time);
};
MAIN.prototype.get_random_pos = function(){
return {
top : this.area.offsetHeight,
left : Math.floor(Math.random() * this.area.offsetWidth)
};
};
MAIN.prototype.get_scale = function(min , max){
return Math.floor((Math.random() * (max - min) + min)*100) / 100;
};
MAIN.prototype.get_rand = function(min , max){
return Math.floor((Math.random() * (max - min) + min));
};
window.addEventListener("load",function(){new MAIN()});
})()
解説
基本的にhtmlには、"bubble-area"というクラス名がついた器の中に、泡を発生させる仕様で、bubble.cssとbubble.jsを事前に読み込んでおく事を前提に設計しています。 cssでの重な内容は、泡1個分のcssを作っているんですが、左右の揺れと、上に移動する処理を別々に行うために、"bubble-move"と"bubble-shake"という2つのdivを自動で作るようにしています。 それをjavascriptで、画面(器)の底辺にx座標をランダムで配置して、タイミングをずらして、画面上部に座標移動すると、cssのトランジション処理で、泡が上に移動していくようにしています。 一番上まで到達した泡は、transitionendイベントを受け取って、自然に消えるようにセットしてみました。 泡が次から次へと生まれてきた時に、エレメントが残った状態では、そのページの処理速度が重くなるだろうと考えて、泡の最大個数を最初に表示して、その後は1個消えたら1個追加するという仕様にしています。 こうすることで、非常に軽い状態を保つことが可能になります。プレビュー
See the Pen Bubble by YugetaKoji (@geta1972) on CodePen.
0 件のコメント:
コメントを投稿