Concept
For this project, the goal was to apply the concepts learned in class, including loops, arrays, and Object-Oriented Programming (OOP), to create an interactive visual experience. The initial goal was to create a dynamic piece where a single spiral would be generated with each mouse click. However, I wanted to enhance user engagement by adding a feature that allows spirals to change color when clicked inside. So, I decided to use mouseDragged
function to generate spirals and mouseClicked
for spirals to change colour. Therefore, the application now produces multiple spirals during a single drag action across the screen. Furthermore, if a spiral is clicked, it temporarily changes color before reverting to its original hue.
To make the application more visually appealing, I attempted to introduce a feature where waves are generated whenever two spirals collide. I added a trailing effect to these waves, aiming to create a mesmerizing interaction between the spirals and the waves produced. Additionally, I implemented a functionality to clear the screen by pressing the ‘c’ key, allowing users to reset the canvas and start anew.
Sample
Embedded Canvas
Drag your mouse and see the magic.
Code
let spirals = [];
function setup() {
createCanvas(800, 800);
background(0);
}
function draw() {
background(0, 25); // Semi-transparent background for a trail effect
for (let i = 0; i < spirals.length; i++) {
spirals[i].update();
spirals[i].display();
// Check for collision with other spirals
for (let j = i + 1; j < spirals.length; j++) {
if (spirals[i].collidesWith(spirals[j])) {
createWaveBetween(spirals[i], spirals[j]);
}
}
}
}
function mouseDragged() {
let newSpiral = new Spiral(mouseX, mouseY);
spirals.push(newSpiral);
}
// Function to chnage colour of the spiral after mouse ci clicked inside the spiral
function mouseClicked() {
for (let i = 0; i < spirals.length; i++) {
if (dist(mouseX, mouseY, spirals[i].pos.x, spirals[i].pos.y) < spirals[i].radius) {
spirals[i].transform();
}
}
}
class Spiral {
constructor(x, y) {
this.pos = createVector(x, y);
this.radius = random(5, 20);
this.angle = 60;
this.color = color(random(255), random(255), random(255), 100);
this.transformed = false;
}
update() {
this.angle += 0.05;
this.radius += 0.5;
}
display() {
// Itsaves the current drawing style settings and transformations applied to the canvas
push();
// moves the origin to the position of the spiral
translate(this.pos.x, this.pos.y);
stroke(this.color);
noFill();
beginShape();
for (let i = 0; i < this.angle; i += 0.1) {
// Calculate the x and y coordinates of each vertex of the spiral
let x = this.radius * cos(i);
let y = this.radius * sin(i);
// This function adds a vertex to the shape of the spiral
vertex(x, y);
}
endShape();
pop();
}
transform() {
this.transformed = true;
this.color = color(random(255), random(255), random(255), 100);
}
collidesWith(other) {
let d = dist(this.pos.x, this.pos.y, other.pos.x, other.pos.y);
return d < this.radius + other.radius;
}
}
function createWaveBetween(spiral1, spiral2) {
// Calculates the start and end points of the line connecting the centers of the two spirals
let startX = spiral1.pos.x + spiral1.radius * cos(spiral1.angle);
let startY = spiral1.pos.y + spiral1.radius * sin(spiral1.angle);
let endX = spiral2.pos.x + spiral2.radius * cos(spiral2.angle);
let endY = spiral2.pos.y + spiral2.radius * sin(spiral2.angle);
let wave = new HorizontalWave(startX, startY, endX, endY);
wave.display();
}
class HorizontalWave {
constructor(x1, y1, x2, y2) {
this.start = createVector(x1, y1);
this.end = createVector(x2, y2);
this.amplitude = 20;
this.frequency = 0.1;
this.color = color(255);
}
display() {
push();
stroke(this.color);
noFill();
beginShape();
for (let x = this.start.x; x < this.end.x; x += 5) {
let y = this.start.y + this.amplitude * sin(this.frequency * x);
vertex(x, y);
}
endShape();
// This function restores the drawing state that was saved with the most recent
pop();
}
}
Challenges & Reflections:
One of the significant challenges I encountered was the implementation of the wave generation when two spirals collide. The vision was to have the spirals transform into waves upon collision, with the spirals disappearing and the waves remaining on screen. However, I faced difficulties in realizing this feature due to my current level of understanding and technical limitations. This project has not only been a fun exploration of interactive graphics but also a valuable learning opportunity. I look forward to revisiting this project in the future, armed with more knowledge and experience, to incorporate the envisioned features and further enhance its interactivity and visual appeal.
References:
E. J. C. (2021, February 17). Excel – Adding and Graphing Sine Waves with Any Amplitude or Phase. YouTube. https://www.youtube.com/watch?v=2SdAtjoYEXo