Concept
The magnetic effects and trails that I have come across a lot while looking for inspiration for this project served as my motivation. After doing some research, I came to Professor Aron’s website, which featured several interactive elements related to text manipulation. And it was these pictures on Pinterest that inspired me. The primary concept was kinetic typography, which used particles to smoothly transition between words to depict the unpredictable character of the natural world. It demonstrates how basic components can come together to create meaningful expressions when they are directed by physics and a little bit of randomness.
Code
The part of the assignment I’m most proud of is the creation of the Vehicle class. This piece of code is special because it makes each dot on the screen move like it has its mind, heading towards a goal. It combines simple rules of movement and direction to bring letters on the screen. What makes this class stand out is how it turns basic coding concepts into something that feels alive and interactive.
let font; let vehicles = []; let originalPoints = []; let cycleDuration = 5000; // Duration of one cycle in milliseconds let lastResetTime = 0; // Tracks the last time the positions were reset let words = ["SHOK", "SHAK", "SHOK"]; // Array of words to cycle through let currentWordIndex = 0; // Index of the current word in the array function preload() { font = loadFont('myfont.otf'); } function setup() { createCanvas(800, 300); background(255); textFont(font); textSize(192); setupWord(words[currentWordIndex]); } function draw() { let currentTime = millis(); if (currentTime - lastResetTime > cycleDuration) { // Move to the next word in the array, cycling back to the start if necessary currentWordIndex = (currentWordIndex + 1) % words.length; setupWord(words[currentWordIndex]); // Setup points for the new word resetPositions(); lastResetTime = currentTime; } else { background(255, 20); // Semi-transparent background for trail effect } for (let v of vehicles) { let noiseForce = getNoise(v.pos.x, v.pos.y); v.applyForce(noiseForce); v.update(); v.show(); } } function setupWord(word) { vehicles = []; // Clear the current vehicles let bounds = font.textBounds(word, 0, 0, 192); let posX = width / 2 - bounds.w / 2; let posY = height / 2 + bounds.h / 4; let points = font.textToPoints(word, posX, posY, 192, { sampleFactor: 0.5 }); originalPoints = points; for (let pt of points) { let vehicle = new Vehicle(pt.x, pt.y); vehicles.push(vehicle); } } function getNoise(x, y) { let noiseVal = noise(x * 0.01, y * 0.01); let angle = map(noiseVal, 0, 1, 0, TWO_PI); let force = p5.Vector.fromAngle(angle); force.mult(0.1); return force; } function resetPositions() { for (let i = 0; i < vehicles.length; i++) { vehicles[i].pos = createVector(originalPoints[i].x, originalPoints[i].y); vehicles[i].vel = p5.Vector.random2D().mult(0); // Reset velocity } } class Vehicle { constructor(x, y) { this.pos = createVector(random(width), random(height)); // Start with random positions this.target = createVector(x, y); this.vel = p5.Vector.random2D(); this.acc = createVector(); this.r = 4; this.maxspeed = 4; this.maxforce = 1; } applyForce(force) { this.acc.add(force); } update() { this.vel.add(this.acc); this.vel.limit(this.maxspeed); this.pos.add(this.vel); this.acc.mult(0); } show() { stroke(0); strokeWeight(this.r); point(this.pos.x, this.pos.y); } }
Embedded Sketch
Reflection and ideas for future work or improvements
Reflecting on this assignment, I’m considering the introduction of interactivity, allowing viewers to influence the flow and form of the animation in real-time. Additionally, refining the transitions between words to be even smoother would elevate the visual fluidity, creating a seamless blend from one word to the next. These improvements aim to turn the animation into a more immersive one.