Skip to content

The Editor

The Editor class is the runtime that ties everything together. It manages the ECS world, runs the tick loop, and coordinates plugins. When you use the WovenCanvas component, it creates an Editor instance internally.

Inside components rendered within WovenCanvas, use the useEditorContext composable:

import { useEditorContext } from "@woven-canvas/vue";
const { getEditor, nextEditorTick } = useEditorContext();
// Get the editor instance (may be null during initialization)
const editor = getEditor();
// Execute code in the next ECS tick
nextEditorTick((ctx) => {
// ctx is the ECS context for reading/writing data
});

You can also access the editor via the ready event:

<script setup lang="ts">
import { WovenCanvas, type Editor } from "@woven-canvas/vue";
function onReady(editor: Editor) {
console.log("Editor ready:", editor);
}
</script>
<template>
<WovenCanvas @ready="onReady" />
</template>

All state lives in the ECS. Use the context to read and write:

import { Block, Color } from "@woven-canvas/core";
nextEditorTick((ctx) => {
// Read component data (immutable)
const block = Block.read(ctx, entityId);
console.log("Position:", block.position);
// Write component data (mutable)
const color = Color.write(ctx, entityId);
color.red = 255;
color.green = 0;
color.blue = 0;
});

Changes made during a tick are automatically tracked for:

  • Undo/redo history
  • Network synchronization
  • Persistence

Vue composables provide reactive access to ECS data:

import { useComponent, useSingleton, useQuery } from "@woven-canvas/vue";
import { Block, Camera, Selected } from "@woven-canvas/core";
// Subscribe to a component on a specific entity
const block = useComponent(entityId, Block);
// Subscribe to a singleton (global state)
const camera = useSingleton(Camera);
// Subscribe to a query (multiple entities)
const selectedBlocks = useQuery([Block, Selected]);

These composables return Vue refs that update automatically when the underlying data changes.

Commands are the primary way to trigger actions from user input.

import { useEditorContext } from "@woven-canvas/vue";
import { Undo, DeselectAll } from "@woven-canvas/core";
const { nextEditorTick } = useEditorContext();
nextEditorTick((ctx) => {
// Undo the last action
Undo.spawn(ctx);
// Deselect all blocks
DeselectAll.spawn(ctx);
});

For convenience, you can also dispatch commands directly on the editor:

import { useEditorContext } from "@woven-canvas/vue";
import { Undo, DeselectAll } from "@woven-canvas/core";
const { getEditor } = useEditorContext();
const editor = getEditor();
editor?.command(Undo);
editor?.command(DeselectAll);

The editor accepts configuration via props on WovenCanvas:

<template>
<WovenCanvas
:editor="{
maxEntities: 10000,
grid: { enabled: true, colWidth: 20, rowHeight: 20 },
plugins: [MyPlugin],
}"
:plugin-options="{
controls: { minZoom: 0.1, maxZoom: 10 },
}"
/>
</template>

You can also disable built-in plugins by passing false:

<template>
<WovenCanvas
:plugin-options="{
pen: false,
eraser: false,
}"
/>
</template>

See the WovenCanvas API reference for all available props.