Skip to main content
Version: 0.x.x

Installation

@canvas-tile-engine/react provides a React component, a stable engine hook, and declarative draw components.

Install

Canvas2D:

npm install @canvas-tile-engine/core @canvas-tile-engine/react @canvas-tile-engine/renderer-canvas

WebGL:

npm install @canvas-tile-engine/core @canvas-tile-engine/react @canvas-tile-engine/renderer-webgl

Basic Setup

import { CanvasTileEngine, useCanvasTileEngine } from "@canvas-tile-engine/react";
import { RendererCanvas } from "@canvas-tile-engine/renderer-canvas";

const tiles = [
{ x: 0, y: 0, size: 1, style: { fillStyle: "#22c55e" } },
{ x: 1, y: 0, size: 1, style: { fillStyle: "#38bdf8" } },
];

export function App() {
const engine = useCanvasTileEngine();

return (
<CanvasTileEngine
engine={engine}
renderer={new RendererCanvas()}
config={{
scale: 48,
size: { width: 800, height: 500 },
backgroundColor: "#0f172a",
eventHandlers: { drag: true, zoom: true, click: true },
}}
center={{ x: 0, y: 0 }}
onClick={(coords) => console.log(coords.snapped)}
>
<CanvasTileEngine.GridLines cellSize={1} strokeStyle="#1e293b" layer={0} />
<CanvasTileEngine.Rect items={tiles} layer={1} />
</CanvasTileEngine>
);
}

Renderer Choice

Switch to WebGL by changing the renderer:

import { RendererWebGL } from "@canvas-tile-engine/renderer-webgl";

<CanvasTileEngine engine={engine} config={config} renderer={new RendererWebGL()} />;

config, center, and renderer are read when the component mounts. Later prop changes are intentionally ignored. Use runtime APIs for live updates:

engine.setBounds({ minX: 0, maxX: 100, minY: 0, maxY: 100 });
engine.setEventHandlers({ drag: false, hover: true });
engine.setCenter({ x: 10, y: 10 });
engine.goCenter(0, 0, 500);
engine.setScale(64);
engine.goScale(64, 500);
engine.setScaleLimits(16, 256);

Remount with a new key when you need to apply a new full config or renderer.

useCanvasTileEngine

const engine = useCanvasTileEngine();

The hook returns a stable handle. Methods are safe before mount: they no-op or return defaults. Use engine.isReady when you need the real core instance or image loader.

PropertyDescription
isReadytrue after the core engine has mounted.
instanceThe underlying core CanvasTileEngine instance, or null.
imagesRenderer image loader, available after mount.

Common methods:

engine.render();
engine.getCenter();
engine.getVisibleBounds();
engine.goCenter(10, 10, 500);
engine.resize(1024, 768, 300);
engine.zoomIn();
engine.zoomOut();
engine.loadImage("/sprite.png");
engine.clearLayer(2);
engine.clearAll();

Component Props

PropTypeDescription
engineEngineHandleRequired handle from useCanvasTileEngine().
rendererIRendererRequired renderer instance.
configCanvasTileEngineConfigRequired initial config.
center{ x, y }Optional initial center. Defaults to { x: 0, y: 0 }.
classNamestringWrapper div class.
styleReact.CSSPropertiesWrapper div style.
childrenReactNodeDraw components.
onCoordsChange(coords) => voidCamera center callback.
onClick / onRightClick / onHoverPointer callbacksReceive world, canvas, and client coordinate objects.
onMouseDown / onMouseUp / onMouseLeavePointer callbacksUseful for drawing tools and mode state.
onDrawonDrawCallbackRuns after engine layers. Context depends on renderer.
onResize() => voidResize callback.
onZoom(scale) => voidZoom callback.

Declarative And Imperative Drawing

Declarative:

<CanvasTileEngine engine={engine} config={config} renderer={new RendererCanvas()}>
<CanvasTileEngine.GridLines cellSize={1} />
<CanvasTileEngine.Rect items={rects} layer={1} />
<CanvasTileEngine.Circle items={markers} layer={2} />
</CanvasTileEngine>

Imperative:

useEffect(() => {
if (!engine.isReady) return;

engine.drawGridLines(1, 1, "#334155", 0);
engine.drawRect(rects, 1);
engine.render();
}, [engine, engine.isReady, rects]);
note

If you remount the component with a key (for example to swap renderer or config), depend on engine.instance instead of engine.isReady. During a remount isReady returns to true within the same effect flush, so effects keyed on it do not re-run, while engine.instance changes identity with every new engine. Draw calls made while no engine is mounted are dropped and log a dev-only console warning.

For declarative draw components, keep large items arrays stable with useMemo or state. A new array identity re-registers the draw callback and can rebuild spatial indexes.