Week 3 – Reading Reflection

The only thing I was impressed with was Crawford’s ability to write that much about the misuse of the term interactivity. In my opinion, Crawford was being quite exaggerative. While I understand the frustration and agree that people sometimes slap the word “interactivity” on more reactive things, many of the examples Crawford gave were not very common. I have never really heard of a movie being called interactive before, unless it’s a kids’ movie like Dora, nor have I heard someone call opening the fridge interactive.

Following his argument to its logical conclusion, we should change “interactive media” to “reactive media.” After all, interactive media is programmed to trigger a reaction when the user interacts with it, but it does not listen, think, and respond the way Crawford claims interactivity should. However, when I Googled the official definition of interactivity, the Oxford dictionary defines it as “the process of two people or things working together and influencing each other.” According to this definition, everything Crawford claimed was not interactive is indeed interactive, because it involves things influencing each other, not necessarily listening, thinking, and speaking.

That said, I do agree with Crawford that interactivity exists on a spectrum. I believe the characteristics of a strongly interactive system are its ability to listen, think, and speak. Generative AI is the best example of a strongly interactive system we currently have, if not the most interactive. It simulates human conversation and allows for human-like interactions. Other examples of interactivity, such as humans triggering a reaction from computer-based artwork (like the sketches we do in class), fall on a slightly lower scale of interactivity because they are more of a “reaction,” to use Crawford’s terms, but I would still consider them highly interactive.

To improve the degree of user interactivity in my sketches, I could go beyond just the click of a mouse. Using different parts of the human body, including an interactive webcam project, like one of my classmates’ projects for this week, and even allowing for multiple interactions at once – something like a two-player game – can all improve the degree of interactivity of my sketches.

Week 3: Object-Oriented Programming Constellation

My Concept:
When I first started thinking about this assignment based on what we did in class, I came up with simple ideas such as a balloon pop, but I felt like I wanted something more interesting and interactive. I got inspired when I was sitting outside at night and watching the stars above, which gave me the idea to recreate that image using code and add animation by making the stars move. Throughout the process, I came up with more ideas, such as adding a glow so they appear as “shining stars,” and turning the piece into something interactive by allowing users to connect the stars together. This way, users can create their own drawings by forming constellations and remove the lines using their keyboard. In the end, I created a constellation-inspired artwork of shining stars that float around a midnight-sky background, where the stars connect through the mouse and the connections are fully controlled by the user, allowing them to create different drawings or patterns.
Inspiration:

Embedded Sketch:

A Code I’m proud of:
In this assignment, I explored the code more deeply, and I’m proud of most of my work. However, a particular part I’m especially proud of is the mouse interaction I added. When I first implemented it, I couldn’t make it fully controlled by the user. Instead, when clicking on a star, it would randomly select another star to connect to, and eventually all the lines would connect to the same one. After looking at the references and experimenting with the code, I was able to use the if and else statements, along with the null value to reset the selection, which allowed the user to freely choose which stars to connect.

//Interactions in the Sketch

//Loop to find first star
//When the mouse is pressed on a star
function mousePressed() {
  if (!chosenStar) {
    for (let star of stars) {
      if (dist(mouseX, mouseY, star.x, star.y) < 6) {
        //Select it as the first star and stop loop
        chosenStar = star;
        break;
      }
    }
  }
  //When first star is found, loop to find the second star
  else {
    //Check that its a different star
    for (let star of stars)
      if (dist(mouseX, mouseY, star.x, star.y) < 6 && star !== chosenStar) {
        //Create a line that connects the two stars and store it in the connections array
        connections.push(new Connection(chosenStar, star));
        //Reset so user can choose new stars
        chosenStar = null;
        break;
      }
  }
}

Another part of the code I’m proud of is the temporary line that appears when selecting stars before finalizing the connection. At first, the line simply appeared, but I wanted it to clearly show where the connection was going. After researching and following tutorials, I was able to add this feature using an if statement along with mouseX and mouse Y, making the interaction clearer and more natural for the user.

//Allow a temporary line to be created when selecting a star and moving to select the second one, controlled by mouse
  if (chosenStar) {
    stroke("white");
    strokeWeight(0.2);
    line(chosenStar.x, chosenStar.y, mouseX, mouseY);
    noStroke();
  }

 

Reflection and ideas for future work or improvements:
Overall, I feel satisfied with the outcome of this assignment. I tried new things and experimented much more with effects such as the glow and breathing animations for the stars. I also added more interactivity for the first time and learned many new things throughout the process. I really enjoyed seeing the idea I had in mind actually work the way I wanted it to. However, there is always room for improvement, and I feel like these are just my first steps. For future work, I would love to add more details to the aesthetics of the piece and possibly introduce even more interactivity. Since the theme is stars, I could add elements such as flying rockets, shooting stars, or even a moon that moves or reacts when something specific happens.

References:
I met with a peer tutor, Mariam Alkhoori, who taught me how to create the glowing, floating stars as a starting point for this project.
I used the p5.js reference page (
https://p5js.org/reference/) to ensure I was using the functions correctly. Some of the specific references I used include:
https://p5js.org/reference/p5/line/
https://p5js.org/reference/p5/mousePressed/
https://p5js.org/reference/p5/sin/
I used the Happy Coding tutorial on array functions to better understand how to use arrays and remove elements using pop() (https://happycoding.io/tutorials/p5js/array-functions#pop)
I used ChatGPT to help navigate and understand bugs in my code when it did not work. When working with the Star class, I sometimes mixed up how object properties are referenced. I mistakenly used ‘star.x’ inside the class instead of ‘this.x’, which caused errors because ‘star.x’ is not defined inside the class. This caused the sketch to not properly access or draw the stars. By reviewing the code with ChatGPT, I was able to identify how properties inside a class must be accessed, as we practiced in class. I applied the same logic when working with the connection class to ensure consistency across all classes and the main sketch. 

Reading Reflection_Week3

The characters of a strongly interactive system should include a strong need for input, and a strong output which has the user intrigued even further. The outputs need to be able to create joy or interest or maybe even frustration, just something that can really have the user feeling deeply about what had happend, and trigger the strong intention to try again. I believe games are a pretty good example of this. They require input to do anything at all, and they might be somehow addictive because the output from the game keeps the gamer strongly sttracted. Whether it is that the user dies and needs to start again, needs to finish something, or needs to start somethign new, the feeling generated by the system urges the user to make another input, and then the cycle of an interactive system can keep spinning until one decides to leave.

For my own p5 sketches, I think they lack an interactive depth. There is too little to do with my sketches, since I haven’t learned enough to build a game out of it. There is no interactive cycle, it is usally just a click or a movement of the mouse, and everything is over. This leaves the user with no intention to start again or do something different because they have already finished everything they can. Also, the output isn’t intersting enough. If the output is, for example, getting a certificate that holds some value, or maybe a souvenier of Abu Dhabi, it might make the users want to participate more (for more or different rewards), or maybe it can attract other users.

According to this, I get the idea that I have to incorparate more interactive funcions to keep the user interested when I go on to learn more code and make the big projects.

Assignment_Week3

Concept

I had my initial inspiration from the algorithmic art of Vera Molnár, but since someone already did art based on that and I wanted something more lively, so I thought of making tracing eyes across the canvas. I originally aimed at giving it a spooky feeling but wasn’t really able to fixate an idea on how to make it spooky. So I just ended up using random colors and having the eyes pop up randomly acreoss the canvas.

The tracing effect was the part that I really wanted to implement the most as an idea. I wanted all the eyes, no matter where they are on the screen, to be looking at the position of the mouse. Since I was using class to draw the eyes, it meant that there needed to be a universal fucntion for all the eyes, and I am pretty proud of the results.

Code that I am proud of 

let dx = mouseX - this.eyex;
    let dy = mouseY - this.eyey;
    //calculates the angle of point(dx,dy) relative to positiveX, which is same as (mouseX,mouseY) to horizontal
    let alpha = atan2(dy, dx);
    //calculate distance between mouse and eye center
    let distance = dist(mouseX, mouseY, this.eyex, this.eyey);
    //if mouse is inside the iris, pupil & iris movements follow the mouse, if mouse is outside, they follow the angle at the max distance of 12.5, so they dont run from the eye
    let movedist = min(distance, 25 / 2);
    let movedist2 = min(distance, 3);
    //cos determines horizontal direction movement and sin defines verticle direction movement
    let pupilx = this.eyex + cos(alpha) * movedist; 
    let pupily = this.eyey + sin(alpha) * movedist;
    let irisx = this.eyex + cos(alpha) * movedist2;
    let irisy = this.eyey + sin(alpha) * movedist2;

The code used in creating the movement was not too difficult, it was the math that took me a lot of time. Arc-tangent-2 was used to calculate the angle for the tracing,  because angle of point (dx,dy) relative to positiveX is the same as (mouseX,mouseY) to positive x.

The line I liked most in this chunk is where I united the situations of the mouse being inside and outside the iris in one line. taking the minimum of the two numbers allowed the pupil to follow the mouse smoothly as it transfers across iris.

Embeded sketch (click to see eyes)

Reflection

I actually have reflected quite alot during the production already. Because I randomnized the size and stroke weight, it was a bit difficult to make the arcs meet at the ends, and some of the thinner lines dont really look good with big eyeballs. Also, I did no fill for the arc so it wouldn’t create a fan shape, but that also leaded the bottom eye to be able to be seen through the top eye. I may need to reasearch into how to fill odd shapes to fit that.

Some further development I want to make to this is maybe attach it to some creature instead of having a lot of eyes floating and stacking on top of each other. I am thinking about maybe putting it on some worm because for some reason I think of the game I am playing called Hollowknight: Silksong when I look at the eyes move.

Reading Reflection – Week 3

The reading by Crawford pushed me to reflect more carefully on how I define interaction in my own work. I usually associate interaction with visible movement or manual input, but Crawford presents it as an exchange in which the user acts and the system responds in ways the user can notice and understand. The user stays engaged when their actions change behavior over time and when feedback feels connected to what they do. Crawford emphasizes listening as a core part of interaction, meaning the system changes only when the user’s input affects future responses. This idea made me realize how easy interaction becomes shallow and meanigless when the system continues regardless of the users presence

When thinking of how I want to apply this idea to my p5 sketches, I see areas where interaction feels just a bit limited in a way. Many sketches rely on randomness and animation, which creates visuals but does not always depend on the user’s actions. When the user moves the mouse or clicks, the sketch often continues in a similar way, which kind of weakens the sense of exchange Crawford describes in the reading. To improve this, I want the users input to influence structure rather than just surface behavior. Mouse movement could change speed, and clicks could change patterns. Changes like these would force the system to listen and respond, which aligns more closely with Crawford’s definition of interaction and helps the work feel more intentional and responsive rather than automatic and fixed. Overall, Crawford’s text really opened my eyes on the concept of interaction, and definitely deepened my understanding of how I want to incorporate it in my own work in the future.

Week 3 Assignment – Simplified Pac-Man

Concept

For this week’s assignment, I decided to draw a bit from the skills I learned in Intro to CS back in my freshman year. I chose to implement a very simplified version of Pac-Man, something I always wanted to recreate.

Here is the final sketch (use the right arrow key to begin moving Pac-Man):

The idea is simple: you use the left and right arrow keys to move Pac-Man, and it eats the ghosts once it approaches them. Once all the ghosts are eaten, and Pac-Man returns to his starting position on the left side of the screen, the ghosts regenerate. This creates a sort of infinite loop.

Pac-Man:

The Pac-Man figure is created using the arc() function. On the p5 reference page for the function, there is a sample code for a biting Pac-Man. So, I used that in my assignment. I used Claude.ai to understand what each line of code was doing, specifically how the sin function works and how it enables the model to open and close its mouth. Building on this knowledge, I was able to adjust the speed at which Pac-Man was biting. I also added a boolean that checks if he is moving, so that he is only biting when he is moving.

Pac-Man’s movements are based on the pressing of the right and left arrow keys. From my Intro to CS class, where we built a sample Super Mario Bros game, I knew there must be a way to trigger movement when a specific key is pressed. With a Google search, I found that you can use

if (keyCode === LEFT_ARROW)

However, this function made it difficult to make Pac-Man move when the key is pressed and stop when the key is released. I had a bug where he would just keep moving on his own. I asked Claude.ai for a different function that is specifically for detecting if a key is held down or not, and it gave me the keyIsDown() function. This function returns true if the key is pressed, and false if not. This function fixed my bug and made Pac-Man stop and go correctly.

Ghosts:

For the ghosts, I found PNG images on Google and uploaded them to the sketch. Then, I found this sketch online, which includes a tutorial on how to load and display images.

I faced some difficulty with getting the ghosts to disappear when Pac-Man eats them. At first, I was just looping through the image names and displaying each image, then checking if the x position of Pac-Man and the image aligned, and deleting the image, but this was not doing anything. I asked Claude.ai why my code was not working, and it pointed out to me that images cannot hold x variables; therefore, I cannot check conditions using them. So, I created a simple Ghost class to store each ghost image’s x and y positions, its size, and image name. I made each ghost image an instance of the Ghost class, and stored them in a ghosts[] array. This allowed me to use the dist() function to see if Pac-Man was close to the ghost and delete that ghost instance from the array, which makes the ghost disappear from the sketch.

I was initially just going to leave the sketch with one iteration of displaying, then eating the ghosts, but then I decided to make it regenerate the ghosts every time they are all eaten. I did this by checking if the ghosts[] array is empty, because that indicates that all ghosts have been eaten. Adding only this condition gave me a small bug where the ghosts do not generate when the sketch first loads. It also would re-display the ghosts as soon as the last ghost is eaten, and since Pac-Man would be in proximity of the last and before last ghosts, it eats them immediately, making all the ghosts disappear as soon as they appear. Therefore, I added a condition that ensures that not only must the array be empty, but Pac-Man must also be on the left side of the screen (back at his starting position).

Code Snippet I am Proud of:

//loop backwards through the ghost objects to delete from the back of the array, otherwise you skip items in the array
 for (let i = ghosts.length - 1; i >= 0; i--) {
   let ghost = ghosts[i];

   //display the ghost image
   image(ghost.imgName, ghost.x, ghost.y, ghost.size, ghost.size);

   //if the distance between the center of pacman and the center of the ghost is smaller than 50
   if (dist(pacman.x, pacman.y, ghost.x + 40, ghost.y + 40) < 50) {
     //delete that ghost object from the array so that it is not displayed
     ghosts.splice(i, 1);
   }
 }

This is the code to display the ghost images and delete them when Pac-Man eats them. I am most proud of it because it took me the longest to figure out, and I made LOTS of edits until I reached the final version that worked.

Reflection

Overall, I am extremely happy with my work. Pac-Man has always been one of my favorite games, and I am thrilled I got the chance to recreate it. Despite running into a lot of bugs, they taught me a lot along the way, helped me discover new functions, and expanded my knowledge on how certain things are done in JavaScript since I have never coded using it before. For the future, I would definitely love to properly implement a full Pac-Man game, maybe for my final project 🙂

References

keyIsDown(): https://p5js.org/reference/p5/keyIsDown/

Image upload tutorial: https://editor.p5js.org/FAAH/sketches/8s1g0vilF 

arc(): https://p5js.org/reference/p5/arc/

Claude AI: https://claude.ai/new

  • Claude was used to understand the biting Pac-Man code from the arc() reference page, for debugging when the ghosts were not disappearing, and for finding the keyIsDown() function. It gave me the solution of creating a ghost class, which I then implemented on my own.

Week 3 – Reading Reflection

Reading Chris Crawford’s chapter made me realize that I never really thought deeply about what “interactivity” actually means. I always assumed anything on a screen was interactive, but Crawford explains that real interactivity is like a conversation where both sides listen, think, and respond. When I compare that to the apps and games I use the most, like TikTok, Tetris, and Block Blast, I can see how they fit his definition. These apps react to what I do, and I react back, so it becomes a cycle. Crawford also talks about how the word “interactive” gets thrown around too much, and I agree because I’ve seen products or websites call themselves interactive even when they don’t respond to the user at all. Sometimes a site has so many buttons, menus, or pop‑ups that it feels more overwhelming than interactive. His point about needing two “actors” made sense to me because a system that only shows information without responding to the user isn’t really interacting. It made me think about how much I value visuals, animations, and feedback because those things make a system feel alive and responsive, not just decorative.

The reading also made me reflect on my own p5 sketches and how they fit into Crawford’s idea of interactivity. So far, I’ve made things like my panda portrait and class exercises with bouncing balls and patterns. These sketches react in small ways, but they don’t fully “listen, think, and speak” back to the user yet. Crawford’s definition made me realize that I want my sketches to respond more directly to what the user does. I want to add animation, movement, and user‑controlled elements so the sketch feels like it is reacting to the person using it. I also want to make something that feels more like a small game or a mini‑movie, where characters move and interact with each other. The reading helped me understand that interactivity is not just about visuals but about creating a back‑and‑forth experience. By the end of the semester, I hope my sketches feel more alive and fun, and I want users to enjoy interacting with them. I’m inspired by old pixel games from the 2000s because they feel nostalgic, simple, and playful, and I want to bring that feeling into my work while also making sure the interaction follows the cycle Crawford describes.

Week 3 – Assignment

My concept:

For this week’s assignment, I created a generative artwork using arrays and objects. I followed the bouncing bubbles example we worked on in class, but I changed it to make something more colorful and fun. The main idea is that the user can click anywhere on the canvas to add bouncing circles. Each circle has a different size, speed, and color because all of those values are random.  I wanted to keep the idea simple while practicing the coding concepts we learned, especially storing objects in arrays and updating them inside a loop.

My concept was to make something interactive that didn’t rely on complicated visuals but still felt fun to use. Since we learned how to create our own objects and store them in arrays, I wanted to build a sketch where the user could generate many circles without manually drawing each one. The bouncing bubbles demo from class inspired me a lot, especially the way each object moves on its own. I also liked the idea of randomness and repetition, which are common in generative art. I wanted the user to help create the final image, so every time the sketch runs, the result is different since they could be different colors and sizes.

How the Project Works:

I started by creating an empty array called shapes, which stores all the circles that appear on the screen:

let shapes = [];

Whenever the user clicks, a new Shape object is created at the mouse position. I used .push() to add it to the array so the sketch can keep track of every circle the user creates. I wrote a Shape class that gives each circle its own position, speed, size, and color. The class also includes functions that make the circle move, bounce off the edges of the canvas, and display itself.

The sketch also includes a simple interaction where pressing any key removes the last circle from the array. This gives the user some control over how crowded the canvas becomes.

Inside the draw() function, I used a for‑loop to update every circle in the array. The loop calls move(), bounce(), and display() for each object. This is what makes the animation run smoothly and allows all the circles to move at the same time.

Embedded Sketch:

Code Highlight:

One part of the code I’m proud of is the loop that updates all the shapes:

for (let i = 0; i < shapes.length; i++) {
  shapes[i].move();
  shapes[i].bounce();
  shapes[i].display();
}

This section shows how useful it is to create your own objects. Instead of writing separate code for each circle, one loop controls everything. It keeps the sketch organized and makes it easy to add or remove shapes.

Reflection and future ideas:

This assignment really helped me understand how arrays and objects work together in a sketch. In the beginning, I kept forgetting small things like using .push() or making sure my variable names matched exactly, and those tiny mistakes caused a lot of errors. Since JavaScript is case‑sensitive, even one wrong letter would break the whole thing, so I had to get used to being more careful. Once I understood how everything connected, the array, the class, and the loop, the project became much easier and honestly more fun to work on. I enjoyed playing around with random values for the colors, sizes, and speeds because it made the artwork feel more alive and unpredictable.

If I had more time, I would love to expand this sketch by adding different types of shapes instead of just circles, or maybe adding fading trails behind the shapes as they move. I also think it would be interesting to experiment with sound interaction or simple physics like gravity to make the movement feel more dynamic. Overall, this assignment made the concepts we learned in class feel much clearer, and it showed me how these techniques can be used creatively instead of just technically.

References:
  • p5.js Reference – random() https://p5js.org/reference/p5/random/
  • p5.js Reference – ellipse() https://p5js.org/reference/p5/ellipse/
  • p5.js Reference – color() https://p5js.org/reference/p5/color/
  •  Reference – mousePressed() https://p5js.org/reference/p5/mousePressed/
  • p5.js Reference – keyPressed() https://p5js.org/reference/p5/keyPressed/
  • Class example: Bouncing Bubbles (Intro to IM)
  • I used AI only to help me fix small mistakes in my code, especially when I had red error lines and couldn’t figure out what was causing them.

Matrix

The inspiration for this is the cyber Matrix. It normally has green strings of number falling down. I wanted to use that concept and make circles of strings. and then have some thing that highlights if a certain number of digits get randomly aligned. I didn’t not think of any user interactivity in this. After mapping it out in terms of pseudocode, I decided on on squared path instead of a circular one.

I started of by making a class for the number trains. The creation of the trains was the easiest thing. I set a length attribute that decides what it will be each string will look like. It start with 2, and each string has a random pattern of this length numbers which repeats all the way. it leaves a trail equal to its each side of the squared path. it vanishes at the end of each side and creates a new one after. This was not the planned behavior but as the code treats each side a single unit, I was not able to make the trail of persistent between sides. One of the ways to achieve this was to make the trail vanish as the new one generates.

The hardest part to code was the movement and making sure it work in the right order at the right time. the first problem I encountered was off by one error. After a lot of hit and trial, I asked chatgpt to look at it. it suggested me to add a lastStop attribute. I used that to as the starting point for the next side. The down side for that was the corner overlapped. This visual change is not noticeable.

Here is how it looks,

The most fun part of the code was when I integrated functions of a class into my final function that controls the working of the code

  round(startx, starty) {
    let sideLen = (this.length ** 2) * this.charSize;
    let loopLen = sideLen * 4;

    let h = this.head % loopLen;

    if (h < sideLen) {
      this.movex(startx, starty, 1, h);
    } 
    else if (h < sideLen * 2) {
      this.movey(starty, startx + sideLen, 1, h - sideLen);
    } 
    else if (h < sideLen * 3) {
      this.movex(startx + sideLen, starty + sideLen, -1, h - sideLen * 2);
    } 
    else {
      this.movey(starty + sideLen, startx, -1, h - sideLen * 3);
    }

    this.head += this.speed;
  }
}

What I will add in this is to decrease the space between the strings and make it more chaotic.

Week 3 – Reading Reflection

From the reading, I understood interactivity as a cyclic process where two actors continuously listen, think, and speak. I would say that I agree with his idea he explains the full idea in the reading clearly and uses relevant examples when introducing a new phrase or concept and I found myself easily understanding what he was saying and connecting it to my own works for example in my assignment 3 I responded to The idea of interactivity by allowing the users to generate new stars which fast like a small version of the listening and speaking and thinking cycle Crawford describes.

I really liked Crawford’s examples and his use of scenarios because they helped me visualize his concept instead of just reading a definition. His conversation example, especially the moment where “Step One: Fredegund listens to Gomer, paying close attention to Gomer’s words…,” made the idea much easier for me to grasp. The refrigerator door example also challenged one of my assumptions; before reading this, I probably would have called anything that reacts “interactive,” but now I see the difference between low interactivity (technically responsive but shallow) and high interactivity (meaningful and thoughtful). What stood out most is that strong interactivity requires all three parts to work well with no trading off. It reminded me of how frustrating it feels when someone “responds” to me without actually listening. A step in the reading I think would be hard to implement in my coding would be making the sketch respond in a meaningful and impactful way. While I can handle simple outputs, creating a system that truly “listens, thinks, and speaks” without weakening any part is more complicated than it sounds, especially as someone still new to code.

One thing that surprised me while reading was how much Crawford’s ideas made me reflect on my own life and experiences, both in coding and in everyday communication. I realized that I naturally focus on the part producing something visually interesting without fully thinking about how well my sketches are actually listening or thinking. It made me more aware of how limited my interactions can feel when the system only reacts in a basic way. But at the same time, that doesn’t make them any less satisfying.

Crawford’s refrigerator example reminded me that even simple reactions can feel rewarding when they respond at the right moment. Kids opening and closing a fridge door aren’t experiencing deep interactivity, but the responsiveness still feels good. That idea felt almost self contradicting at first, but it helped me understand that my sketches don’t need to be extremely complex to feel interactive they just need to respond in a way that feels intentional and connected to the user. That shift in perspective helped me appreciate the small interactions I’m already creating, while also motivating me to push them further.

To improve my sketch, I want to increase the “level” of conversation between the user and the system. Crawford’s idea that interactivity depends on how well something listens, thinks, and speaks made me realize that my sketches mostly stop at the listening stage. Since I’m still new to coding, the hardest part for me is creating a response that feels thoughtful rather than mechanical. One idea I’m excited about is having the sketch interpret the user’s “words” in a more complex way. For example, I want the code to listen to sound input and translate different volume levels into different colors, creating an evolving color palette. This would make the sketch feel like it’s actually responding to the user’s presence and energy, not just reacting to a single input. It’s a small step toward completing the “thinking” part of the cycle, but it feels like a meaningful way to push my work closer to the kind of interactivity Crawford describes.