art
generative
fxhash
Citrus Mosaic

Citrus Mosaic

written by reyrove

06 Oct 2024100 EDITIONS
1 TEZ

Let's break down the code line by line to explore how this beautiful chaos comes to life.

Setting Up Key Variables

const ratio = 1 / 1;
const prefix = 'Citrus Mosaic';

const features = {};
let resizeTmr = null;
let thumbnailTaken = false;

Handling URL Parameters and Animation

const urlSearchParams = new URLSearchParams(window.location.search);
const urlParams = Object.fromEntries(urlSearchParams.entries());
let forceDownloaded = false;

const animated = false;
let nextFrame = null;

setup Function

This function is where the magic begins. We define colors, calculate divisions for the pattern, and set up features.

const setup = () => {
  const readableFeaturesObj = {};

  const ForegroundColours = ['#F5F5F5', '#98AFC7', '#728FCE', '#1E90FF', '#95B9C7', '#3BB9FF', '#C2DFFF'];
  const ForegroundNames = ['WhiteSmoke (W3C)', 'Blue Gray', 'Light Purple Blue', 'DodgerBlue', 'Baby Blue', 'Midday Blue', 'Sea Blue'];
  const ForegroundIndex = Math.floor($fx.rand() * ForegroundColours.length);

  features.ForegroundColour = ForegroundColours[ForegroundIndex];
  readableFeaturesObj['Foreground Color'] = ForegroundNames[ForegroundIndex];

Next, we define the number of divisions in the pattern and randomly select square colors:

features.numofDivision = Math.floor($fx.rand() * 13) + 2;
features.numofSquares = features.numofDivision ** 2;

const Colors = [];
for (i = 0; i < features.numofSquares; i++) {
  Colors[i] = Squarecolors[Math.floor($fx.rand() * Squarecolors.length)];
}
features.SquareColor = Colors;

readableFeaturesObj['Number of Squares'] = features.numofSquares;
$fx.features(readableFeaturesObj);

Creating the Repeating Pattern

The function createRepeatingArcPattern is responsible for the intricate arc patterns in each square.

function createRepeatingArcPattern(ctx, X, Y, W, H, fillColor, arcfill) {
  // Set up canvas context and position
  ctx.translate(X, Y);
  ctx.fillStyle = fillColor;
  ctx.fillRect(0, 0, W, H);

  const A = Math.floor($fx.rand() * 22);
  if (A == 0) {
    ctx.beginPath();
    ctx.arc(0, 0, W, 0, 0.5 * Math.PI);
    ctx.lineTo(0, 0);
  }
  // ... additional pattern drawing logic ...
  ctx.shadowColor = arcfill;
  ctx.shadowBlur = W / 2;
  ctx.strokeStyle = arcfill;
  ctx.stroke();
  ctx.fillStyle = arcfill;
  ctx.fill();
}

Drawing the Canvas

The drawCanvas function stitches everything together.

const drawCanvas = async () => {
  window.cancelAnimationFrame(nextFrame);
  
  const canvas = document.getElementById('target');
  const ctx = canvas.getContext('2d');
  const w = canvas.width;
  const h = canvas.height;

  ctx.fillStyle = 'black';
  ctx.fillRect(0, 0, w, h);

  const numCols = features.numofDivision;
  const numRows = features.numofDivision;

  for (let row = 0; row < numRows; row++) {
    for (let col = 0; col < numCols; col++) {
      createRepeatingArcPattern(ctx, col * (w / numCols), row * (h / numCols), w / numCols, h / numCols, features.SquareColor[j], features.ForegroundColour);
    }
  }

Resizing and Downloading

Finally, we have helper functions to handle resizing and saving the canvas as an image.

const autoDownloadCanvas = async () => {
  const canvas = document.getElementById('target');
  const element = document.createElement('a');
  const filename = `${prefix}_${$fx.hash}`;
  element.setAttribute('download', filename);

  const imageBlob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
  element.setAttribute('href', window.URL.createObjectURL(imageBlob));

  element.click();
  document.body.removeChild(element);
};

autoDownloadCanvas: Downloads the canvas as a PNG file using the randomly generated $fx.hash for the filename.

With this code, you can explore the beauty of randomness and geometry in digital art. Each refresh of the page brings a new mosaic to life, featuring an eclectic mix of colors, shapes, and arcs. A delightful experiment in generative art! for full code, click HERE!

With love, sass, and digital flair by Frostbond Coders✨

stay ahead with our newsletter

receive news on exclusive drops, releases, product updates, and more

feedback