xxxxxxxxxx
272
/***************************
* CS 1004: Lab 2 *
* Prof. Smith *
* Last Updated: 1-19-2023 *
***************************/
//Variables in all caps are brush state variables
var VERTICAL_LINES = false;
var HORIZONTAL_LINES = false;
var FIREWORK = false;
var CIRCLES = false;
var TENPRINT = false;
var PATCHES = false;
var RAINBOW = false;
var TRANSPARENCY = false;
//Global variables necessary for the vertical and horizontal line brushes
vNoiseIncr = 0;
hNoiseIncr = 0;
//Code inside setup runs once at the beginning of the program
function setup() {
createCanvas(600, 600);
background(250);
angleMode(DEGREES);
}
//Code inside draw runs every frame
function draw() {
/*
Vertical lines and horizontal lines are allowed to be
drawn together; the others are not
Each brush draws noise-modified lines that span the
screen (V/H) at the mouse position
Uses the 2D noise function, scaled, and incrementing
the second dimension after each line for variety
*/
if (VERTICAL_LINES == true || HORIZONTAL_LINES == true) {
strokeWeight(1);
if (VERTICAL_LINES == true) {
for (var i = 0; i < height; i++) {
stroke(random(0, 20), random(0, 20), random(0, 20), 50);
point(mouseX + noise(i * 0.05, vNoiseIncr * 0.05) - 0.5, i);
}
vNoiseIncr += 1;
}
if (HORIZONTAL_LINES == true) {
for (var i = 0; i < width; i++) {
stroke(random(0, 20), random(0, 20), random(0, 20), 50);
point(i, mouseY + noise(hNoiseIncr * 0.05, i * 0.05) - 0.5);
}
hNoiseIncr += 1;
}
}
/*
PATCHES draws large, mostly transparent circles to the
screen to make a patchy/textured appearance
*/
else if (PATCHES == true) {
fill(random(150, 170), random(24, 57), random(150, 170), 10);
noStroke();
diameter = random(200, 400);
ellipse(random(width), random(height), diameter, diameter);
}
/*
TENPRINT is inspired by the classic BASIC maze-generation program,
it is modified to support drawing squares in addition to / and \
probability of each can be modified with with p_back and p_forward
*/
else if (TENPRINT == true) {
//control parameters - gridSize is # pixels wide each element is
//boxOffset controls size of box option
var gridSize = 20;
var boxOffset = 5;
//p_back: probability of a backslash
//p_forward: probability of a forward slash
// (if p_back + p_forward < 1, remainder is probability of a box)
var p_back = 0.5;
var p_forward = 0.5;
//create a background rectangle
fill(random(255), random(255), random(255), 20);
noStroke();
rect(0, 0, width, height);
noFill();
stroke(0, 20);
strokeWeight(3);
//now draw the 10PRINT maze
for (var i = 0; i < width; i += gridSize) {
for (var j = 0; j < height; j += gridSize) {
choice = random(1);
if (choice < p_back) {
line(i, j, i + 20, j + 20); //draw the \ line
} else if (choice < p_back + p_forward) {
line(i + 20, j, i, j + 20); //draw the / line
} else {
rect(
i + boxOffset,
j + boxOffset,
gridSize - boxOffset * 2,
gridSize - boxOffset * 2
); //draw a box
}
}
}
//turn this brush off immediately after complete the drawing
TENPRINT = false;
}
/*
FIREWORK uses polar coordinate conversion to draw
a mini sunburst/firework at the mouse position
*/
else if (FIREWORK == true) {
//random strokeweight gives some variety to the generated fireworks
strokeWeight(random(1, 3));
//base color that can then be modified slightly
//for the large and small radiating lines
var rf = random(20, 50);
var gf = random(20, 50);
var bf = random(20, 50);
for (var theta = 0; theta < 360; theta += 20) {
stroke(rf + random(-5, 5), gf + random(-5, 5), bf + random(-5, 5));
noFill();
//draw the large radiating lines
line(
mouseX + 5 * cos(theta),
mouseY + 5 * sin(theta),
mouseX + 25 * cos(theta),
mouseY + 25 * sin(theta)
);
stroke(rf + random(-5, 5), gf + random(-5, 5), bf + random(-5, 5));
//draw intermediate radiating lines at theta+10
line(
mouseX + 10 * cos(theta + 10),
mouseY + 10 * sin(theta + 10),
mouseX + 40 * cos(theta + 10),
mouseY + 40 * sin(theta + 10)
);
}
//after drawing a single firework, turn off the brush
FIREWORK = false;
}
/*
CIRCLES draws a trail of circles near the mouse
with some low probability on each frame
*/
else if (CIRCLES == true) {
strokeWeight(3);
fill(random(200, 255), random(200, 255), random(200, 255), 50);
stroke(random(0, 50), random(0, 50), random(0, 50), 50);
for (var diameter = 5; diameter < 20; diameter += int(random(5,10))) {
if (random(1) < 0.25) {
ellipse(mouseX + random(-20, 20), mouseY + random(-20, 20),
diameter, diameter);
}
}
}
/*
RAINBOW creates patchy rainbow blobs and
scatters them randomly across the screen
*/
else if (RAINBOW == true) {
noStroke();
rectMode(CENTER);
//startX, startY holds the center of each patchy blob
startX = random(0, width);
startY = random(0, height);
//randomly order the colors that we interpolate between
choice = random(1);
if (choice < 0.25) {
//purple, yellow, cyan
rainbowColor1 = color(random(200, 255), 0, random(200, 255), 10)
rainbowColor2 = color(random(200, 255), random(200, 255), 0, 10)
rainbowColor3 = color(0, random(200, 255), random(200, 255), 10)
}
else if (choice < 0.5) {
//cyan, yellow, purple
rainbowColor1 = color(0, random(200, 255), random(200, 255), 10)
rainbowColor2 = color(random(200, 255), random(200, 255), 0, 10)
rainbowColor3 = color(random(200, 255), 0, random(200, 255), 10)
}
else if (choice < 0.75) {
//purple, cyan, yellow
rainbowColor1 = color(random(200, 255), 0, random(200, 255), 10)
rainbowColor2 = color(0, random(200, 255), random(200, 255), 10)
rainbowColor3 = color(random(200, 255), random(200, 255), 0, 10)
}
else {
//yellow, purple, cyan
rainbowColor1 = color(random(200, 255), random(200, 255), 0, 10)
rainbowColor2 = color(random(200, 255), 0, random(200, 255), 10)
rainbowColor3 = color(0, random(200, 255), random(200, 255), 10)
}
secondColor = rainbowColor2
//each patchy blob is a bunch of transparent rectangles arranged,
//overlapping, in two concentric circles
for (var t = 0; t < 360; t += 20) {
//lerpColor is a function that takes two colors (first two params)
// and a number between 0 and 1 (t). It returns a color that is t% between
// the first and second color, using linear interpolation in RGB space
fill(lerpColor(rainbowColor1, rainbowColor2, t/360.0));
currX = startX + 30*cos(t);
currY = startY + 30*sin(t);
rect(currX, currY, 30, 30);
fill(lerpColor(rainbowColor2, rainbowColor3, t/360.0));
currX = startX + 70*cos(t);
currY = startY + 70*sin(t);
rect(currX, currY, 80, 80);
}
rectMode(CORNER);
}
/*
TRANSPARENCY overlays a transparent rectangle across the entire screen.
Useful when wanting to just lighten up what's there to make room for more!
*/
if (TRANSPARENCY == true) {
fill(255, 255, 255, 100);
noStroke();
rect(0, 0, width, height);
TRANSPARENCY = false;
}
}
function keyPressed() {
if (key == "v") {
VERTICAL_LINES = !VERTICAL_LINES;
vNoiseIncr += 1;
}
if (key == "h") {
HORIZONTAL_LINES = !HORIZONTAL_LINES;
hNoiseIncr += 1;
}
if (key == "f") {
FIREWORK = !FIREWORK;
}
if (key == 'c') {
CIRCLES = !CIRCLES;
}
if (key == "p") {
PATCHES = !PATCHES;
}
if (key == "1") {
TENPRINT = true;
}
if (key == 'w') {
RAINBOW = !RAINBOW;
}
if (key == 't') {
TRANSPARENCY = true;
}
if (key == "r") {
background(250);
}
if (key == "s") {
save("output.png");
}
}