This project begins with a small circle that gradually expands over time while continuously cycling through various colors. The circle is interactive, precisely following the movement of the mouse cursor. Its color is set to a random hue determined at the exact moment mouse cursor is moved. When the mouse button is pressed and held, the circle will slowly shrink. Upon releasing the mouse button, the circle will resume its gradual expansion.
When the mouse is pressed, a dotted, circular path is generated, originating from the location of the click. This path remains on the screen until the user clicks in a new location, which then generates a new path. The color of each new path cycles sequentially through a predefined palette of seven rainbow colors.
This project visualizes the Lissajous curve, an elegant mathematical function. The color of the drawing pen continuously evolves over time, creating a dynamic visual effect. Users are the conductor of this visual symphony: the mouse's position directly controls the amplitude of the curve's function. As a result, when the user constantly moves the mouse, the rapid changes in amplitude produce chaotic and jagged line segments. In contrast, when the mouse is held still, the system settles into a peaceful, perfect harmonic motion.
LESSON LEARNED
In this design sketch, my inspiration was drawn from the synthesis of various mathematical functions. The exploration began by combining different equations to generate complex forms, but the project truly found its focus with the final iteration. This concluding piece introduces a layer of interactivity by focusing not on the function itself, but on the method of its rendering. By allowing the user to directly manipulate how the curve is drawn in real-time—altering continuity—the design transforms a static mathematical formula into a dynamic and responsive visual experience.
CODE
Wormhole:
let circleD;
function setup() {
createCanvas(400, 400);
background(220);
circleD = 10;
}
function draw() {
fill(random(0, 255), random(0, 255), random(0, 255), 150);
noStroke();
circle(mouseX, mouseY, circleD);
if (mouseIsPressed) {
circleD -= 1;
} else {
circleD += 1;
}
if (circleD < 10) {
circleD = 10;
}
if (circleD > 200) {
circleD = 200;
}
}
Cosmos:
let centerX, centerY;
let angle = 0;
let currentRadius = 0;
let currentStartAngle = 0;
let currentColor;
let wasPressedLastFrame = false;
let clickCount = 0;
function setup() {
createCanvas(600, 600);
background(0);
centerX = width / 2;
centerY = height / 2;
currentColor = color(0, 0, 0);
stroke(255);
strokeWeight(8);
point(centerX, centerY);
}
function draw() {
let isPressedNow = mouseIsPressed;
if (isPressedNow === true && wasPressedLastFrame === false) { // Check if it is a new press
angle = 0;
currentRadius = dist(mouseX, mouseY, centerX, centerY);
currentStartAngle = atan2(mouseY - centerY,mouseX - centerX);
let colorIndex = clickCount % 7;
if (colorIndex === 0) { currentColor = color(255, 0, 0); }
else if (colorIndex === 1) { currentColor = color(255, 165, 0); }
else if (colorIndex === 2) { currentColor = color(255, 255, 0); }
else if (colorIndex === 3) { currentColor = color(0, 255, 0); }
else if (colorIndex === 4) { currentColor = color(0, 0, 255); }
else if (colorIndex === 5) { currentColor = color(75, 0, 130); }
else { currentColor = color(238, 130, 238); }
clickCount = clickCount + 1;
}
wasPressedLastFrame = isPressedNow;
if (currentRadius > 0) {
angle = angle + 0.02;
let currentAngle = currentStartAngle + angle;
let x = centerX + currentRadius * cos(currentAngle);
let y = centerY + currentRadius * sin(currentAngle);
stroke(currentColor);
strokeWeight(2);
point(x, y);
}
}
Chaotic Peace:
let time;
let prevX, prevY;
function setup() {
createCanvas(600, 600);
background(0);
colorMode(HSB, 360, 100, 100);
const centerX = width / 2;
const centerY = height / 2;
prevX = centerX;
prevY = centerY;
time = 0;
}
function draw() {
let freqX = map(mouseX, 0, width, 0, 10);
let freqY = map(mouseY, 0, height, 0, 10);
const amplitudeX = width / 2 - 20;
const amplitudeY = height / 2 - 20;
let x = width / 2 + amplitudeX * cos(freqX * time);
let y = height / 2 + amplitudeY * sin(freqY * time);
let hue = (time * 20) % 360;
stroke(hue, 90, 90);
strokeWeight(1.5);
line(prevX, prevY, x, y);
prevX = x;
prevY = y;
time += 0.02;
}