Skip to content

Repository files navigation

frankzhang.org

React + TypeScript + Vite. Deployed from GitHub to Cloudflare Pages, which builds and serves dist/ — only index.html and whatever public/ contains reach the web.

npm install
npm run dev          # localhost:5173
npm run check        # validate the sheet — run after moving any cell
npm run lint
npm run build
npm run capture      # re-photograph the four live project sites
npm run film-ground  # re-bake the film texture images

The microfiche viewer

The desktop layout is a contact sheet of film seen through a lens. MICROFICHE_PLAN.md has the design brief.

src/
  projects.ts                 the five projects — the site's content
  microfiche/
    index.ts                  public surface: MicroficheViewer, clusters
    sheetData.ts              every cell and its coordinates
    SheetCell.tsx             how each kind and variant draws
    MicroficheViewer.tsx      the lens: travel, dragging, keyboard, sound
    microfiche.css
public/microfiche/
  captures/                   generated by `npm run capture` — never edit by hand
  archive/                    hand-placed images and baked textures

Everything sits at a fixed coordinate on one sheet, 1 unit = 100px. The viewer moves a lens over it at a single fixed magnification; nothing zooms.

Adding a cell

  1. Put images in public/microfiche/archive/. Not captures/npm run capture deletes that folder. Flatten transparency first, or the film's black shows through: sips -s format jpeg x.png --out public/microfiche/archive/x.jpg

  2. Add a cell to sheetData.ts with an id, a kind, and x, y, w, h in units.

    kind is needs
    capture an image src, label
    plate drawn in code variant, usually title and lines
    clipping the description headline, body
    cover the index card nothing — built from the project record
  3. Two optional flags. project puts the cell in that cluster, so it brightens with that project and clicking it centres there; without it the cell is transitional filler between clusters. framed adds it to the block the lens centres on — keep a cluster's framed block under about 8 × 5.5 units or it will not fit the lens.

  4. Set fit: "contain" on diagrams. The default crops to fill, which is right for a screenshot and wrong for a figure.

  5. Run npm run check. Cells are hand-placed and an overlap raises no error, it just looks wrong. It catches overlaps, cells off the sheet, duplicate ids and missing images.

  6. If the content outgrows the sheet, change SHEET in sheetData.ts; the stylesheet follows it.

To add a new plate variant: add the name to PlateVariant, add a case to Plate in SheetCell.tsx wrapping the contents in <Body>, and style .fiche-<style> if it needs its own treatment. Several variants share one style, so a plain ruled list can reuse style="record" and need no CSS.

Don't change

npm run capture steps the parking chart back to the last month its collector populated (it stopped in April 2026) and waits a long time for the satellite globe to draw — don't shorten those.

The sheet is far too large to hold as one texture, so the browser rasterises it in tiles on demand. Anything painted across it costs frames while panning, which is why the mottling and grid are baked images rather than CSS gradients. Keep it that way.

About

My personal website

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages