art
generative
fxhash
Ephemeral Whirls – Generative Art through Loops and Motion

Ephemeral Whirls – Generative Art through Loops and Motion

written by reyrove

07 Oct 2024100 EDITIONS
1 TEZ

The Initial Setup: Creating the Canvas

const e = Math.min(innerWidth, innerHeight);
const canvas = {};
canvas.w = e;
canvas.h = e;

Features and Global Variables

const features = {};
var loopers;
var backgroundColor;

The Setup Function: Laying the Groundwork

function setup() {
  createCanvas(e, e);

Choosing Colors: Palette of Pastels and Vibrancy

const backgroundColours =  ['#F5F5F5','#9AFEFF','#AAF0D1', ...];
const backgroundNames = ['WhiteSmoke (W3C)','Electric Blue','Magic Mint', ...];
const backgroundIndex = Math.floor($fx.rand() * backgroundColours.length);
features.backgroundColour = backgroundColours[backgroundIndex];
const LooperColor = [['#9F21DE','#60DE21'], ['#F20DB2','#0DF24D'], ...];
features.LooperColors = LooperColor[Math.floor($fx.rand() * LooperColor.length)];

Building the Loopers: Our Dancing Shapes

features.NumberOfLoopers = Math.floor($fx.rand() * 2 + 23);
features.Time = Math.floor($fx.rand() * 2000 + 2000);
loopers = [];
for (let i = 0; i < features.NumberOfLoopers; i++) {
  loopers.push(new Looper(0, $fx.rand() * e));
}

Drawing the Scene: Orienting and Setting the Stage

if (features.side == 0) {
  rotate(Math.PI / 2);
  translate(0, -e);
} else if (features.side == 1) {
  rotate(-Math.PI / 2);
  translate(-e, 0);
}
background(features.backgroundColour);
strokeWeight(e / ($fx.rand() * 200 + 200));

The Magic of Motion: Loopers Take Their Step

for (let i = 0; i < features.Time; i++) {
  drawOnce();
}
for (const looper of loopers) {
  looper.step();
  looper.draw1();
}

The Looper Class: The Heart of Motion

class Looper {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.heading = 0.1;
    this.speed = $fx.rand() * (e / 1000);
    this.sinOffset = $fx.rand() * 1000;
    this.loopingSpeed = $fx.rand() * (0.025, 0.1) * ($fx.rand() < 0.5 ? 1 : -1);
  }
step() {
  if (this.looping) {
    this.heading += this.loopingSpeed + sin(this.sinOffset + 100 * 0.1) * 0.05;
    this.constrainHeading();
    if (this.maybeDoneLooping && (this.heading < TAU * 0.05 || this.heading > TAU * 0.95)) {
      this.looping = false;
    }
  }
draw1() {
  stroke(this.c);
  line(this.prevX, this.prevY, this.x, this.y);
}

Saving the Canvas: A Moment Captured

function keyPressed() {
  if (key === 's' || key === 'S') {
    saveCanvas('Ephemeral Whirls', 'png');
  }
}

Conclusion

The "Ephemeral Whirls" project is more than just code—it’s a symphony of motion and color, where each looper dances across the screen, leaving behind trails of beauty. The randomness ensures that every execution generates a new, unique work of art, just like the natural unpredictability of life itself. This generative piece celebrates the interplay between control and chaos, inviting you to watch, play, and create in the digital world.

Click here for the full code, and let the art flow. Let’s explore these ephemeral whirls together and share our creations with the world!

*With all our creativity, love, and the code that brings this art to life,*🌸💻

_Frostbond Coders

stay ahead with our newsletter

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

feedback