For this assignment, I decided to take my previous work and try and make it interactive. I have to admit that it took me longer than expected but I eventually got there.
First step was the code. I had to find a way in which I could create firstly a ball that was moving on the screen. After that, I just had to make a bunch of them and make them move in different directions.
I decided to make the colors of the circles random because I thought it might end up being colorful, which it did.
Regarding challenges I think that the constructor was the thing that took me longer but I eventually made it work.
Chris Crawford’s elucidation on interactivity, particularly his analogy of it as a conversation between users and systems, introduces a profound reevaluation of our engagement with digital interfaces. This perspective challenges the traditional view of interactivity as mere binary exchanges—inputs and outputs—by imbuing it with a relational, almost human-like quality. The notion that interactivity could harbor the depth and dynamism of a conversation compels us to reconsider the essence of our digital interactions. It suggests that these exchanges are not just about the transmission of information but about building a relationship, a dialogue that evolves with each interaction.
However, while Crawford’s analogy enriches our understanding of interactivity, it also raises several questions about its applicability in the real world. The portrayal of interactivity as a seamless conversation glosses over the inherent complexities and frictions present in human-computer interaction. Real-world interactivity is fraught with misunderstandings, misinterpretations, and a lack of feedback that can disrupt the ideal flow of conversation Crawford imagines. This discrepancy between the ideal and the real prompts a deeper inquiry into how we can design interactive systems that truly embody the conversational model Crawford proposes. Can systems be designed to understand and adapt to the nuanced feedback of users? How do we account for the diverse ways individuals interact with technology?
Moreover, Crawford’s perspective invites us to explore the ethical dimensions of designing interactive systems. If we conceive of interactivity as a conversation, then we must also consider the responsibilities inherent in facilitating these dialogues. How do we ensure that these conversations are inclusive, respectful, and enriching for all participants? In what ways might our interactive systems impose upon, rather than enhance, the autonomy of users?
In reflecting on Crawford’s work, I am both intrigued and skeptical. His vision for interactivity as a conversation between users and systems offers a compelling framework for understanding and enhancing our digital interactions. Yet, it also underscores the need for a critical examination of the assumptions underlying this analogy and the practical challenges of implementing it. As we continue to navigate the evolving landscape of interactive design, Crawford’s insights serve as both inspiration and provocation, urging us to think more deeply about the nature of our digital conversations and the worlds they create.
Reflection on “The Art of Interactive Design” by Chris Crawford:
After reading Crawford’s work, I found myself thinking about how interactivity is often misunderstood. Crawford compares interactivity to a conversation, where both parties listen, think, and speak. This analogy helped me understand that for interaction to be meaningful, both parties need to actively participate. Crawford also talks about how interactivity is often misused and misunderstood. (Pg 5, 6)
However, I had some questions about Crawford’s perspective. He criticizes traditional media like books and movies for not being interactive enough. But I believe these media still have value because they make us feel and think, even though they don’t interact with us directly. Crawford also seems biased towards interactive design over human factors engineering, which focuses on making tools more efficient for workers.
Another question that came up for me was about the limits of interactivity. Are there times when traditional media offer experiences that can’t be replaced by interactive designs? Overall, reading Crawford’s work made me rethink what interactivity means and how it affects design. It made me consider the importance of both form and function in design processes.
I was experimenting with the Circles class that we created in class and thought of some way of generating abstract art by using Circles to draw random lines on the Canvas . I came up with a simple algorithm to generate art :
1.Create random points 2.Draw a circle with random radiuses around the points (restricted random radiuses) 3.Wherever the center of circle is in another, invert the color 4.Make options to change the frame rate 5.Move the circles randomly by making their speeds random 6.Make sliders to change color 7.At the end draw the paths taken to create something random but intriguing
Each Circle on the canvas would have its own corresponding class ,Whenever a Circle would pass over another, it would change color . The user could also add circles by clicking on the canvas. Initially I had fixed the color to a black background and tried experimenting with different colors of circles and backgrounds . Then I thought – ” Why not create a slider to let the user choose what background color they want according to their preferences ?” This would solve the problem of selecting the best looking background and would add user interactivity as well .
Then came the question of art . What kind of final product would I want ?I wanted the art generated to be random but intriguing . I decided to draw the paths traced by the circle . This was done using a graphics buffer . The entire canvas is emptied but only the buffer remains when the simulation ends . I experimented a bit with the color of the trails generated by the circles and decided to make this color relative to the background(just like the fill color of the circles) . I also tried different strokeWeights for the trails and different alpha values for color to make them more or less transparent . at the end I stuck to using strokeWeight as 1 and alpha value as 150 .
Sketches
The following are some interesting sketches that I got by experimenting with color, and strokeWeights and Alpha values for the circle trails
The kind of sketch that We can get from default setting is like follows:
The background color can also be changed according to what the user wants :
In short, there are a lot of variation that the user could decide on , the circles while drawing the lines are aesthetically pleasing too :
I had to make a decision of whether or not to display the trail lines when the circles are still there . At the end I decided to keep the trail lines . However, hiding them until the end requires changing just one if-else loop which I have indicated in the commented code .
Sketch
Below is the embedded sketch :
Try playing with the color values and clicking on the sketch to draw the circles before clicking on end simulation to get the web of lines . Ideally the sketch at the end looks best with a black background
Code that I am proud of
The Display() function of Circles Class is where the magic happens and this is the part of code that I am most proud of :
display() {
stroke(255);
strokeWeight(1);
fill(150 - get(this.x,this.y)[0],255 - get(this.x,this.y)[1],255 -get(this.x,this.y)[2]); // inverting the color of fill from the color at the center of the circle
circle(this.x,this.y,this.radius*2);
// Draw a line segment from previous position to current position onto trails buffer
trails.stroke(255 - get(this.x,this.y)[0],255 - get(this.x,this.y)[1],255 -get(this.x,this.y)[2] ,150);//writes to the trails buffer
//alpha value is 150
trails.strokeWeight(1);
trails.line(this.prevX, this.prevY, this.x, this.y);
// Store current position as previous position for next frame
this.prevX = this.x;
this.prevY = this.y;
}
The idea of using a graphics buffer called trails to make the trails was very useful . the fill() function in this class inverts the color of fill of the circle from the color of the background at the center of the circle . the trails.stroke and trails.strokeWeight command are at the essence of the final art piece (as illustrated in the picture gallery above) . Changing and experimenting with these values was a big part of this project .
Another part that I am proud of is creating the sliders for color and framerate and the end simulation button as it adds to the user interactivity of the sketch .
function setup() {
createCanvas(400, 400);
trails=createGraphics(400,400);
backgroundColor = color(33, 33, 45); // Default background color
//Sliders at the bottom of Canvas
backgroundColorRedSlider = createSlider(0, 255, red(backgroundColor)); // Slider for the red component
backgroundColorRedSlider.position(10, height + 30);
backgroundColorRedSlider.style('width', '80px');
let backgroundColorRedLabel = createDiv('Red');
backgroundColorRedLabel.position(10, height + 10);
backgroundColorRedLabel.style('color', '#FF5733'); // Custom color
backgroundColorRedLabel.style('font-family', 'Arial, sans-serif'); // Custom font
backgroundColorGreenSlider = createSlider(0, 255, green(backgroundColor)); // Slider for the green component
backgroundColorGreenSlider.position(110, height + 30);
backgroundColorGreenSlider.style('width', '80px');
let backgroundColorGreenLabel = createDiv('Green');
backgroundColorGreenLabel.position(110, height + 10);
backgroundColorGreenLabel.style('color', '#156F25'); // Custom color
backgroundColorGreenLabel.style('font-family', 'Arial, sans-serif'); // Custom font
backgroundColorBlueSlider = createSlider(0, 255, blue(backgroundColor)); // Slider for the blue component
backgroundColorBlueSlider.position(210, height + 30);
backgroundColorBlueSlider.style('width', '80px');
let backgroundColorBlueLabel = createDiv('Blue');
backgroundColorBlueLabel.position(210, height + 10);
backgroundColorBlueLabel.style('color', '#3366FF'); // Custom color
backgroundColorBlueLabel.style('font-family', 'Arial, sans-serif'); // Custom font
frameRateSlider = createSlider(10, 150, 70); // Min: 1, Max: 60, Starting value: 30
frameRateSlider.position(10, height + 80);
frameRateSlider.style('width', '80px');
let frameRateLabel = createDiv('Frame Rate');
frameRateLabel.position(10, height + 60);
frameRateLabel.style('color', '#560F0F'); // Custom color
frameRateLabel.style('font-family', 'Arial, sans-serif'); // Custom font
frameRateSlider.position(10, height + 80);
frameRateSlider.style('width', '80px');
//End simulation button
let endButton = createButton('End Simulation');
endButton.position(10, height + 100);
endButton.mousePressed(stopSimulation);
endButton.style('font-family', 'Arial, sans-serif');
endButton.style('background-color', '#FF5733');
endButton.style('color', '#ffffff');
endButton.style('border', 'none');
endButton.style('padding', '5px 10px');
endButton.style('border-radius', '5px');
endButton.style('cursor', 'pointer');
//Create all required Arrays
speeds = generateSpeeds(num_of_circles);
v = generateRandomPoints(num_of_circles); //10 points
r = createRandomRadiuses(num_of_circles, 30, 20); //(length , max_radius ,min_radius)
arr_circles = createArrayCircles(v, r); //Create array of Circle objects
}
Challenges and Further Ideas
One challenge was thinking about the various variables involved in this sketch and asking questions like- the number of default circles? The range of speed? The framerate? the Background color? How should the trail color relate to the background color? What should be the Stroke weights and alpha values for the trail color? Some of these do not have a right or wrong answer and much depends on user preferences . I factored in user input for some of these and determined the rest by experimenting with what looked good (even the variables determined by the user needed to have a default value that should look good to most people) .
While adding user interactivity solved some of these problems, there is scope for taking even more input from the user in the form of asking for alpha values or Stroke weights that would allow the user to use this as a tool for creating generative art .
I also had further ideas of changing the colors of the circles at the intersection (the part where they intersect) rather than changing colors based on the coordinates of the circles center . This would make the “drawing” part perhaps more visually appealing or could be made into an artwork of its own .
Overall Reflections
I am happy with the final result and with the variety of sketches that I got playing around with the transparency and color of the trails drawn by the circle. I learnt a lot about creating sliders and graphicBuffers . This project also taught me the power of OOP – one small change in the circles class affects the entire sketch in drastic ways . I was looking to implement something based on Perlin noise for the color of the circles if they are to change without any user input but eventually I just decided to stick to the slider mechanism . Replacing the user input with Perlin noise is something I look forward to experimenting with in future projects .
This reading totally shifted my thinking on what interactivity really means. The metaphor of a back-and-forth conversation was a lightbulb moment for me. Like two people listening and responding to each other. It clearly shows why a book isn’t truly interactive even when it fully engages me. A book just conveys information, oblivious to my reactions. It doesn’t necessarily tailor itself to me.
Framing interactivity as a spectrum rather than a yes/no thing landed perfectly too. It’s like turning the volume up and down – experiences can be more or less interactive. A video game responds more to me than a cooking show I passively watch. And good graphics or UI design is only part of the equation – you have to build in that two-way communication. Looks alone don’t cut it.
I’ll admit some sections felt dense on first read. But the big takeaway was that interactivity isn’t just about engagement, it’s about a back-and-forth exchange where both parties actively listen and speak. Measuring where something falls on that spectrum makes me evaluate all kinds of media differently now. How much am I conversing rather than just being “spoken to”? Food for thought as I wrap my head around design. Overall, this was a solid, informative read.
We often overlook the audience for whom we create something, a tendency especially noticeable in the tech sphere. The primary focus tends to be on making the code function well, while the ‘thinking’ process is neglected, as the author points out. This mirrors human interaction; understanding the person you are talking with is similar to the concept of being interactive. You should know their personality and truly grasp what they want and like to foster meaningful conversation. I believe the true essence of being ‘interactive’ lies in the ability to engage people by understanding their preferences.
Initially, my view of interactive media was merely as a course that merges art and technology. However, after further reflection, my understanding of interactive media has deepened. Now, I see interactive media as something beyond merely delivering impressive outputs; it is about conveying a message and touching someone’s heart, whether by making them feel happy, interested, or impressed. It gains true significance through the “thinking” process between inputs and outputs. My decision to major in business was driven by a desire to create something meaningful for people. Realizing that interactive media can achieve this objective has made it increasingly appealing to me.
While brainstorming for my assignment, my initial thoughts centered around creating an art piece featuring several repetitive elements in motion. Suddenly, I recalled an image of Turkey I had seen before, specifically a picture of hot air balloons in Cappadocia.
The sight of these balloons, each a different color, struck me as particularly appealing, and I decided to base my art on the concept of hot air balloons moving upwards. This idea aligned perfectly with my original concept of incorporating moving, repetitive elements.
Upon completing the hot air balloon portion of my project, I noticed the background felt somewhat empty, so I decided to make moving clouds in the background. Thus, the combination of clouds and hot air balloons became my final concept.
I started with the hot air balloons by creating a Balloon Class, aiming to generate several balloons simultaneously using the same code. Within this class, I implemented a move() function to enable the balloons to move upwards.
//move Hot Air Balloons
move() {
this.x = this.x + this.xspeed;
this.y = this.y + this.yspeed;
}
Next, I used the show() function to draw the hot air balloon.
To ensure each hot air balloon displayed different colors, I introduced variables like “balloonColor” and “highlightColor,” assigning them random RGB colors. The balloon featured two colors: a primary color and a “highlightColor,” which was derived by adjusting the blue component of the RGB value to complement the primary color.
//Randomize Balloon colors
let red = random(255);
let blue = random(255);
let green = random(255);
this.balloonColor = color(red, green, blue);
//Highlight Color in the middle which is similar to the sum of R and B of the main color
let b = (red + blue / 1.3)
this.highlightColor = color(red, green, b)
To continually regenerate hot air balloons and ensure upward movement, keeping the canvas filled, I created a reset() function.
//create a new balloon and reset the animation if the hot air balloon reaches the end of the canvas
reset() {
if (this.y < -250) {
this.y = height + 100
this.yspeed = random(-2, -5)
this.x = random(width)
this.xspeed = 0
}
As mentioned earlier, I wanted to include clouds in the background. Thus, I crafted a separate Cloud Class and utilized similar methods to those in the Balloon Class for showCloud(), moveCloud(), and resetCloud(). The clouds moved from left to right, and their reset function triggered upon reaching the canvas’s right edge. Cloud sizes varied randomly.
I then utilized “this.cloudsize” within the showCloud() function to render a cloud.
To populate the scene with multiple clouds and hot air balloons, I established arrays for each, allowing for automated element addition up to a predefined number.
let balloons = []; //create balloons array
let clouds = []; //create clouds array
function setup() {
createCanvas(1000, 1000);
//create 7 hot air balloons positioned randomly in the canvas with random speed (moving up) and add them to the balloons array
for (let i = 0; i < 8; i++)
balloons[i] = new Balloon(random(width), random(height), 0, random (-2, -5))
//create 9 clouds positioned randomly in the canvas with random speed (moving from left to right) and add them to the clouds array
for (let i1 = 0; i1 < 10; i1++)
clouds[i1] = new Cloud(random(width), random(height), random(2, 5), 0)
}
It was very interesting to learn how to use arrays and classes together to create elements. The process of simultaneously producing multiple elements became significantly simpler. One challenge I encountered while crafting the art piece involved randomizing colors for each air balloon. Initially, I placed the code for randomizing colors in the sketch.js file within the “new Balloon” constructor, which resulted in the color of a single balloon changing randomly each frame. I then realized that I should incorporate this code inside the Balloon Class, utilizing `this.balloonColor` to ensure the randomness of color could be applied specifically to each balloon. Overall, this assignment was highly engaging, and I feel like I gained a considerable amount of knowledge.
Reflecting on “The Art of Interactive Design,” it feels like embarking on a spirited journey through what makes technology engaging. The author presents a world where interactivity is about the clicks and taps on our devices and the conversation between humans and machines. Imagine sitting with a good friend over coffee, where the exchange of thoughts and ideas flows freely. This book suggests that our gadgets should offer a similar two-way street of communication, a concept that feels revolutionary and glaringly obvious.
There’s a playful yet earnest tone in the author’s argument that nudges us to question the authenticity of our digital interactions. Are we merely following a script laid out by designers, or are we genuinely engaging in a dialogue? This perspective might tilt towards a bias for more profound, meaningful connections over superficial tech encounters, but it’s hard not to be swayed by such a compelling case. It leaves you pondering about the true essence of interactivity and whether our current technology meets that mark or acts as interactive. It’s an invitation to dream up a world where every interaction with technology enriches our lives, making us users and participants in a digital dance of ideas.
The concept of using Perlin noise to simulate natural, fluid motion in the particles is inspired. Perlin noise generates a more natural and organic flow compared to purely random movement, as it ensures smooth transitions and variations. This approach is commonly used in generative art and simulations to mimic natural phenomena like smoke, fire, and flowing water.
Code Highlight
// Update the particle's position
move() {
// Calculate a noise value for organic movement
let noiseValue = noise(this.noiseOffset);
this.pos.x += map(noiseValue, 0, 1, -1, 1) * this.rate;
this.pos.y += map(noiseValue, 0, 1, -1, 1) * this.vertRate;
// Wrap the particle around edges to make it looks like space
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
// Increment the noise offset for the next frame
this.noiseOffset += 0.01;
}
The move() function in the particle system utilizes Perlin noise to simulate organic and fluid motion, creating a natural, lifelike behavior in each particle. By calculating a smoothly varying noise value and mapping it to influence the particle’s velocity, the function ensures each particle moves in a unique, seamless manner that mimics natural phenomena. Additionally, the function incorporates edge wrapping to create a continuous, boundless effect on the canvas, enhancing the illusion of a natural, endless environment. This innovative use of Perlin noise, combined with the edge wrapping technique, sets the function apart by providing a sophisticated method to generate complex, visually appealing animations that evoke the randomness and elegance of the natural world.
Embedded Sketch
Code
let particles = [];
function setup() {
createCanvas(600, 600);
// Initialize particles and add them to array
for (let i = 0; i < 400; i++) {
particles.push(new Particle());
}
}
function draw() {
background(0);
// Loop through all particles to display and move them
for (let particle of particles) {
particle.display();
particle.move();
}
}
// Define the Particle class
class Particle {
constructor() {
// Set initial position to a random point within the canvas
this.pos = createVector(random(width), random(height));
this.size = random(0.5, 2);
//Set random transparency value
this.alpha = random(150, 255);
this.noiseOffset = random(0, 1000);
this.rate = random(-1, 1);
this.vertRate = random(-1, 1);
}
// Display the particle on the canvas
display() {
noStroke();
fill(255, this.alpha);
ellipse(this.pos.x, this.pos.y, this.size);
}
// Update the particle's position
move() {
// Calculate a noise value for organic movement
let noiseValue = noise(this.noiseOffset);
this.pos.x += map(noiseValue, 0, 1, -1, 1) * this.rate;
this.pos.y += map(noiseValue, 0, 1, -1, 1) * this.vertRate;
// Wrap the particle around edges to make it looks like space
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
// Increment the noise offset for the next frame
this.noiseOffset += 0.01;
}
}
Reflection
I was creating this particle system with p5.js, especially using Perlin noise for fluid motion. This approach transformed a basic animation into a mesmerizing display that closely mirrors the elegance of natural phenomena. The seamless movement and edge wrapping created an endless, captivating visual experience. This project pushed the boundaries of what I thought possible with code and deepened my appreciation for programming as a form of creative expression.
Future work
Looking ahead, I’m excited to explore further possibilities with this particle system, such as introducing interactions between particles to simulate forces like attraction and repulsion, adding color gradients for a more dynamic visual effect, and experimenting with different noise algorithms to vary the motion patterns.
In “What Exactly Is Interactivity?”, the first Chapter of Chris Crawford’s book, “The Art of Interactive Design,” Crawford attempts to lay down a definition of what interactivity entails from which certain guidelines for interactive design could be extrapolated. He essentially posits that interactivity is a cyclic process of listening, thinking, and speaking that involves two or more actors – much like the process of conversating with other human beings. Going off this definition, Crawford weeds out certain activities as “non-interactive,” from reading books and watching movies to dancing and attending theatrical performances. By arguing that participation in these activities involves a “strong reaction,” which is qualitatively different from strong interaction, he excludes these forms of activities which may be labeled by some as interactive as strictly devoid of the necessary back-and-forth between actors that characterizes high levels of interactivity.
One of the things I appreciated about Crawford’s discursive thought process as he distills what makes things interactive, in addition to his humor and the use of examples to illustrate his points, was the idea that interactivity does not have to be an exclusive binary, but could be assigned a value on a spectrum from low to high. Based on this approach, people subjectively assign degrees of interactivity to certain activities. It did, however, strike me as a little contradictory to go on to adjudicate that some activities were definitively non-interactive, even though some may experientially feel like they were. It also begs the question of whether different people were unified in their understanding of what interactivity is when assigning values to the degree of interactivity they experienced.
Crawford then goes on to theorize the differences between user interface and interactivity designers. While the former mainly considers structure and form, the latter is more concerned with how a given target function is best served by one form over the other. He also makes the observation that interactivity designers come from a less technical background and are often underserved by their inability to match the more established knowledge, frameworks, and technical expertise employed by their counterparts in the user interface domain.
The definition of interactivity as a recurring process of listening, thinking, and speaking stuck with me as I contemplated the forms of interactivity that people claim to have incorporated into their work when making web applications or digital artworks. While conversations are dynamic, forward-moving, and seldom repeating, many of the interactive elements embedded in digital creations are rarely so. In conversation, actors have a large space of sentences to choose from when speaking and an almost infinite thought space from which a thought could form. This leads to conversations that are new and fresh every time. In the digital space, this is less likely as user interaction is restricted to a small set of defined actions (e.g. clicks or movements) that are mapped to algorithmically consistent behaviors. How do we then emulate the full range of fluidity that true interactivity entails, given that we are sometimes restricted by computational resources? I think the rise in generative AI tools is definitely getting us closer to actualizing Crawford’s interactivity. I am, however, left wondering if Crawford’s definition of interactivity is restrictive. It seems to place high expectations on designers to equip themselves with higher-end technologies to satisfy Crawford’s interactivity guidelines, which may counteractively act as a deterrent.