Fujimod
Try your camera firmware in the browser and build Fujimod SD boot files.
Design a picture frame by its dimensions and get the cut list, joinery details and stock layout for nine traditional frame joints.
LifestyleJavaScript · HTMLGitHub @dvsiiOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Picture frame cut lists, joinery details, a 3D joint model and stock layouts for nine corner joints. Installable offline web app.
Taken from the repository README
Loading the full README.
Read the full README ↗Use it here: https://dvsii.github.io/frame-designer/ (open it on your phone and add it to the home screen to install it; see Install on a phone). There's also a native iPhone app built from the same files.
A lightweight web app for making picture frames. Enter the sizes you know on a drawing of the frame (artwork, outside size, rail and stile widths, in any combination) and it works out the rest, then gives you:
It runs entirely in the browser: plain HTML and JavaScript, no build step, no server, no dependencies (the fonts are bundled in fonts/). It installs to a phone's home screen as an app and works offline.
| Joint | What runs full length | Rail length (stiles through) |
|---|---|---|
| Miter (glue, V-nails or biscuits) | everything, measured on the long point | outside width |
| Miter w/ spline (triangular splines across each corner) | everything, measured on the long point | outside width |
| Half-lap | everything | outside width |
| Mitered half-lap | everything | outside width |
| Bridle (open mortise) | everything | outside width |
| Mortise & tenon | stiles (or rails) | outside − 2 × stile + 2 × tenon |
| Tongue & groove (stub tenon) | stiles (or rails) | outside − 2 × stile + 2 × groove depth |
| Cope & stick | stiles (or rails) | outside − 2 × stile + 2 × cope depth |
| Butt (dowels, biscuits, pocket screws, Domino) | stiles (or rails) | outside − 2 × stile |
Miters handle unequal widths (for example a wider bottom rail): the miter line runs corner to corner and the saw angle for each end is atan(width of the mating piece / width of this piece), so the two angles at a corner always add up to 90°.
Under Stock and cutting, choose what the pieces are cut from:
With Suggest the boards to buy on, the stock layout shows the mix of standard boards (1×2 to 1×12 at ¾″, or 5/4 and 2× for thicker frames; 18–44 mm metric) of the length you set that holds every piece with the least wood. It also lists single-size alternatives. The search is exact for the usual three strip widths (stiles, top and bottom rails) and falls back to a greedy fill for very large batches.
glass (= artwork, or mat outer size)
rabbet opening = glass + fit allowance
sight opening = rabbet opening − 2 × rabbet width
outside = sight opening + left + right stile (width)
= sight opening + top + bottom rail (height)
"Calculate" picks which of the three (outside size, artwork size, or widths) is worked out from the other two. Editing a calculated value in the drawing switches what's calculated, so any combination works. With a mat, the artwork size is the image: glass = image − 2 × overlap + borders.
Any static file server works. From this folder:
python3 -m http.server 8000
Then open http://localhost:8000. Opening index.html straight from disk also works, apart from offline install.
dist/frame-designer.html is the whole app in a single file (build it with python3 scripts/build_single.py), handy for e-mailing or keeping on a USB stick in the shop. It loads its fonts from Google Fonts and falls back to system fonts offline.
Upload the folder (or just index.html, manifest.webmanifest, sw.js, js/, icons/ and fonts/) to any static host: GitHub Pages, Netlify, Cloudflare Pages, or your own server. It must be served over HTTPS for the install and offline features.
GitHub Pages, for example:
git init && git add . && git commit -m "Frame Designer"
gh repo create frame-designer --public --source . --push
gh api repos/{owner}/frame-designer/pages -X POST -f "source[branch]=main" -f "source[path]=/"
After the first visit it opens offline.
ios/ is a native iPhone (and iPad) app made with Capacitor: a native shell with a web view that loads these same files from inside the app, so it works with no connection at all. In the app, the cut list's Share button opens the iPhone share sheet (Copy, Mail, Messages, Notes, Save to Files…) in place of Copy as text and Print, and saved designs live in the app's own storage, which iOS doesn't clear. The repo root stays the GitHub Pages site; npm run sync copies the web files into www/ and from there into the Xcode project.
You need Xcode (free from the Mac App Store) and Node. Once:
brew install node
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
npm install
Then, after every change to the web files:
npm run sync
npm run ios does the same and opens the project in Xcode. To try it in the Simulator, pick an iPhone from the device menu at the top of the Xcode window and press Run (⌘R).
A free Apple ID is enough for this.
npm run ios. In the project navigator click App, then the App target, then Signing & Capabilities. Leave Automatically manage signing on and set Team to your name (Personal Team). If Xcode says the bundle identifier com.dvsii.framedesigner isn't available, change it here and in capacitor.config.json to something of your own, such as com.yourname.framedesigner.With a free Apple ID the app stops opening after 7 days, and a free account can have only three such apps on a phone at once. Plug the phone in and press Run again to renew it for another 7 days; your saved designs are kept. After the first install, Xcode can also install over Wi-Fi when the phone is on the same network.
These need the Apple Developer Program ($99 a year). It also stops the 7-day expiry.
framedesigner).What the review asks for:
Info.plist declares that the app uses no non-exempt encryption, so uploads don't ask.Start the local server and open http://localhost:8000/tests/ — the page runs about 150 checks on the sizing math, every joint's cut list, the stock layout and the 3D geometry (including exact volume checks that each joint's pieces fill the frame with no gaps or overlaps), then renders every joint for a visual check. The tab title reads PASS n or FAIL n.
index.html page, styles and markup
privacy.html privacy policy (the App Store's privacy policy URL)
support.html support page (the App Store's support URL)
js/core.js sizes, joints, cut list, materials, steps, stock layout (no DOM; testable)
js/geom.js convex solids, plane clipping, the 3D frame model for each joint
js/render.js small z-buffer renderer with wood grain and outlines
js/app.js UI wiring: drawing, editor, inspector, results, saved designs
sw.js offline cache for the installed app
manifest.webmanifest install metadata
icons/ app icons (regenerate with scripts/make_icons.py, which also writes the iPhone app icon)
fonts/ Barlow, Barlow Semi Condensed and IBM Plex Mono, with their licences (scripts/fetch_fonts.py)
scripts/ icon, font and single-file builders, and copy_www.mjs for the iPhone app
tests/index.html browser test page
package.json Capacitor and the iPhone app's npm scripts
capacitor.config.json app id and name for the iPhone app
ios/ the Xcode project (www/ and node_modules/ are generated and not committed)
Saved designs and your last design are kept in the browser's local storage on that device only (in the iPhone app, in the app's own storage). The web app and the iPhone app don't share them.