<section class="section">
<svg class="svg"></svg>
<div class="block">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Accusamus cum maxime recusandae. Porro repellendus illum nam deserunt at magni, ad quae sint molestiae voluptas fuga aperiam odit esse labore consectetur!</div>
</section>
* {
box-sizing: border-box;
}
body {
margin: 0;
background:
linear-gradient(to right, #0001 1px, transparent 1px) 0 0 / 8px 8px,
linear-gradient(to bottom, #0001 1px, transparent 1px) 0 0 / 8px 8px;
}
.section {
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
height: 100vh;
min-height: 500px;
}
.svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.svg circle {
fill: gray;
fill-opacity: 0.5;
}
.block {
width: 50%;
max-width: 250px;
margin-left: 50px;
padding: 15px;
background-color: #0f07;
}
const lerp = (v0, v1, t) => v0 * (1 - t) + v1 * t;
const SVG_NS = "http://www.w3.org/2000/svg";
const svg = document.querySelector(".svg");
const block = document.querySelector(".block");
const blockRect = block.getBoundingClientRect();
const shiftCoef = 0.75;
const cellWidth = 48;
const cellHeight = 48;
const radius = 12;
function isIntersectRects(r1, r2) {
return !(
r2.x > r1.x + r1.width ||
r2.x + r2.width < r1.x ||
r2.y > r1.y + r1.height ||
r2.y + r2.height < r1.y
);
}
function createSubdivRange(fromTo, size) {
const { from = 0, to } = fromTo;
const step = (to - from) / Math.round((to - from) / size);
const out = [];
for (let position = from; position <= to; position += step) {
out.push({ position, size: step });
}
return out;
}
const cols = createSubdivRange({ from: 0, to: svg.clientWidth }, cellWidth);
const rows = createSubdivRange({ from: 0, to: svg.clientHeight }, cellHeight);
for (let ci = 0; ci < cols.length; ci++) {
for (let ri = 0; ri < rows.length; ri++) {
const { position: x, size: width } = cols[ci];
const { position: y, size: height } = rows[ri];
const dx = (width / 2 - radius) * shiftCoef;
const dy = (height / 2 - radius) * shiftCoef;
const cx = x + width / 2 + lerp(-dx, dx, Math.random());
const cy = y + height / 2 + lerp(-dy, dy, Math.random());
const isIntersects = isIntersectRects(blockRect, {
x: cx - radius,
y: cy - radius,
width: radius * 2,
height: radius * 2
});
if (!isIntersects) {
const circle = document.createElementNS(SVG_NS, "circle");
circle.setAttributeNS(null, "cx", cx);
circle.setAttributeNS(null, "cy", cy);
circle.setAttributeNS(null, "r", radius);
svg.appendChild(circle);
}
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.