Sourcerepo

Lightbox

An image viewer in plain TypeScript: pictures grow out of their thumbnails, swipe between them, drag down to close and pinch to zoom, with no dependencies.

Status
Open source
Language
TypeScript
License
MIT
Updated
Oct 2026
A tour of the viewer: a print grows out of its tile, a swipe moves to a chart screenshot, a double tap zooms in to read the numbers, and a drag down sends the picture back to its tile

An image viewer that starts from the thumbnail you tapped. The picture grows out of its tile with the tile's crop, then opens to the whole image; closing shrinks it back into the same spot. On a phone it handles like a photo app: swipe between pictures, drag down to close, pinch to zoom. It is plain TypeScript with no dependencies, and this site runs on it.

Install

Clone
git clone https://github.com/drkxbt/lightbox
Install
npm install github:drkxbt/lightbox
Use
import { lightbox } from "@drkxbt/lightbox"

Features

  • Opens from the thumbnail and flies back on close, keeping its crop, corners and tilt
  • Swipe between pictures, drag down to close, pinch or double-tap to zoom, pan with rubber-band edges
  • Arrow keys, Escape, click and wheel zoom on a desk; the Back gesture closes it on a phone
  • The thumbnail shows at once and the full image takes over when it has decoded
  • A labelled dialog that keeps focus inside, fades under reduced motion and runs under a strict Content Security Policy

How it works

  • The full-size frame is moved and scaled onto the thumbnail and clipped to what the tile shows, then both animate to nothing. Only transform, clip-path and opacity move.
  • A tilted thumbnail turns upright as it opens and tilts back as it lands, turning around its own centre.
  • Three slides sit side by side: the picture and its neighbours. A swipe moves the row, then the slides rotate behind the scenes.
  • One finger decides what it is doing from how it first moves: across to swipe, down to close, anywhere to pan when zoomed. Two fingers pinch around their midpoint.
  • Release speed comes from the last 100ms of movement, so a quick flick is enough and a pause before letting go reads as still.

Where it shows here

The screenshots on Source and on each review, the prints in the Gallery and the covers on the Bookshelf. Tap one: the Gallery prints straighten as they lift off the table.

Screenshots

  • A woodblock print grows out of its tile in the gallery and fills the screen
    OpenGrows out of its tile
  • A swipe slides from the print to a chart screenshot
    SwipeA flick to the next one
  • A double tap zooms into the chart, a drag pans across it, and a second double tap zooms back out
    ZoomDouble tap, pan, zoom out
  • A drag down shrinks the screenshot as the backdrop fades, and it flies back into its tile
    CloseDrag down to send it home

Stack

  • TypeScript
  • Pointer Events
  • Node test runner

Run it locally

git clone https://github.com/drkxbt/lightboxcd lightboxnpm installnpm run demo