I decided to play a bit with p5.js. I haven’t been using processing or p5.js for some time, and so I decided to do something simple, with random outlined polygons moving and leaving a trace!
Try to see what happens when the polygons have 0 sides (if that makes sense) and the outline bigger by playing with the two buttons above!
And here’s the (not so polished) code for the sketch above:
/* DEPENDENCIES
//
// - https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js
// - https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js
// - https://www.dariomazzanti.com/js/RandomColorPaletteGeneration.js
*/
// we will use this to store a nice color palette
var palette;
var maxColNum = 50;
// we will store here the colors to generate our palette
var col_1, col_2, col_3;
// color of the background
var bgColor;
// how many polygons would you like?
var howMany = 30;
// storing polygons here
var polygons =[];
// fun mode
var noSidesPoly = false;
function setup()
{
// "polysketch" is the ID of the div containing this script
// we get a reference to it in order to know its current width and height
const elt = select("#polysketch");
w = elt.width;
h = elt.height;
// we now create our canvas for p5js, and parent it to the specified element (our "polysketch" div)
canvas = createCanvas(w, h);
canvas.parent('polysketch');
canvas.position(0,0);
// we use this value to generate objects which fit within the canvas
var elementsScaler = min(width, height);
// oh yes
smooth();
// we are not going to fill the shapes, we just draw their outline
noFill();
// setting the outline thickness, based on canvas proportions
// we want a thicker outline for our noSidesPoly mode :)
if(noSidesPoly)
strokeWeight(elementsScaler/100);
else
strokeWeight(elementsScaler/400);
// setting up some colors
bgColor = color(0, 8);
col_1 = color(30, 67, 130);
col_2 = color(0, 255, 51);
col_3 = color(51, 78, 210);
// and generating our palette!
GeneratePalette();
// instantiating the polygons
if(noSidesPoly)
{
// no polygons! check the third argument, it's 0!
for(var i = 0; i < 100; i++)
polygons[i] = new AnimPoly(random(width), random(height), 0, random(elementsScaler/15, elementsScaler/3), color(palette[int(random(maxColNum))]));
}
else
{
// random number of polygons! Check the third argument: it will return a float - I suppose that's why we have also non-regular polygons ;)
for(var j = 0; j < howMany; j++)
polygons[j] = new AnimPoly(random(width), random(height), random(1,7), random(elementsScaler/15, elementsScaler/3), color(palette[int(random(maxColNum))]));
}
background(bgColor);
fill(bgColor);
rect(0,0,width,height);
}
// calling this we can set the mode while the sketch is running
function noSidesPolysMode(_enable)
{
noSidesPoly = _enable;
setup();
}
// in case the window is resized
function windowResized()
{
const elt = select("#polysketch");
w = elt.width;
h = elt.height;
if(w > displayWidth)
w = displayWidth;
if(h > displayHeight)
h = displayHeight;
resizeCanvas(w, h);
setup();
}
function draw()
{
// no background, just a rectangle using a transparent color, so that shapes leave a trail
fill(bgColor);
rect(0,0,width,height);
// update of animating values and then drawing each shape
for(var i = 0; i < howMany; i++)
{
polygons[i].animate(0.01, 0.001);
polygons[i].draw();
}
}
// our polygons!
class AnimPoly
{
constructor(_x, _y, _n, _scale, _col)
{
this.posX = _x;
this.posY = _y;
this.speedX = random(-0.1, 0.1);
this.speedY = random(-0.1, 0.1);
this.nSides = _n;
this.rotAngle = 0.0;
this.col = _col;
this.dim = _scale;
this.startDim = this.dim;
this.dimMult = 1.0;
this.thickness = 5;
this.timeOffset = random(1000);
this.pulseSpeed = random(0.01, 0.02);
this.rotSpeed = random(0.001, 0.003);
this.polyAngle = TWO_PI / this.nSides;
}
draw()
{
push();
translate(this.posX, this.posY);
rotate(this.rotAngle);
stroke(this.col);
beginShape();
for (var a = 0; a < TWO_PI; a += this.polyAngle)
{
var sx = cos(a) * this.dim;
var sy = sin(a) * this.dim;
vertex(sx, sy);
}
endShape(CLOSE);
pop();
}
// updating current rotation angle
rotate()
{
this.rotAngle = sin(this.rotSpeed*25*(frameCount + this.timeOffset));
}
// scaling the shape over time
pulsate()
{
this.dimMult = sin(this.pulseSpeed*(frameCount + this.timeOffset));
this.dim = (this.dimMult *this.startDim + this.startDim)*0.5;
if(this.dim <=1)
{
this.posX = random(width);
this.posY = random(height);
this.speedX = random(-0.1, 0.1);
this.speedY = random(-0.1, 0.1);
this.col = color(palette[int(random(maxColNum))]);
}
}
// moving around randomly
move()
{
this.posX += this.speedX*deltaTime;
this.posY += this.speedY*deltaTime;
}
// calling some functions...
animate()
{
this.rotate();
this.pulsate();
this.move();
}
}
// this one calls a palette generator from our RandomColorPaletteGeneration "api"
function GeneratePalette()
{
var colorsNum = maxColNum;
var greyControlValue = 0.9;
palette = new Array(colorsNum);
palette = RandomMixPalette(
col_1,
col_2,
col_3,
greyControlValue,
colorsNum
);
}
An interesting thing to notice is that polygons are not always regular! This specific feature is given by this part of code:
polygons[j] = new AnimPoly(random(width), random(height),
random(1,7),
random(proport/15, proport/3), color(palette[int(random(maxColNum))]));
The third parameter of the AnimPoly constructor is the number of sides of the polygon. You would expect an integer value for that, but here we are passing a random value between 1 and 7!