JSFiddle - React, Tailwind, and code Playground
by sosegon
HTML
<div id='container'>
</div>
JavaScript
import { SvJs, Gen, Noise } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"
const svg = new SvJs().addTo(document.getElementById("container"))
const svgSize = Math.min(window.innerHeight, window.innerWidth)
svg.set({
x: 0,
y: 0,
width: svgSize,
height: svgSize,
viewBox: "0 0 1000 1000",
})
svg.create("rect").set({
x: 0,
y: 0,
width: 1000,
height: 1000,
fill: "#000",
})
const frameSize = Gen.random(500, 700)
const frame = svg.create("rect").set({
id: "frame",
x: (1000 - frameSize) / 2,
y: (1000 - frameSize) / 2,
width: frameSize,
height: frameSize,
fill: "#abcdef",
stroke: "#12121288",
stroke_width: frameSize / 10,
})
const numCircles = Math.floor(frameSize / 20)
const circles = []
for (let i = 0; i < numCircles; i++) {
let radius = Gen.random(frameSize / 100, frameSize / 25)
let velocityX = Gen.random(0.1, 5, true)
let velocityY = Gen.random(0.1, 5, true)
let circle = svg.create("circle").set({
cx: 500,
cy: 500,
r: radius,
vx: Gen.chance() ? velocityX : -velocityX,
vy: Gen.chance() ? velocityY : -velocityY,
fill: `hsl(${Gen.random(0, 360)} 80% 80% / .8)`,
})
circles.push(circle)
}
let frameEdge = Number(frame.get('x'));
let frameInset = Number(frame.get('stroke-width')) / 2;
function animate(time) {
if (time === undefined) time = 0
for (let i = 0; i < numCircles; i++) {
let radius = Number(circles[i].get('r'));
let lowerBound = frameEdge + radius + frameInset;
let upperBound = frameEdge + frameSize - radius - frameInset;
let vx = Number(circles[i].get("vx"))
let vy = Number(circles[i].get("vy"))
let cx = Number(circles[i].get("cx"))
let cy = Number(circles[i].get("cy"))
if (cx <= lowerBound || cx >= upperBound) {
vx = -vx
}
if (cy <= lowerBound || cy >= upperBound) {
vy = -vy
}
cx += vx
cy += vy
circles[i].set({ cx, cy, vx, vy })
}
requestAnimationFrame(animate)
}
animate(0)