JSFiddle - React, Tailwind, and code Playground
by justinwinter
HTML
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Animated Bubbles</title>
<link rel="stylesheet" href="movingbubbles.css" type="text/css" />
<style>
/* Start slider CSS */
#sliderContainer {
position:absolute;
top:20px;
right:20px;
background-color:#fff;
background-image:linear-gradient(to bottom, #fff, #eee);
border-radius:5px;
padding:10px;
box-shadow:0 5px 5px rgba(0, 0, 0, .2);
text-shadow:0 1px #fff;
opacity:0.2;
transition:opacity linear 0.25s;
font-family:Arial, sans-serif;
}
#sliderContainer:hover {
opacity:1;
}
#sliderContainer h3 {
margin:0;
text-align:center;
}
#sliderContainer strong {
width:115px;
display:inline-block;
}
#sliderContainer input {
width:200px;
margin:0;
}
#sliderContainer span {
padding:5px 0;
width:5%;
}
#sliderContainer hr {
background:#999;
box-shadow:0 1px #fff;
border:0;
height:1px;
}
/* End slider CSS */
</style>
<script src="movingbubbles.js" type="text/javascript"></script>
<script type="text/javascript">
/**
* A function for the settings sliders to properly update bubbleOptions
* @this {Window}
* @param {[object HTMLInputElement]} slider The slider element
* @param {String} bubbleSetting The variable name of bubbleOptions that the slider modifies
*/
function sliderUpdate(slider, bubbleSetting) {
var value = parseFloat(slider.value);
//Special cases
//The bubble-pixel ratio requires changing the number of bubbles
//And if the bubble cap is lower than the number of bubbles,
//then the bubbles also need to be changed
if(bubbleSetting == 'ratio' ||
(bubbleSetting == 'maxBubbles' && bubbleOptions.bubbles.length > value)) {
var bubbleContainer =...
CSS
/*
* CSS for the moving bubbles
* Makes sure the bubble container appears behind the contents of the page
* Gerard Godone-Maresca
*/
html, body {
padding:0;
margin:0;
min-height:100%;
background-color:#50afe4;
background-image:linear-gradient(to bottom,#57B7E0,#3C799D);
background-attachment:fixed;
}
html * { z-index: 1; position:relative; }
#bubbleContainer {
z-index:0;
overflow:hidden;
position:fixed;
height:100%;
width:100%;
}
#bubbleContainer div {
position:fixed;
z-index:-1;
border-radius:1000px;
}
JavaScript
/**
* Creates an animated bubble background
* @author Gerard Godone-Maresca
*/
/*
* An object that stores different settings for the bubbles
*/
var bubbleOptions = {
maxBubbles : 250, //A bubble ceiling, for high resolution monitors
timer : -1, //The interval time
tick : 100, //The tick speed
bubbles : [], //The array of bubbles
hue : 188, //The hue
hueRand : 20, //The hue variance
saturation : 63, //The saturation
saturationRand : 10, //The saturation variance
light : 57, //The lightness
lightRand : 10, //The lightness variance
opacityFactor : 3, //What Math.random() opacity should be divided by
minOpacity : 0.1, //The minimum opacity
ratio : 45000, //The bubble:pixel ratio
update : function(tick) { //Function to change the tick timer
//Since IE8 and below don't support HSLA colors,
//do nothing for these browsers
if(!document.addEventListener) return;
window.clearInterval(this.timer);
if(!tick) tick = this.tick;
if(!this.bubbles.length) this.bubbles = instantiateBubbles();
var bubbles = this.bubbles;
this.timer = window.setInterval(
function() {
for(var i = 0; i < bubbles.length; i++)
bubbles[i].move();
},
tick
);
}
};
//Instantiate the bubble on page load
if(window.onload) {
windowOnLoad = window.onload;
window.onload = function() {
windowOnLoad();
bubbleOptions.update();
}
} else window.onload = function() { bubbleOptions.update(); };
/**
* instantiateBubbles creates the array of bubble objects, and adds them to <body>
* @returns {Array} An array of bubbles
*/
function instantiateBubbles() {
//The bubbles need a container element
var bubbleContainer = document.getElementById("bubbleContainer");
if(!bubbleContainer) {
bubbleContainer = document.createElement('div');
bubbleContainer.setAttribute('id',...