Svg Grids

by sosegon

HTML

<div id='container'>

</div>

JavaScript

import { SvJs, Gen } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"

// Parent SVG.
const svg = new SvJs().addTo(document.getElementById("container"))

// Viewport and viewBox (1:1 aspect ratio).
const viewBoxSize = 1000
const svgSize = Math.min(window.innerWidth, window.innerHeight)
svg.set({
  width: svgSize,
  height: svgSize,
  viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`,
})

// Background.
svg.create("rect").set({
  x: 0,
  y: 0,
  width: 1000,
  height: 1000,
  fill: "#181818",
})

let grid = svg.create("g")
let gridSize = Gen.random(400, 800)
let rows = Gen.random(5, 10)
let spacing = Gen.random(5, 10)

let increment = gridSize / rows
let cellSize = Math.abs(increment - spacing)

let palettes = [
  ["#5465FF", "#788BFF", "#9BB1FF", "#BFD7FF", "#E2FDFF"],
  ["#22577A", "#38A3A5", "#57CC99", "#80ED99", "#C7f9CC"],
  ["#4C5760", "#93A8AC", "#D7CEB2", "#A59E8C", "#66635B"],
]

let pickedPalette = Gen.random(palettes)
let hue = Gen.random(0, 360)

for (let y = 0; y < gridSize; y += increment) {
	hue = (hue >= 360) ? (hue - 360) + (120 / rows) : hue + (120 / rows);
  for (let x = 0; x < gridSize; x += increment) {
    let clip = grid.create("clipPath").set({ id: `${x}-${y}` })
    clip.create("rect").set({
      x,
      y,
      width: cellSize,
      height: cellSize,
    })
    let cx = Gen.random([x, x + increment])
    let cy = Gen.random([y, y + increment])

    if (Gen.chance(20)) {
      for (let r = pickedPalette.length; r > 0; r -= 1) {
        grid.create("circle").set({
          cx,
          cy,
          r: r * (cellSize / pickedPalette.length),
          fill: pickedPalette[r - 1],
          clip_path: `url(#${x}-${y})`,
        })
      }
    } else {
      for (let i = 0; i < cellSize; i++) {
        grid.create("line").set({
          x1: Gen.random(x, x + cellSize),
          y1: Gen.random(y, y + cellSize),
          x2: Gen.random(x, x + cellSize),
          y2: Gen.random(y, y + cellSize),
          stroke: `hsl(${hue} 80% 80% /...