Polaroid Camera

A fun, interactive polaroid camera in the browser. Click, capture, and watch your shot develop in real time.

My role

Sole engineer and designer. Designed the camera UI in CSS, built the capture and develop animation in JavaScript, shipped with zero dependencies.

2 weeks · 2025

Results

  • Zero dependencies
  • Real-time capture
  • Polaroid develop animation
  • Pure vanilla JS
Polaroid Camera

Because browsers should be fun

This one started with a simple question: can you build a polaroid camera in a browser, with no libraries, no canvas hacks, and no dependencies at all?

The answer is yes, and it took about a weekend.

The idea

Polaroid cameras have a specific ritual. You point, you click, the shot ejects slowly, and then you wait. The image develops from nothing, detail by detail. That delay is the whole experience. It's not a bug. It's the point.

Most digital photo effects skip the development part. They apply a filter instantly and call it done. I wanted to actually simulate the wait, the slow reveal from a washed-out white to a developed image, because that tension is what makes it feel like a polaroid rather than an Instagram filter.

Building it without frameworks

The camera UI is pure CSS. The lens, the body, the viewfinder, the shutter button: all box model and border-radius, no images, no SVGs. It's a fun constraint. CSS is surprisingly capable of mimicking physical objects when you lean into it.

The capture flow works in three steps. First, the browser grabs a frame from the webcam stream. Second, it draws that frame onto a hidden canvas element to get the pixel data. Third, it ejects an animated polaroid card and runs the development sequence: a CSS transition that fades the image in from white over a few seconds, timed to feel like the real thing.

The development animation was the part that required the most tuning. Too fast and it feels like a filter. Too slow and you lose interest. The sweet spot is somewhere around three to four seconds, slow enough to feel deliberate, fast enough to stay satisfying.

What vanilla JS taught me here

Working without a framework means managing the webcam stream lifecycle manually. Starting it, pausing it, cleaning it up when the tab loses focus. None of that is complicated, but doing it by hand makes you understand what the browser is actually doing. The getUserMedia API, the MediaStream object, the track lifecycle: you don't have to think about any of this in a framework because it abstracts it away. Writing it directly made me much more comfortable with browser APIs generally.

The canvas capture is similarly instructive. Drawing a video frame to canvas, reading back the pixel data, applying the polaroid color grade as a series of pixel-level operations: this is the kind of thing that's usually hidden behind an image processing library. Doing it manually is slower to write but faster to understand.

Just a fun thing

Not everything needs to be a production system. Sometimes the goal is to make something that makes people smile when they use it. This does that.

What Worked

  • The develop animation convincingly mimics the physical Polaroid experience. The slowdown at the end is the detail that makes it feel real.
  • Zero-dependency approach means instant load: no bundle, no parse time, nothing between the user and the camera
  • Camera UI entirely in CSS is a genuine flex; it looks like a camera because the layout is doing the work

What Didn't

  • WebRTC camera access requires HTTPS and explicit user permission; some browsers add friction here
  • No save functionality; the photo disappears on refresh, which is in-character for Polaroid but frustrates users who want to keep shots

Built with

HTML5CSS3JavaScript