Core Plugin
The Core plugin provides the foundational systems that power Woven Canvas. It handles input processing, block intersection detection, cursor management, selection, transform, and includes built-in block types like sticky notes, text, images, shapes, and frames.
Overview
Section titled “Overview”The Core plugin is always included automatically and cannot be disabled. It provides:
- Input handling — Keyboard, mouse, pointer, and screen events
- Selection — Single, multi-select, marquee selection
- Transform — Scale, stretch, rotate handles
- Block systems — Intersection detection, z-ordering, visibility culling
- Cursor management — Visual cursor state
- Keybind processing — Converts key presses to commands
- Edge scrolling — Auto-scroll when dragging near viewport edges
- Frame containment — Group blocks within frame containers
- Built-in block types — Sticky notes, text, images, shapes, and frames
Options
Section titled “Options”Configure the core plugin via the corePlugin editor option:
const editor = new Editor(el, { corePlugin: { edgeScrolling: { enabled: true, edgeSizePx: 20, edgeScrollSpeedPxPerFrame: 10, edgeScrollDelayMs: 100, } }})Edge Scrolling
Section titled “Edge Scrolling”Auto-scrolls the camera when dragging near viewport edges.
| Option | Type | Default | Description |
|---|---|---|---|
edgeScrolling.enabled | boolean | true | Enable auto-scroll when dragging near viewport edges |
edgeScrolling.edgeSizePx | number | 10 | Size of the edge zone in pixels |
edgeScrolling.edgeScrollSpeedPxPerFrame | number | 15 | Camera scroll speed in pixels per frame |
edgeScrolling.edgeScrollDelayMs | number | 250 | Delay before scrolling starts in milliseconds |
Built-in Block Types
Section titled “Built-in Block Types”Sticky Note
Section titled “Sticky Note”A colored note block with editable text and vertical alignment.
{ tag: 'sticky-note', components: [Color, Text, VerticalAlign], editOptions: { canEdit: true }}A text-only block that auto-sizes and can be removed when empty.
{ tag: 'text', components: [Text], resizeMode: ResizeMode.Text, editOptions: { canEdit: true, removeWhenTextEmpty: true }}An image block with asset loading support. The resizeMode can be overridden per-block to allow unlocking aspect ratio.
{ tag: 'image', components: [Image, Asset], resizeMode: ResizeMode.Scale}A geometric shape with optional text content.
{ tag: 'shape', components: [Shape, Text, VerticalAlign], resizeMode: ResizeMode.Free, editOptions: { canEdit: true }}A container that groups blocks. Blocks dragged into a frame become children.
{ tag: 'frame', components: [Frame], resizeMode: ResizeMode.Free, canRotate: false, connectors: { enabled: false }}Keyboard Shortcuts
Section titled “Keyboard Shortcuts”| Shortcut | Action |
|---|---|
Ctrl/Cmd + A | Select all blocks |
Delete | Remove selected blocks |
] | Bring selected forward (z-order) |
[ | Send selected backward (z-order) |
Commands
Section titled “Commands”Commands can be dispatched programmatically via editor.command():
Selection Commands
Section titled “Selection Commands”import { SelectBlock, DeselectBlock, DeselectAll, SelectAll, ToggleSelect,} from '@woven-canvas/core'
// Select a specific blockeditor.command(SelectBlock, { entityId, deselectOthers: true })
// Deselect all blockseditor.command(DeselectAll)
// Select all blockseditor.command(SelectAll)Block Manipulation Commands
Section titled “Block Manipulation Commands”import { RemoveSelected, DuplicateSelected, BringForwardSelected, SendBackwardSelected,} from '@woven-canvas/core'
// Delete all selected blockseditor.command(RemoveSelected)
// Duplicate selected blockseditor.command(DuplicateSelected)
// Change z-ordereditor.command(BringForwardSelected)editor.command(SendBackwardSelected)Components
Section titled “Components”Spatial Components
Section titled “Spatial Components”| Component | Description |
|---|---|
Block | Core block data (position, size, rotation, stratum, rank) |
Aabb | Axis-aligned bounding box for collision detection |
HitGeometry | Hit detection geometry (arcs, capsules) |
ScaleWithZoom | Marks entities that scale with camera zoom |
Content Components
Section titled “Content Components”| Component | Description |
|---|---|
Text | Text content and styling |
Color | Color values (hue, saturation, lightness) |
Shape | Shape type and stroke configuration |
Image | Image dimensions and source |
Asset | Asset upload state and URL |
VerticalAlign | Vertical text alignment |
Opacity | Entity opacity |
State Components
Section titled “State Components”| Component | Description |
|---|---|
Hovered | Marks an entity as hovered |
Held | Marks an entity as held/pressed |
Edited | Marks an entity as being edited |
Connector | Arrow connection point data |
Pointer | Pointer input state with sample history |
User | User presence information |
Selection Components
Section titled “Selection Components”| Component | Description |
|---|---|
Selected | Marks an entity as selected |
DragStart | Tracks drag initiation position |
EditAfterPlacing | Triggers edit mode after block creation |
SelectionBox | Marquee selection rectangle |
TransformBox | Transform box container |
TransformHandle | Corner, edge, and rotation handles |
Frame Components
Section titled “Frame Components”| Component | Description |
|---|---|
Frame | Frame container data (label) |
FrameDropTarget | Marks a frame as a drop target during drag |
Using Components
Section titled “Using Components”import { defineQuery, Block, Selected } from '@woven-canvas/core'
// Query for selected blocksconst selectedBlocks = defineQuery((q) => q.with(Block, Selected))
// In a systemfor (const entityId of selectedBlocks.current(ctx)) { const block = Block.read(ctx, entityId) console.log(block.position)}Singletons
Section titled “Singletons”Singleton components store global editor state (one instance per world):
| Singleton | Description |
|---|---|
Camera | Viewport position and zoom level |
Screen | Screen dimensions and device pixel ratio |
Cursor | Current cursor style |
Tick | Tick timing and delta time |
Keyboard | Keyboard state bitmask |
Mouse | Mouse position and button state |
Controls | Active tool and control mode |
Grid | Grid snapping configuration |
Intersect | Block intersection results |
RankBounds | Min/max block z-order values |
ScaleWithZoomState | Zoom-based scaling state |
SelectionStateSingleton | Selection state machine state |
TransformBoxStateSingleton | Transform box state machine state |
ScrollEdgesStateSingleton | Edge scrolling state machine state |
FrameDrawState | Frame drawing state machine state |
FrameContainmentState | Frame containment state machine state |
Accessing Singletons
Section titled “Accessing Singletons”import { defineEditorSystem } from '@woven-canvas/core'import { Camera, Mouse } from '@woven-canvas/core'
const mySystem = defineEditorSystem({ phase: 'update' }, (ctx) => { const camera = Camera.read(ctx) const mouse = Mouse.read(ctx)
console.log(`Camera at (${camera.x}, ${camera.y}), zoom: ${camera.zoom}`) console.log(`Mouse at (${mouse.x}, ${mouse.y})`)})Systems
Section titled “Systems”The Core plugin runs these systems automatically:
Input Phase
Section titled “Input Phase”| System | Description |
|---|---|
frameSystem | Updates frame timing and delta time |
rankBoundsSystem | Computes min/max block z-order |
keyboardSystem | Processes keyboard events |
mouseSystem | Processes mouse events |
screenSystem | Monitors screen/viewport changes |
pointerSystem | Processes pointer events with pressure |
Capture Phase
Section titled “Capture Phase”| System | Description |
|---|---|
intersectSystem | Detects which block is under the pointer |
selectSystem | Runs the selection state machine (click, drag, marquee) |
keybindSystem | Matches key presses to registered keybinds |
hoverCursorSystem | Sets cursor when hovering transform handles |
scrollEdgesSystem | Auto-scrolls when dragging near viewport edges |
captureTransformBoxSystem | Manages transform box lifecycle |
captureFrameContainmentSystem | Tracks frame containment during drag |
captureFrameDrawSystem | Handles frame drawing interactions |
Update Phase
Section titled “Update Phase”| System | Description |
|---|---|
blockSystem | Handles block manipulation commands |
dragHandlerSystem | Updates blocks when transform box moves |
updateSelectSystem | Handles selection box commands |
updateFrameDrawSystem | Processes frame draw commands |
updateFrameContainmentSystem | Processes frame containment commands |
updateFrameSetupSystem | Sets up hit geometry for frames |
Render Phase
Section titled “Render Phase”| System | Description |
|---|---|
scaleWithZoomSystem | Updates scale for zoom-dependent entities |
canSeeBlocksSystem | Culls blocks outside the viewport |
cursorSystem | Applies cursor style to the DOM |
presenceSystem | Renders user presence indicators |
Keyboard Input
Section titled “Keyboard Input”The Keyboard singleton tracks which keys are currently pressed:
import { defineEditorSystem } from '@woven-canvas/core'import { Keyboard, Key } from '@woven-canvas/core'
const mySystem = defineEditorSystem({ phase: 'update' }, (ctx) => { const keyboard = Keyboard.read(ctx)
// Check if a key is pressed if (keyboard.isDown(Key.Space)) { console.log('Space is held') }
// Check modifier keys if (keyboard.mod) { console.log('Ctrl/Cmd is held') }})Key Constants
Section titled “Key Constants”import { Key } from '@woven-canvas/core'
Key.SpaceKey.EnterKey.EscapeKey.BackspaceKey.DeleteKey.ArrowUpKey.ArrowDownKey.ArrowLeftKey.ArrowRight// ... and all alphanumeric keysCamera Control
Section titled “Camera Control”The Camera singleton controls the viewport:
import { Camera } from '@woven-canvas/core'
// Read camera stateconst camera = Camera.read(ctx)console.log(camera.x, camera.y, camera.zoom)
// Modify camera (in a system)const cam = Camera.write(ctx)cam.x = 100cam.y = 200cam.zoom = 1.5Coordinate Conversion
Section titled “Coordinate Conversion”Convert between screen and world coordinates:
import { screenToWorld, worldToScreen } from '@woven-canvas/core'
// Screen pixel to world coordinateconst worldPos = screenToWorld(ctx, screenX, screenY)
// World coordinate to screen pixelconst screenPos = worldToScreen(ctx, worldX, worldY)Vue Components
Section titled “Vue Components”The Vue package provides toolbar and floating menu components for core block types:
| Component | Description |
|---|---|
SelectTool | Toolbar button for the select tool |
StickyNoteTool | Toolbar button to create sticky notes |
TextTool | Toolbar button to create text blocks |
ImageTool | Toolbar button to upload images |
ShapeTool | Toolbar button to create shapes |
ColorButton | Color picker for block color |
ShapeKindButton | Floating menu dropdown for shape type |
ShapeFillColorButton | Floating menu dropdown for shape fill |
ShapeStrokeColorButton | Floating menu dropdown for shape stroke |
Toolbar Usage
Section titled “Toolbar Usage”<script setup lang="ts">import { WovenCanvas, SelectTool, StickyNoteTool, TextTool, ImageTool, ShapeTool, Toolbar,} from '@woven-canvas/vue'</script>
<template> <WovenCanvas> <template #toolbar> <Toolbar> <SelectTool /> <StickyNoteTool /> <TextTool /> <ImageTool /> <ShapeTool /> </Toolbar> </template> </WovenCanvas></template>Floating Menu
Section titled “Floating Menu”When blocks are selected, the floating menu automatically shows contextual controls based on block type. These are included in the default FloatingMenuBar. To customize:
<script setup lang="ts">import { WovenCanvas, FloatingMenu, FloatingMenuBar, ColorButton, ShapeKindButton, ShapeFillColorButton, ShapeStrokeColorButton,} from '@woven-canvas/vue'</script>
<template> <WovenCanvas> <template #floating-menu> <FloatingMenu> <FloatingMenuBar> <template #button:color="{ entityIds }"> <ColorButton :entity-ids="entityIds" /> </template> <template #button:shape="{ entityIds }"> <ShapeKindButton :entity-ids="entityIds" /> <ShapeFillColorButton :entity-ids="entityIds" /> <ShapeStrokeColorButton :entity-ids="entityIds" /> </template> </FloatingMenuBar> </FloatingMenu> </template> </WovenCanvas></template>