xxxxxxxxxx
263
//thanks to coding train (dan schiffman), steve's makerspace, turing code, and colorful coding on youtube for resources/code snippets in this p5.js sketch
//how fast the mandala changes
var rate = 0.3;
//how fast the color changes
var layerColorDelta = 1.2;
//the range of colors
var colorRange = 180;
//the number of colors available to choose from
var numColors = 5; //for chromatic
//introducing randomness into the mandala
var randomEventChance = 0.4;
//arrays to keep mandala variables
var oldMandala = [];
var newMandala = [];
//keeping mandala parameters
var layerColor;
var angle;
var currentLayerRadius;
//creates the segments within the mandala and establishes layer properties
var segmentCount;
var layer;
var layerColorInitial;
var layerColorMax;
//variables for all points + coordinates in the mandalas
var deltaX1, deltaX2, deltaY2, deltaX3, deltaY3, deltaX4;
var innerLayerControlX1, innerLayerControlX2, innerLayerControlY2, outerLayerControlX3, outerLayerControlY3, outerLayerControlX4;
var maxValY2;
var maxValY3;
//variables for saturation, brightness, and alpha level of mandalas
var satLevel = 105;
var brightnessLevel = 50;
var alphaLevel = 40;
//variables for audio
var song, fft; //song values
var mid, treble; //mid values
//load in the audio
function preload(){
song = loadSound('bairagi-final-1.mp3');
}
function setup() {
//setting the frame rate. a lower frame rate makes the mandala slow down
frameRate(20);
var maxSize = min(windowWidth, windowHeight);
//setting the canvas size
createCanvas(maxSize, maxSize);
//using degrees and hue saturation brightness alpha for the color type
angleMode(DEGREES);
colorMode(HSB, 360, 100, 100, 100);
//playing the song
song.play();
//initializing the audio variables
amp = new p5.Amplitude();
fft = new p5.FFT();
//calling the generate mandala function here
generateMandala();
}
//function to generate the mandala
function generateMandala(vol) {
//clear background and make it black
background(0);
oldMandala = []; //reset oldMandala array
//set variables for generating the mandala
segmentCount = random(8, 25); //number of parts the mandala has
layer = random(4, 30); //number of layers the mandala has
angle = 360 / segmentCount; //angle at which the segments need to be at
//initializing first layer colors, a max layer color, and current color to keep track
layerColorInitial = 150;
layerColorMax = layerColorInitial + colorRange;
var currentColor = 0;
//loop to generate all the layers of the mandalas
for (var j = layer; j > 0; j--) {
currentLayerRadius = (j / layer) * (width / 2);
innerLayerControlX1 = random(0.35 * currentLayerRadius, 0.45 * currentLayerRadius);
innerLayerControlX2 = random(0.5 * currentLayerRadius, 0.7 * currentLayerRadius);
maxValY2 = innerLayerControlX2 * tan(angle) * 0.9;
innerLayerControlY2 = random(0.05 * currentLayerRadius, maxValY2);
outerLayerControlX3 = random(innerLayerControlX2 * 1.2, 0.8 * currentLayerRadius);
maxValY3 = outerLayerControlX3 * tan(angle) * 0.9;
outerLayerControlY3 = random(0.05 * currentLayerRadius, maxValY3);
outerLayerControlX4 = random(0.85 * currentLayerRadius, 0.95 * currentLayerRadius);
deltaX1 = deltaX2 = deltaY2 = deltaX3 = deltaY3 = deltaX4 = (rate / layer) * j;
//calculate the layer color
layerColor = layerColorInitial + (currentColor * colorRange) / numColors;
//wrap the layer color if it goes out of the hue range
if (layerColor > 360) {
layerColor -= 360;
}
currentColor++;
//reset the color index if it goes over the number of allotted colors
if (currentColor > numColors) {
currentColor = 0;
}
//push all the layer info to the old mandala array
oldMandala.push(innerLayerControlX1, innerLayerControlX2, innerLayerControlY2, outerLayerControlX3, outerLayerControlY3, outerLayerControlX4, deltaX1, deltaX2, deltaY2, deltaX3, deltaY3, deltaX4, layerColor, layerColorDelta
);
}
}
function draw() {
//analyzes the audio and get the mid frequencies
fft.analyze();
mid = fft.getEnergy("mid");
//print(mid)
randommid = random(2, 60);
newmid = mid + randommid
if(newmid > 255){mid-=255}
var vol = amp.getLevel();
mid4alpha = map(newmid, 0, 70, 0, 250);
newVol = map(vol, 0, 1, 10, 250);
alphaLevel = newVol; //originally 100, then newVol
brightnessLevel = newVol;
satLevel = mid4alpha;
newMandala = [];
push();
translate(width / 2, height / 2);
for(var k = layer; k > 0; k--) {
var layerIndex = (layer - k) * 14;
var x1NewVal = oldMandala[layerIndex + 0];
var x2NewVal = oldMandala[layerIndex + 1];
var y2NewVal = oldMandala[layerIndex + 2];
var x3NewVal = oldMandala[layerIndex + 3];
var y3NewVal = oldMandala[layerIndex + 4];
var x4NewVal = oldMandala[layerIndex + 5];
var x1DeltaNewVal = oldMandala[layerIndex + 6];
var x2DeltaNewVal = oldMandala[layerIndex + 7];
var y2DeltaNewVal = oldMandala[layerIndex + 8];
var x3DeltaNewVal = oldMandala[layerIndex + 9];
var y3DeltaNewVal = oldMandala[layerIndex + 10];
var x4DeltaNewVal = oldMandala[layerIndex + 11];
var layerColorN = oldMandala[layerIndex + 12];
var layerColorNDelta = oldMandala[layerIndex + 13];
currentLayerRadius = (k / layer) * (width / 2);
var randomEventChance = 0.1;
var randomEvent = random(10) < randomEventChance;
//all this code below (the next few if statements) updates the positions of the points that control the segments of the mandala
//basically i am reversing the direction of change if certain contisions are met,
x1NewVal += x1DeltaNewVal;
if (x1NewVal < 0.35 * currentLayerRadius || x1NewVal > 0.45 * currentLayerRadius || randomEvent) {
x1DeltaNewVal *= -1;
}
x2NewVal += x2DeltaNewVal;
if (x2NewVal < 0.5 * currentLayerRadius || x2NewVal > 0.7 * currentLayerRadius || randomEvent) {
x2DeltaNewVal *= -1;
}
//making sure mandala segment count values don't go out of bounds and have visual balance
maxValY2 = x2NewVal * cos(angle) * 0.9;
y2NewVal += y2DeltaNewVal;
if (y2NewVal < 0.05 * currentLayerRadius || y2NewVal > maxValY2 || randomEvent) {
y2DeltaNewVal *= -1;
}
x3NewVal += x3DeltaNewVal;
if (x3NewVal < x2NewVal * 1.1 || x3NewVal > 0.85 * currentLayerRadius || randomEvent) {
x3DeltaNewVal *= -1;
}
//making sure mandala segment count values don't go out of bounds and have visual balance
maxValY3 = x3NewVal * tan(angle) * 0.9;
y3NewVal += y3DeltaNewVal;
if (y3NewVal < 0.05 * currentLayerRadius || y3NewVal > maxValY3 || randomEvent) {
y3DeltaNewVal *= -1;
}
x4NewVal += x4DeltaNewVal;
if (x4NewVal < 0.85 * currentLayerRadius || x4NewVal > 0.95 * currentLayerRadius || randomEvent) {
x4DeltaNewVal *= -1;
}
//this if statement checks the layer color after i added the delta change to it, and if it goes out of bounds it reverses the direction of change for the delta
layerColorN += layerColorNDelta;
if (layerColorN > 360 || layerColorN > layerColorMax || layerColorN < 0 || layerColorN < layerColorInitial || randomEvent) {
layerColorNDelta *= -1;
}
//get the values for mandala shape
noFill();
strokeWeight(1);
stroke(layerColorN, satLevel, brightnessLevel, alphaLevel);
//add in the new mandala values
newMandala.push(x1NewVal, x2NewVal, y2NewVal, x3NewVal, y3NewVal, x4NewVal, x1DeltaNewVal, x2DeltaNewVal, y2DeltaNewVal, x3DeltaNewVal, y3DeltaNewVal, x4DeltaNewVal, layerColorN, layerColorNDelta);
//draw the mandala shape
for(var i = 0; i < segmentCount; i++){
beginShape();
curveVertex(x4NewVal, 0);
curveVertex(x4NewVal, 0);
curveVertex(x3NewVal, y3NewVal);
curveVertex(x2NewVal, y2NewVal);
curveVertex(x1NewVal, 0);
curveVertex(x2NewVal, -y2NewVal);
curveVertex(x3NewVal, -y3NewVal);
curveVertex(x4NewVal, 0);
curveVertex(x4NewVal, 0);
endShape();
rotate(angle);
}
rotate(angle/2);
}
//set the new old mandala equal to the new mandala so it has all the newer properties for next loop
pop();
oldMandala = newMandala;
}