Midterm Project

Final Update: Concept

At first, I wanted my project to recreate my old, cluttered workspace in Bangladesh—full of life, creativity, and memories. But after moving into my dorm, I realized my space now is the opposite: empty, open, and full of possibility.

So instead of a busy, object-filled world, my interactive artwork in p5.js reflects this new beginning. The emptiness isn’t just emptiness—it’s potential. It invites exploration, just like my dorm did when I first moved in. This project became more than just a recreation; it’s a reflection of change, growth, and the spaces we make our own.

️ How It Works

This p5.js sketch opens with a sliding door animation triggered by a double-click—inviting the user into my new, reimagined space. The background is made of looping breathing frames (3 total), giving life to an otherwise still room. All visuals are hand-drawn—hair, furniture, plants, and even a little desktop cat.

Hair animations are split into base, fringe, and left/right segments. Each segment has its own independent frame logic, animated dynamically in code, not as spritesheets—saving memory while giving me more layering control. The breathing and hair create ambient movement that never overwhelms the canvas.

There’s interaction too:

  • Hovering over the lamp activates its glow and animates its arm.

  • Clicking the mirror brings up a live webcam feed. You can “capture yourself” inside the mirror.

  • Clicking the cat opens a surprise sketch.

  • Clicking the Spotify icon links to my actual profile—and starts background music.

I also display a live UAE time clock on the desk monitor, updating every second. Because yes, I coded that too.

 What I’m Proud Of

  • The balance between aesthetics and interaction. I didn’t just cram in clickable objects—I made them meaningful, subtle, and thematic.

  • Hair movement logic. Animating hair in separate segments and syncing their speed gave it a much more natural feel than I could’ve achieved with pre-rendered spritesheets.

  • // Left hair animation
    image(leftHairFrames[currentLeft], xPos - xOffset, yPos - yOffset, hairWidth, hairHeight);
    leftBlend += hairSpeed;
    if (leftBlend >= 1) {
      leftBlend = 0;
      currentLeft = nextLeft;
      nextLeft = (nextLeft + 1) % leftHairFrames.length;
    }
    

     

  • Mirror interaction. Using cam.get() and masking the feed to fit into an oval gave the illusion of a real, personal reflection without needing AR libraries.

  • Sound integration. Audio feedback (the knock, the music) grounds the scene and enhances immersion without stealing the spotlight.

Challenges & Improvements

1. Asset Load Limits & Compression Woes
Initially, I tried creating one big spritesheet for all hair frames—until p5.js (rightfully) panicked. Compressing the sheet butchered the image quality, so I scrapped it in favor of individually loaded and layered PNGs.

// Breathing animation logic
image(breathingFrames[currentFrame], 0, 0, width, height);
tint(255, 255 * blendAmount);
image(breathingFrames[nextFrame], 0, 0, width, height);
blendAmount += fadeSpeed;

if (blendAmount >= 1) {
  blendAmount = 0;
  currentFrame = nextFrame;
  nextFrame = (nextFrame + 1) % breathingFrames.length;
}
noTint();

 

2. Interactivity Clutter
I wanted everything to be interactive. Bad idea. Midway through, I remembered something Professor Mang said: it’s better to be clean and compelling than overloaded. So I scaled back. Some items are just pretty. And that’s fine.

3. Mirror Lag on Some Browsers
Depending on user permissions, the webcam sometimes doesn’t load right. I didn’t implement a fallback system, but it’s something I’d add next time.

 Conclusion

This project started as an homage to an old space but became a meditation on new beginnings. It’s my first time making an ambient interactive piece—part game, part diary, part room. It’s not perfect, but it’s mine. And like any good workspace, it’s full of potential.

Leave a Reply