Skip to content

Instantly share code, notes, and snippets.

@emmaly
Created November 5, 2023 05:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emmaly/602dbc773161ae277b81a3df76410d16 to your computer and use it in GitHub Desktop.
Save emmaly/602dbc773161ae277b81a3df76410d16 to your computer and use it in GitHub Desktop.
Glowy Floaty Balls
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Glowy Floaty Balls</title>
<style>
body {
background-color: #222;
/* Dark gray background */
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
height: 100%;
}
#floatingCircles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Define the glow effect using SVG filters */
svg {
filter: drop-shadow(0 0 8px);
}
</style>
</head>
<body>
<svg id="floatingCircles" width="100%" height="100%">
<defs>
<filter id="glow-effect">
<feGaussianBlur stdDeviation="2" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
</svg>
<script>
document.addEventListener('DOMContentLoaded', function () {
const svgNS = "http://www.w3.org/2000/svg";
const container = document.querySelector('#floatingCircles');
const width = window.innerWidth;
const height = window.innerHeight;
const circleCount = 99;
const animationVariations = Math.ceil(circleCount / 4);
// Function to generate random animation values
function randomAnimationValues() {
return {
translateY1: Math.random() * 20 - 10, // Range -10px to 10px
scale1: Math.random() * 0.1 + 0.95, // Range 0.95 to 1.05
translateY2: Math.random() * 20 - 10,
scale2: Math.random() * 0.1 + 0.95,
translateY3: Math.random() * 20 - 10,
scale3: Math.random() * 0.1 + 0.95
};
}
// Function to create keyframe animations
function createKeyframes(i, values) {
const keyframes = `
@keyframes combined-waver-drift-${i} {
0% { transform: translateX(0vw) translateY(0) scale(1); }
25% { transform: translateX(26vw) translateY(${values.translateY1}px) scale(${values.scale1}); }
50% { transform: translateX(52vw) translateY(${values.translateY2}px) scale(${values.scale2}); }
75% { transform: translateX(78vw) translateY(${values.translateY3}px) scale(${values.scale3}); }
100% { transform: translateX(105vw) translateY(0) scale(1); }
}
`;
return keyframes;
}
// Insert the generated keyframes into the head of the document
function insertKeyframes() {
const style = document.createElement('style');
document.head.appendChild(style);
const sheet = style.sheet;
for (let i = 1; i <= animationVariations; i++) {
const values = randomAnimationValues();
const keyframeString = createKeyframes(i, values);
sheet.insertRule(keyframeString, sheet.cssRules.length);
}
}
insertKeyframes();
// Function to create and animate circles with random animations
function createCircle(animationName) {
const circle = document.createElementNS(svgNS, 'circle');
const radius = Math.random() * 3;
const cy = Math.random() * (height - radius * 2) + radius;
const duration = Math.random() * 10 + 20;
const delay = -Math.random() * duration;
circle.setAttribute('r', radius);
circle.setAttribute('cx', -radius);
circle.setAttribute('cy', cy);
circle.style.fill = `hsla(${Math.random() * 360}, 50%, 50%, 0.9)`;
circle.style.filter = 'url(#glow-effect)';
circle.style.transformOrigin = 'center';
circle.style.animation = `${animationName} ${duration}s linear infinite ${delay}s`;
container.appendChild(circle);
}
// Create circles with random animations
for (let i = 0; i < circleCount; i++) {
createCircle(`combined-waver-drift-${(i % animationVariations) + 1}`);
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment