Skip to content

Repository files navigation

Tack

An open-source PureRef for the browser. An infinite wall you drop images on, arrange, crop, rotate, pack tight, annotate, and keep. Nothing leaves your computer: boards live in the browser's IndexedDB, the app works offline once it has loaded, and there is no account and no server.

Live: https://projects.patrickreinbold.com/tack/ — installable as a PWA. Source: https://github.com/st-patrick/tack — MIT. Landing page: landing.html. Support: if Tack saved you a licence fee, you can put something back.

Tack with a packed board

What it does

  • Images in by drag and drop (from the desktop or another browser tab), by paste (a screenshot on the clipboard, an image URL, or plain text becomes a note), or through the file picker. Original bytes are kept — nothing is re-encoded.
  • Arrange: move with edge/centre snapping to neighbours, scale about the opposite corner (or the centre with Alt), rotate with a knob (Shift snaps to 15°), crop by dragging edges, flip, greyscale, opacity, z-order, duplicate, nudge with the arrow keys. Multi-select by marquee or Shift-click; group scale and rotate.
  • Pack (Ctrl P) tidies everything — or the selection — into a tight rectangle shaped like your window; Ctrl Shift P first normalises heights.
  • Notes: double-click empty space, type. They wrap, scale and rotate like images.
  • Boards: any number of them, switch from the toolbar. A board can be saved as one .tack file with the images inside, and opened again anywhere. Export the board or a selection as a PNG at full resolution.
  • Undo/redo for everything, autosave 400 ms after the last change, and on tab switch.
  • Light and dark, keyboard-first, touch pinch/pan on tablets.

Run it

It is static files. Serve the folder with anything:

npx serve .          # or python -m http.server, or open index.html over http

There is no build step and no dependency. The source is ES modules:

src/scene.js    the board: items, camera, selection, undo (pure data)
src/render.js   canvas drawing, handle geometry, PNG export
src/input.js    pointer + keyboard gestures, snapping, pinch
src/store.js    IndexedDB (boards + original image blobs)
src/images.js   decode cache with a ≤1024px mip for zoomed-out drawing
src/pack.js     shelf packing ("Optimize")
src/files.js    drops, pastes, URLs, .tack export/import
src/app.js      wiring: boards, autosave, menus, note editing
sw.js           offline shell cache

Test

test/walk.mjs drives the app in headless Chromium: drops synthetic images, packs, drags, scales, rotates, crops, flips, marquee-selects, group scales, writes a note, reloads to check persistence, saves and reopens a .tack file, exports a PNG, toggles theme, and checks that nothing logged an error. Playwright is the only (dev) dependency, and it lives in test/ so the app itself stays dependency-free.

cd test && npm install
npm run serve      # serves the repo root on :8460
npm run walk       # in a second terminal; screenshots land in test/shots/

File format

.tack is JSON: { app: "tack", v: 1, name, cam, items[], blobs{ id: dataURL } }. Item fields: kind (image|note), x y (centre, world px), scale, rot (radians), flipX flipY gray opacity z, crop {l t r b} as fractions of the natural size, nw nh natural pixels, blobId; notes carry text w.

Licence

MIT.

About

An open-source PureRef for the browser: an infinite wall for reference images. No account, no upload, works offline.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages