Files
jsoncanvas-desktop/README.md
T
2026-09-09 21:19:44 +02:00

121 lines
5.1 KiB
Markdown

# JSON Canvas Editor
A native desktop editor for the [JSON Canvas](https://jsoncanvas.org) 1.0 file
format, written in Rust. It runs on Windows and Linux from a single binary and
reads and writes plain `.canvas` files on the local disk — there is no server,
no account and no hidden state.
![The editor with a canvas open](docs/screenshot.png)
## What it does
**The whole spec.** All four node types (`text`, `file`, `link`, `group`) and
every edge attribute (`fromSide`/`toSide`, `fromEnd`/`toEnd`, `label`, `color`),
plus both `canvasColor` forms — the six presets and `#rrggbb` hex.
**It does not damage files it does not fully understand.** Unknown top-level
keys, unknown node/edge attributes and even unknown node `type`s are carried
through a load/save cycle untouched, and attributes are written back in the
order the spec lists them, so a save produces a small diff rather than a
reshuffle.
**Direct manipulation.**
| Gesture | Result |
| --- | --- |
| Double-click empty canvas | New text note, ready to type in |
| Double-click a note | Edit its Markdown in place |
| Double-click a file/link node | Open it with the system default application |
| Drag a dot on a node's edge | Draw a connection; drop it on empty canvas to create the node too |
| Drag a corner or side handle | Resize |
| Drag a group | Moves the group and everything inside it |
| Drag on empty canvas | Rubber-band selection (hold <kbd>Shift</kbd> to add) |
| Middle- or right-drag | Pan |
| <kbd>Ctrl</kbd>+wheel | Zoom around the pointer |
**Markdown in text nodes**: headings, bold/italic/strikethrough, inline and
fenced code, quotes, bullet, numbered and task lists, rules, images and links.
Links are clickable; a link to another `.canvas` file opens it in the editor.
**File node previews**: images are rendered inline, text files are previewed as
Markdown, and a `subpath` such as `#Design` shows just that section of the file.
Group `background` images are drawn with the fitting their `backgroundStyle`
asks for (`cover`, `ratio` or `repeat`). Paths are stored relative to the
canvas, so a canvas plus its files stays portable.
**The usual editor comforts**: undo/redo of every change, copy/paste/duplicate,
grouping, alignment, z-order, a properties inspector, snap-to-grid, light and
dark themes, and a warning before you lose unsaved work.
## Building and running
```sh
cargo run --release # start with an empty canvas
cargo run --release -- board.canvas
```
The release binary is self-contained:
```sh
cargo build --release # target/release/jsoncanvas-desktop[.exe]
```
* **Windows** — nothing beyond a Rust toolchain (MSVC or GNU).
* **Linux** — the usual desktop development packages for windowing and
rendering, e.g. on Debian/Ubuntu:
```sh
sudo apt install build-essential pkg-config libx11-dev libxcursor-dev \
libxrandr-dev libxi-dev libgl1-mesa-dev libwayland-dev libxkbcommon-dev
```
File dialogs use the XDG desktop portal, so no GTK development packages are
needed; install `xdg-desktop-portal` and a backend for your desktop if it is
not already present.
Run the tests with `cargo test` (the model, geometry, Markdown and editing logic
are covered headless — no display required).
## Keyboard shortcuts
| | |
| --- | --- |
| <kbd>Ctrl</kbd>+<kbd>N</kbd> / <kbd>O</kbd> / <kbd>S</kbd> | New, open, save |
| <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>S</kbd> | Save as |
| <kbd>Ctrl</kbd>+<kbd>Z</kbd> / <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd> | Undo, redo |
| <kbd>Ctrl</kbd>+<kbd>C</kbd> / <kbd>V</kbd> / <kbd>D</kbd> | Copy, paste, duplicate |
| <kbd>Ctrl</kbd>+<kbd>A</kbd> | Select everything |
| <kbd>Ctrl</kbd>+<kbd>G</kbd> | Put the selection in a group |
| <kbd>Ctrl</kbd>+<kbd>I</kbd> | Show or hide the inspector |
| <kbd>Delete</kbd> | Delete the selection |
| <kbd>F2</kbd> | Edit the selected node |
| <kbd>F</kbd> | Zoom to the selection |
| <kbd>Escape</kbd> | Stop editing, clear the selection |
| Arrow keys | Nudge by 1 (<kbd>Shift</kbd>: 10) |
| <kbd>Ctrl</kbd>+<kbd>0</kbd> / <kbd>1</kbd> | Zoom to fit, actual size |
## How it is put together
The UI toolkit is [egui](https://github.com/emilk/egui) via `eframe`. An
infinite canvas is essentially one large custom-painted widget, which is what
immediate-mode GUI is good at, and it builds to a single binary on both targets
without a GTK or Qt runtime. Pan and zoom are a transform on a dedicated egui
layer, so real widgets (the in-place Markdown editor, links) keep working while
the canvas is scaled.
| Module | Responsibility |
| --- | --- |
| `model.rs` | The file format: parsing, writing, round-trip fidelity |
| `document.rs` | Open document: path, dirty state, undo history |
| `geometry.rs` | Node boxes, edge anchors, Bézier routing, hit testing |
| `view.rs` | The canvas: painting, selection, and every gesture |
| `nodes.rs` | Node bodies: Markdown, file previews, links |
| `markdown.rs` | The Markdown subset used by text nodes |
| `inspector.rs` | The properties panel |
| `theme.rs` | Palettes and the six preset colours |
| `app.rs` | Menus, toolbar, dialogs, file handling, shortcuts |
## Licence
MIT.