ouija board1
jeeboard docs getting-started.md
3.6 kB
Markdown
at main


title: Getting started with jeeboard description: Shows how to install the jeeboard packages and wire a minimal editor with a canvas renderer. #

Getting started #

This guide builds a minimal editor. The editor shows one rectangle on an infinite canvas. It has no tools and no persistence. Later sections link to the packages that add these features.

Install #

Install the packages for the minimal editor:

pnpm add @jeeboard/core @jeeboard/dom @jeeboard/renderer-canvas2d
  • @jeeboard/core holds the elements and the change history.
  • @jeeboard/dom marks the host element for the editor.
  • @jeeboard/renderer-canvas2d draws the elements.

Prepare the page #

Add a host element and a canvas to your HTML:

<div id="editor">
  <canvas id="board"></canvas>
</div>

Give the canvas a size with CSS. The renderer reads the CSS size when you call resize.

Create the editor core #

The editor core holds all elements. Create it and add one element in a transaction:

import { createEditorCore, elementId } from "@jeeboard/core";

const core = createEditorCore();

core.transact("create rectangle", (tx) =>
  tx.create({
    id: elementId("rectangle-1"),
    type: "shape",
    bounds: { x: 0, y: 0, width: 160, height: 100 },
    properties: { shape: "rectangle" },
  })
);

Each transaction that mutates elements becomes one undo step. See @jeeboard/core for the full data model.

Create the renderer #

Create the renderer on the canvas element:

import {
  createCanvas2DRenderer,
  type Camera,
} from "@jeeboard/renderer-canvas2d";

const canvas = document.querySelector<HTMLCanvasElement>("#board")!;
const renderer = createCanvas2DRenderer(canvas, { background: "#ffffff" });

const camera: Camera = { center: { x: 80, y: 50 }, zoom: 1 };

renderer.resize(canvas.clientWidth, canvas.clientHeight, window.devicePixelRatio);

The camera has a center point in world coordinates and a zoom factor. The zoom must be finite and positive.

Mark the host element #

Attach the editor core to the host element:

import { createEditorHost } from "@jeeboard/dom";

const editorHost = createEditorHost(document.getElementById("editor")!);
editorHost.attach(core);

The attach method sets the data-jeeboard-editor attribute and an aria label. See @jeeboard/dom for text portals and the accessibility mirror.

Render frames #

Render one frame now. Render a new frame each time the core changes:

function renderFrame(): void {
  renderer.present({
    camera,
    visibleElements: core.list(),
  });
}

renderFrame();
core.subscribe(() => renderFrame());

NOTE: core.list() returns all elements. For large boards, query only the visible elements with the spatial index from @jeeboard/scene.

Check renderer.diagnostics().pendingTileCount after present. Request another animation frame when the count is greater than zero. The renderer then rasterizes the remaining tiles.

Next steps #

Add the features that your editor needs:

  1. Add @jeeboard/scene for fast viewport queries and hit tests.
  2. Add @jeeboard/ink for freehand strokes.
  3. Add @jeeboard/text-prosemirror for rich-text editing.
  4. Add @jeeboard/storage for local persistence.
  5. Add @jeeboard/automerge for CRDT sync and collaboration.

The playground is a complete application that composes all packages. Use it as the reference for a full integration.