| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A browser-based tool for generating framed photo layouts for social media. Stage as many photos as you want, pick a template, select which images to use, see a live preview, and download a full-resolution PNG.
Live site: https://brooksilg.github.io/frames/
Serve the project directory over HTTP (required for fetch to load templates):
cd frames
python3 -m http.server 8080Open http://localhost:8080 in your browser.
frames/ ├── index.html # HTML shell — two-panel layout, links CSS and JS ├── templates.json # Template definitions (edit this to add layouts) ├── src/ │ ├── styles.css # All styling (responsive, masonry thumbnails) │ └── app.js # Application logic (staging, selection, rendering, persistence) └── README.md
Two-panel layout: left panel (1/3 width on desktop) has the drop zone and thumbnail gallery; right panel (2/3 width) has the template selector, status bar, and canvas preview. Falls back to single-column on mobile (<900px).
Dark-themed UI with:
All application logic:
| Section | Responsibility |
|---|---|
| State | templates[], stagedImages[], selectedIds[], currentTemplate |
| IndexedDB | openDB(), saveImageToDB(), deleteImageFromDB(), clearImagesDB(), loadAllImagesFromDB() — persists image blobs |
| localStorage | Saves/restores template index, selected IDs, staging order, next ID counter |
| Template loading | Fetches templates.json, populates dropdown, then calls restoreState() |
| File handling | Drag-and-drop and file input; stages unlimited images |
| Selection logic | toggleSelect() — manages slot assignment with replace-last-slot behavior |
| Thumbnails | Masonry grid with selection badges, hover × buttons, clear-all |
| Rendering | Builds slot array (real images + placeholders), validates, draws onto canvas |
| Resize helpers | resizeToLargestSide() and fitInBox() compute scaled dimensions |
| Draw helpers | drawSlot() — draws either an image or a grey placeholder rectangle |
| Single image | Centers one resized image on the canvas, with optional border |
| Diptych | Side-by-side or stacked layout for 2 images, with equal spacing |
| Download | Exports the canvas as a PNG blob and triggers a browser download |
An array of template objects. Each template defines:
| Template | Images | Canvas | Notes |
|---|---|---|---|
| White Frame — Any Ratio | 1 any | auto | 2.5% padding from longest side |
| White Frame + Black Border — Any Ratio | 1 any | auto | 2.5% padding + 10px black border |
| White Frame — Vertical 4×5 | 1 portrait | 3200×4000 | |
| White Frame — Horizontal 5×4 | 1 landscape | 4000×3200 | |
| White Frame + Black Border — Vertical 4×5 | 1 portrait | 3200×4000 | 10px black border |
| White Frame + Black Border — Horizontal 5×4 | 1 landscape | 4000×3200 | 10px black border |
| White Frame — Diptych Vertical 4×5 | 2 | 3200×4000 | Stacked |
| Square White Frame — 1×1 | 1 any | 4000×4000 | |
| Square White Frame + Black Border — 1×1 | 1 any | 4000×4000 | 10px black border |
Edit templates.json and add a new object to the array. Reload the browser — no build step needed.
| Back | FazBrowse Home | New Git URL |
{ "name": "Display name", "imageCount": 1, // 1 or 2 "orientation": "vertical", // "vertical", "horizontal", or "any" "canvas": { "width": 3200, "height": 4000 }, "background": "#ffffff", // any CSS color // For auto-canvas templates (padding-based, any aspect ratio): "canvasMode": "auto", // canvas sized from image + padding "paddingPercent": 2.5, // padding = 2.5% of longest side, applied equally on all sides // For fixed-canvas single-image templates: "canvas": { "width": 3200, "height": 4000 }, "images": [ { "resizeLargestSide": 3800, // scale so the largest dimension equals this "border": { // optional, omit or null for no border "width": 10, "color": "#000000" }, "position": "center" } ], // For 2-image (diptych) templates, add: "layout": "stacked", // "side-by-side" or "stacked" "gap": 40, // px gap between images "images": [ { "resizeTo": "fit", "maxWidth": 3000, "maxHeight": 1940, "position": "center-top" }, { "resizeTo": "fit", "maxWidth": 3000, "maxHeight": 1940, "position": "center-bottom" } ] }