No description
Find a file
2026-01-13 18:43:23 -08:00
adapters all the slop thats fit to merge 2025-12-19 14:27:58 -08:00
auth jpeg keys, key retrieval, storage 2026-01-01 18:00:20 -08:00
controllers big refactor much more modular and full controls to edit special pictures 2025-12-29 17:30:17 -08:00
core add untagged filter to library page 2026-01-13 18:43:23 -08:00
editor huge performance improvements for exporting and scene loading 2025-12-29 21:37:18 -08:00
library add untagged filter to library page 2026-01-13 18:43:23 -08:00
.containerignore open containers 2025-12-16 11:56:41 -08:00
.gitignore sighs, infra in the repo 2025-12-16 16:58:30 -08:00
app.js new canvas from selected and finally a delet this button 2025-12-29 22:11:20 -08:00
function-registry.js midi cc support 2025-12-29 13:42:30 -08:00
index.html big refactor much more modular and full controls to edit special pictures 2025-12-29 17:30:17 -08:00
init-controls.js big refactor much more modular and full controls to edit special pictures 2025-12-29 17:30:17 -08:00
input-adapter.js first step starts with a single first step 2025-12-18 17:08:11 -08:00
key.html jpeg keys, key retrieval, storage 2026-01-01 18:00:20 -08:00
library.html high res exports 2026-01-09 13:08:45 -08:00
package-lock.json first step starts with a single first step 2025-12-18 17:08:11 -08:00
package.json first step starts with a single first step 2025-12-18 17:08:11 -08:00
README.md update readme and test push mirror 2025-12-29 14:28:20 -08:00
register-functions.js TIMELINE VIEW 2025-12-29 14:06:11 -08:00
register.html jpeg keys, key retrieval, storage 2026-01-01 18:00:20 -08:00
server.js jpeg keys, key retrieval, storage 2026-01-01 18:00:20 -08:00
storage.js jpeg keys, key retrieval, storage 2026-01-01 18:00:20 -08:00
styles.css first step starts with a single first step 2025-12-18 17:08:11 -08:00

pictures

A tool for composing images with blend modes, z-index manipulation, and keyboard controls. Drag images into the canvas, arrange them with gestures, apply blend modes, and export your compositions.

Architecture

Frontend

  • index.html - Main workspace interface
  • app.js - Core application logic, keyboard controls, image manipulation
  • styles.css - Minimal styling (no rounded corners, clean aesthetic)
  • library.html - Image management interface with editing capabilities

Backend

  • server.js - Express server serving static files and handling image operations
  • storage.js - Storage abstraction layer supporting local filesystem or S3-compatible storage
  • package.json - Node.js dependencies

Data Storage

  • localStorage - Browser-based storage for spaces and image paths
  • Storage backend - Supports local filesystem or S3-compatible storage (configured via environment variables)

Setup

  1. Install dependencies:

    npm install
    
  2. Configure storage backend (optional):

    • The app defaults to local storage
    • For S3 storage, set environment variables for your S3-compatible service
  3. Start the server:

    npm start
    
  4. Open http://localhost:3030 in your browser

Adding Images

Drag and Drop

Simply drag images from your file manager directly into the browser window. You can drag multiple images at once! They'll be automatically uploaded and available for use.

The app automatically loads available images on startup and whenever you refresh the page.

Usage

Workspace Controls

Image Loading

  • n - Load random collection of images (based on photo count set in space)

Image Manipulation

  • Click an image to focus it (black border appears)
  • Drag images to reposition them
  • Scroll on focused image - Scale image up/down from center
  • Shift + Scroll - Normal page scrolling (when canvas exceeds viewport)
  • Shift + + or Shift + = - Scale all images up by 10% (from their centers)
  • Shift + - or Shift + _ - Scale all images down by 10% (from their centers)
  • r - Randomize positions of all images

Blend Modes

  • b - Cycle blend mode on focused image
  • shift + b - Randomize blend modes for all images

Available blend modes: normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity

Export

  • e - Export workspace as PNG (preserves blend modes and z-index layering)

Timeline

  • t - Toggle timeline mode (navigate through state history)
  • Scroll (in timeline mode) - Navigate backward/forward through states
  • Arrow keys (in timeline mode) - Navigate backward/forward through states
  • Visual indicator shows current position (e.g., "TIMELINE 5/23")

The timeline automatically records state changes during your session. Press t to enter timeline mode, then use scroll or arrow keys to navigate through your composition history. The timeline preserves all image positions, sizes, blend modes, and z-index values.

Navigation

  • ← / → - Cycle through images (change focus)
  • Escape - Unfocus current image
  • Click outside workspace to unfocus

Image Management (library.html)

Access via the "library" link in the workspace or navigate directly to /library or library.html. This is the primary interface for managing your image collection.

Grid View

  • Instagram-style grid showing all images
  • Click any image to open in full-screen modal

Image Editing Modal

  • ✎ (pencil icon) - Toggle edit mode
    • When enabled: scroll to zoom, click+drag to pan, crop overlay appears
    • Crop handles on edges/corners for resizing
    • Drag crop area to reposition
  • × (close) - Close modal
  • save - Save edits (replaces original file with cropped/edited version)

Editing Features

  • Scroll - Zoom in/out (centers on cursor position)
  • Click + Drag - Pan around zoomed image
  • Crop Overlay - Drag edges/corners to resize, drag center to reposition
  • All edits are gesture-based (no sliders)

Technical Details

Image Storage

  • Supports local filesystem or S3-compatible storage backends
  • Image paths are cached in browser localStorage
  • Server provides /api/images endpoint to list all images
  • Server provides /api/upload endpoint for drag-and-drop uploads
  • Server provides /api/images/:filename PUT endpoint for updating images
  • Server provides /api/images/:filename DELETE endpoint for deletion
  • Thumbnails are automatically generated and stored alongside originals

Space Management

  • Spaces are stored in browser localStorage as JSON
  • Each space contains: id, name, width, height, photoCount, createdAt
  • Multiple spaces can be created and switched between

Export Functionality

  • Uses manual canvas compositing (not html2canvas) to preserve blend modes
  • Maps CSS blend modes to canvas globalCompositeOperation
  • Renders images in z-index order
  • Exports at exact workspace dimensions

Image Transformations

  • Images can be scaled, panned, and cropped
  • Transform state is maintained per image
  • Crop calculations account for zoom/pan transforms
  • Saved edits replace original files

File Structure

blender/
├── index.html          # Main workspace interface
├── library.html        # Image management interface
├── app.js              # Core application logic
├── styles.css          # Styling
├── server.js           # Express server
├── storage.js          # Storage abstraction (local/S3)
├── package.json        # Dependencies
└── README.md           # This file

Keyboard Shortcuts Summary

Command Palette

Key Action
? or / or Ctrl/Cmd + k Open command palette

Image Loading

Key Action
n Load random images (uses photo count from space settings)

Image Manipulation

Key Action
Click Focus an image (black border appears)
Drag Reposition focused image
Scroll (on focused image) Scale image up/down from center
Shift + Scroll Normal page scrolling (when canvas exceeds viewport)
Shift + + or Shift + = Scale all images up by 10% (from their centers)
Shift + - or Shift + _ Scale all images down by 10% (from their centers)
r Randomize positions of all images

Image Navigation

Key Action
/ Cycle through images (change focus)
Escape Unfocus current image
Click outside canvas Unfocus current image

Blend Modes

Key Action
b Cycle blend mode on focused image
Shift + b Randomize blend modes for all images

Available blend modes: normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity

Z-Index (Layering)

Key Action
Move focused image up on z-axis (bring forward)
Move focused image down on z-axis (send backward)
Shift + ↑ Randomize z-index for all images

Export

Key Action
e Export workspace as PNG (preserves blend modes and z-index layering)

Timeline

Key Action
t Toggle timeline mode (enter/exit state history navigation)
Scroll (in timeline mode) Navigate backward/forward through states
/ (in timeline mode) Navigate backward/forward through states
/ (in timeline mode) Navigate backward/forward through states

The timeline automatically records every state change during your session (image additions, deletions, position changes, blend mode changes, etc.). When you enter timeline mode, a visual indicator shows your current position in the timeline. Navigate through states to see how your composition evolved over time.

Control System Architecture

The app uses a modular control system that supports keyboard, MIDI, gamepad, and OSC inputs through a unified architecture:

InputAdapter (normalizes all inputs)
    ↓
ControlMapper (maps inputs → functions)
    ↓
FunctionRegistry (executes functions)

MIDI Control (Continuous & Discrete)

Continuous controls (CC knobs, gamepad axes, OSC faders) map to parameters, while discrete controls (notes, buttons, keys) map to functions.

Setup MIDI Mappings

  1. Open the Control Palette (? or / or Ctrl/Cmd + k)
  2. Switch to the Screensaver tab
  3. Click any "map" button next to:
    • Tempo (BPM) - Maps a MIDI CC knob to control playback speed
    • Play/Stop buttons - Maps MIDI notes to start/stop the screensaver
    • Function probability sliders - Maps MIDI CC knobs to control how often each function triggers

Mapping Process

  1. Click a "map" button - it will pulse red and show "learning..."
  2. For CC mappings: Move the MIDI knob/fader you want to assign
  3. For Note mappings: Press the MIDI note/pad you want to assign
  4. The mapping is saved automatically to localStorage

Features

  • Universal - Works with any MIDI controller
  • Live updates - CC changes update parameters in real-time
  • Visual feedback - See all current mappings at the bottom of the Screensaver tab
  • Automatic scaling - CC values (0-127) automatically scale to parameter ranges
    • Tempo: 40-240 BPM
    • Probability: 0-100%
  • Extensible - Easy to add new parameter mappings for any feature

How It Works

MIDI CC events flow through InputAdapterControlMapper (with value scaling) → FunctionRegistry (with scaled parameter). This means any continuous control (not just MIDI) can map to any parameter, making the system highly modular and reusable.

The screensaver runs on a tempo-based clock and probabilistically triggers functions on each tick. With MIDI control, you can:

  • Adjust tempo in real-time for faster/slower chaos
  • Control individual function probabilities to shape the behavior
  • Start/stop the screensaver with notes/pads instead of clicking buttons

Future Enhancements

  • Multiplayer support with shared cursors and workspaces
  • Real-time collaboration
  • More advanced image editing tools
  • OSC support
  • Video & text
  • Export formats beyond PNG