let colorSet = [ '#001121', '#f7f8ff', '#8c44eb'];
backGroundCol : ["Dark", "Light"],
particleColMode : ["Velocity", "Position", "Black", "White"],
drawingMethod : ["Lines", "Rectangle", "Circle", "Point"],
particleDecayRateMin : 30,
particleDecayRateMax : 800,
particleSpawn : ["Side", "Center", "Cross", "Random"],
alphaSliderParticle : 200,
alphaSliderParticleMin : 0,
alphaSliderParticleMax : 255,
alphaSliderBackground : 20,
alphaSliderBackgroundMin : 0,
alphaSliderBackgroundMax : 255,
fieldType : ['PerlinNoise', 'Swirl', 'Wave1', 'Wave2', 'Wave3', 'Wave4'],
fieldDynamicsStep : 0.01,
fieldUpdateStep : 0.0001,
fieldStrenghStep : 0.001,
function createMetaTag() {
let meta = createElement('meta');
meta.attribute('name', 'viewport');
meta.attribute('content', 'user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width,height=device-height');
let head = select('head');
createCanvas(window.innerWidth, window.innerHeight);
colorB = color(colorSet[0]);
let boundary = new Rectangle(width / 2, height / 2, width, height);
qt = new QuadTree(boundary, forceControl.quadTreeCapacity);
field = new FlowField(20);
particles = new ParticleSystem(poolSize, drawControl.particleSize, 0, field, color(colorSet[0]), 100);
gui1 = createGui('Drawing Control');
gui1.addObject(drawControl);
gui1.setPosition(205, 100);
gui2 = createGui('Force Control');
gui2.addObject(forceControl);
gui2.setPosition(205*2, 100);
guiToggle = createGui('Toggle UI');
guiToggle.addObject(GUIToggle);
guiToggle.setPosition(0, 300);
if (!GUIToggle.ShowControllUI) {
if (drawControl.backGroundCol == "Dark") {
colorB = color(colorSet[0]);
} else if (drawControl.backGroundCol == "Light") {
colorB = color(colorSet[1]);
colorB.setAlpha(drawControl.alphaSliderBackground);
qt.capacity = forceControl.quadTreeCapacity;
particles.quadTreeInsert(qt);
if (drawControl.showQuadTree) qt.show();
particles.update(diffusion, drawControl);
particles.poolSizeControl();
particles.setPoolSize(drawControl.particleCount);
particles.setHealth(drawControl.particleDecayRate);
if (forceControl.fieldToggle) {
field.update(forceControl.fieldUpdate);
field.setDyn(forceControl.fieldDynamics);
field.setMags(forceControl.fieldStrengh);
if (drawControl.clearCanvas == true) {
if (drawControl.frameRateToggle) showFrameRate();
if (instruction) introduction();
function introduction() {
let cx = width / 2 - 300;
let cy = height / 2 - 20;
let title = "Particle Canvas"
let instructions = "Press P to pause, S to save, R to switch color, ArrowKey for wind"
let haveFun = "Combine different settings to create your own painting!!"
let pressToContinue = "Press anywhere to continue"
text(instructions, cx, cy + gap);
text(haveFun, cx, cy + gap*2);
text(pressToContinue, cx, cy + gap*3);
if (paused == true) noLoop();
if (key === 'r') particles.randomizeCol();
function mousePressed() {
function showFrameRate() {
text("FPS: " + fps.toFixed(0), 10, height - 10);