<div id="bubble-container" class="animakuz-container gradient-bg-blue">
<!-- bubble prototype -->
<!-- <div class="bubble bubble-part bubble-1">
<div class="soft-light base-light bubble-part">
</div>
<div class="mid-light top-light bubble-part">
</div>
<div class="mid-light bottom-light bubble-part">
</div>
<div class="hard-light off-light-1 bubble-part">
</div>
<div class="hard-light off-light-2 bubble-part">
</div>
</div> -->
<!-- options -->
<button id="btn-show-options">^</button>
<div id="options" class="box">
<p class="options-title">
<span class="title-text">Bubble Options</span>
<button id="btn-hide-options">X</button>
</p>
<p class="options-body">
<label>Bubble Density</label>
<input id="txt-bubble-density" type="text" value="10">
<button id="btn-generate">Generate</button>
</p>
</div>
<!-- show error message on input to bubble density -->
<div id="message-box" class="box message-box error-message">
<p id="message-line" class="message">
<span id="message-icon" class="error-icon">!</span>
<span id="message-text">Error</span>
</p>
<button id="message-button">OK</button>
</div>
</div>
/* interface */
body, html {
overflow: hidden;
}
/* boxes */
.box {
border-radius: 5px;
border: 1px solid rgba(200,200,250,0.4);
background-color: rgba(150,150,200,0.4);
box-shadow: 0 2px 4px rgba(50,50,100,0.4);
}
.active-box {
display: block !important;
}
#btn-show-options, #options {
position: absolute;
left: 50%;
transform: translateX(-50%);
z-index: 2;
}
#btn-show-options {
display: block;
bottom: 10px;
height: 32px;
padding: 4px 14px 0;
font-size: 32px;
border-radius: 4px;
cursor: pointer;
border: 1px solid rgba(200,200,250,0.2);
box-shadow: 0 2px 4px rgba(50,50,100,0.2);
background-color: rgba(60,60,200,0.2);
color: rgba(220,220,240,0.8);
}
#btn-show-options:hover {
background-color: rgba(60,60,200,0.8);
color: rgba(220,220,240,1);
}
#options {
display: none;
bottom: 10%;
}
.options-title {
margin: 0;
height: 24px;
line-height: 24px;
background-color: rgba(50,50,150,0.2);
border-radius: 5px 5px 0 0;
}
.options-title .title-text {
margin-left: 10px;
color: #dedede;
}
#btn-hide-options {
cursor: pointer;
position: absolute;
right: 0;
top: 0;
border-radius: 5px;
border: 0;
height: 24px;
width: 24px;
font-size: 12px;
font-weight: bold;
background-color: rgba(200,60,60,0.8);
color: rgb(240,220,220);
}
#btn-hide-options:hover {
color: rgba(200,60,60,0.8);
background-color: rgb(240,220,220);
}
.options-body {
margin: 20px 20px 10px;
}
.options-body label {
color: #dedede;
margin-right: 10px;
}
#txt-bubble-density {
width: 40px;
text-align: center;
border: 1px solid rgba(0,0,0,0.14);
border-radius: 4px;
padding: 2px 5px;
}
#btn-generate {
border: 0;
cursor: pointer;
border-radius: 5px;
padding: 8px 10px;
margin-left: 4px;
background-color: rgba(20,150,20, 0.8);
color: rgb(220,240,220);
}
#btn-generate:hover {
background-color: rgb(220,240,220);
color: rgba(10,100,10, 0.8);
}
@media (max-width: 767px) {
#options {
}
.options-body label {
display: block;
margin: 5px auto 10px;
text-align: center;
}
}
#txt-bubble-density {
}
#btn-generate {
}
.message-box {
display: none;
padding: 14px 20px 10px;
position: absolute;
top: 30%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.message-box .message {
margin: 0 auto 15px;
/* font-weight: bold;*/
text-align: center;
}
.message-box #message-icon {
display: inline-block;
margin-right: 5px;
width: 20px;
height: 20px;
line-height: 22px;
text-align: center;
border-radius: 50%;
color: #fff;
}
.message-box #message-button {
border: 0;
border-radius: 5px;
padding: 4px 16px;
cursor: pointer;
color: #fff;
background-color: rgba(50,100,150, 0.8);
}
.message-box #message-button:hover {
color: rgba(50,100,150, 0.8);
background-color: rgba(250,250,250,0.8);
}
.error-message {
color: rgb(200,20,20);
}
.error-icon {
background-color: rgba(255,50,50,1);
}
.confirm-message {
color: rgb(200,250,200);
}
.confirm-icon {
background-color: rgba(0,150,0,1);
}
/*-- bubble construction */
.bubble-part {
border-radius: 50%;
position: absolute;
}
.bubble {
background-color: rgba(50,50,100,0.1);
}
.soft-light {
background: radial-gradient(rgba(255,255,255,0.3),
rgba(255,255,255,0.1), rgba(255,255,255,0));
}
.mid-light {
background: radial-gradient(rgba(255,255,255,0.4),
rgba(255,255,255,0.1), rgba(255,255,255,0));
transform: rotateZ(-30deg);
}
.hard-light {
background: radial-gradient(rgba(255,255,255,0.4),
rgba(255,255,255,0.4));
transform: rotateZ(-30deg);
}
.base-light {
top: 3%;
left: 3%;
width: 94%;
height: 94%;
}
.top-light {
top: 10%;
left: 15%;
width: 40%;
height: 30%;
}
.bottom-light {
width: 60%;
height: 50%;
top: 40%;
left: 35%;
transform: rotateZ(-40deg);
}
.off-light-1 {
width: 6%;
height: 6%;
top: 35%;
left: 30%;
}
.off-light-2 {
width: 10%;
height: 10%;
top: 50%;
left: 25%;
opacity: 0.8;
}
/*--bubble animation*/
@keyframes bubbleRise {
from {
top: 100%;
}
to {
top: -20%;
}
}
var baseFunc = {
getRandomInt: function(min, max) {
//get random integer between a specific range
//Source - Ionuț G. Stan - StackOverflow - Answer 06/10/09
return Math.floor(Math.random() * (max - min + 1)) + min;
},
addClass: function(element, classesToAdd) {
//add a class or multiple classes to an element
var newClassName = element.className.trim().replace(/\s+/g,' ') + ' ';
var newClasses = classesToAdd.split(/\s+/);
var len = newClasses.length;
var ind = 0;
while(ind < len) {
var testTerm = new RegExp(newClasses[ind] + ' ');
if (!testTerm.test(newClassName)) {
//current className doesn't contain class - add it
newClassName += newClasses[ind] + ' ';
}
ind++;
}
element.className = newClassName.trim();
},
removeClass: function(element, classesToRemove) {
//remove a class or multiple classes from an element
var newClass = element.className.trim().replace(/\s+/g,' ') + ' ';
var classes = classesToRemove.split(/\s+/);
var ind = classes.length;
while(ind--) {
//remove class
newClass = newClass.replace(classes[ind] + ' ','');
}
element.className = newClass.trim();
}
};
var showBox = function(box) {
baseFunc.addClass(box, "active-box");
};
var hideBox = function(box) {
baseFunc.removeClass(box, "active-box");
};
var showMessage = function(message, messageType) {
var messageBox = document.getElementById("message-box");
var messageLine = document.getElementById("message-line");
var messageIcon = document.getElementById("message-icon");
var messageText = document.getElementById("message-text");
var messageButton = document.getElementById("message-button");
messageText.innerHTML = message;
if (messageType === "error") {
messageBox.className = "box message-box error-message";
messageIcon.className = "error-icon";
messageIcon.innerHTML = "!";
} else if (messageType === "confirm" ) {
messageBox.className = "box message-box confirm-message";
messageIcon.className = "confirm-icon";
messageIcon.innerHTML = "i";
}
messageButton.onclick = function() {
hideBox(messageBox);
};
showBox(messageBox);
};
var animakuzBubbles = function() {
var btnGenerate = document.getElementById("btn-generate");
var btnShowOptions = document.getElementById("btn-show-options");
var btnHideOptions = document.getElementById("btn-hide-options");
var bubbles = [];
var createBubble = function(duration, delay, depth, size, pos) {
var bubble = document.createElement("div");
var baseLight = '<div class="soft-light base-light bubble-part"></div>';
var topLight = '<div class="mid-light top-light bubble-part"></div>';
var bottomLight = '<div class="mid-light bottom-light bubble-part"></div>';
var offLight1 = '<div class="hard-light off-light-1 bubble-part"></div>';
var offLight2 = '<div class="hard-light off-light-2 bubble-part"></div>';
//bubble properties
baseFunc.addClass(bubble, "bubble bubble-part");
bubble.style.width = size + "px";
bubble.style.height = size + "px";
bubble.style.top = "100%";
bubble.style.left = pos + "%";
bubble.style.opacity = depth / 100;
//inner parts
bubble.innerHTML = baseLight + topLight + bottomLight +
offLight1 + offLight2;
//animation
bubble.style.animationName = "bubbleRise";
bubble.style.animationDuration = duration + "s";
bubble.style.animationDelay = delay + "s";
bubble.style.animationIterationCount = "infinite";
return bubble;
};
var clearBubbles = function() {
//clear bubbles alredy present
var container = document.getElementById("bubble-container");
var len = bubbles.length;
while(len--) {
container.removeChild(bubbles[len]);
}
bubbles = [];
};
var generateBubbles = function(density) {
var container = document.getElementById("bubble-container");
var i;
//limits
var maxDuration = 10;
var minDuration = 5;
var maxDelay = 10;
var minDelay = 1;
var maxDepth = 10;
var minDepth = 100;
var maxSize = 100;
var minSize = 20;
var maxPos = 100;
var minPos = 1;
//bubble properties
var bubbleDuration;
var bubbleDelay;
var bubbleDepth;
var bubbleSize;
var bubblePos;
clearBubbles();
for (i=0; i<density; i++) {
bubbleDuration = baseFunc.getRandomInt(minDuration, maxDuration);
bubbleDelay = baseFunc.getRandomInt(minDelay, maxDelay);
bubbleDepth = baseFunc.getRandomInt(minDepth, maxDepth);
bubbleSize = baseFunc.getRandomInt(minSize, maxSize);
bubblePos = baseFunc.getRandomInt(minPos, maxPos);
bubbles.push(createBubble(bubbleDuration, bubbleDelay, bubbleDepth, bubbleSize, bubblePos));
container.appendChild(bubbles[i]);
}
};
btnGenerate.onclick = function() {
//generate button click
var txtBubbleDensity = document.getElementById("txt-bubble-density");
var density = txtBubbleDensity.value;
if (isNaN(density) || Number(density) <= 0) {
//show error
showMessage("Please enter a valid number!", "error");
} else {
//generate bubbles
generateBubbles(density);
}
};
btnShowOptions.onclick = function() {
//show options button click
var optionsBox = document.getElementById("options");
showBox(optionsBox);
btnShowOptions.style.display = "none";
};
btnHideOptions.onclick = function() {
//close button on options box
var optionsBox = document.getElementById("options");
hideBox(optionsBox);
btnShowOptions.style.display = "block";
};
generateBubbles(20);
};
animakuzBubbles();
This Pen doesn't use any external JavaScript resources.