Skip to content

Pen Plugin

The Pen plugin provides freehand drawing functionality with smooth SVG ink strokes and stylus pressure sensitivity.

  • Select the Pen tool and draw on the canvas
  • Strokes inherit the current color from the toolbar color picker
  • Strokes can be selected, moved, and resized like any other block

The Pen plugin is included by default when using WovenCanvas. To disable it:

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

The Pen plugin has no configuration options. Pen strokes automatically inherit the current color from the editor state.

  • Smooth SVG strokes — Strokes are rendered as vector paths for crisp display at any zoom level
  • Pressure sensitivity — When using a stylus, stroke width varies with pen pressure
  • Scalable and rotatable — Strokes behave like regular blocks and can be transformed
  • Hit geometry — Precise selection based on stroke path, not bounding box
import {
StartPenStroke,
AddPenStrokePoint,
CompletePenStroke,
RemovePenStroke,
} from '@woven-canvas/plugin-pen'
// Start a new stroke
editor.command(StartPenStroke, {
worldPosition: [100, 100],
pressure: 0.5,
thickness: 4,
})
// Add points while drawing
editor.command(AddPenStrokePoint, {
strokeId,
worldPosition: [150, 120],
pressure: 0.7,
})
// Finalize the stroke
editor.command(CompletePenStroke, { strokeId })
// Cancel a stroke
editor.command(RemovePenStroke, { strokeId })
ComponentDescription
PenStrokeStores stroke point data and rendering information

The PenStroke component stores up to 1024 points per stroke. Each point includes position and pressure data.

import { PenStroke } from '@woven-canvas/plugin-pen'
import { defineQuery } from '@woven-canvas/core'
const penStrokeQuery = defineQuery((q) => q.with(PenStroke))
// In a system
for (const entityId of penStrokeQuery.current(ctx)) {
const stroke = PenStroke.read(ctx, entityId)
console.log('Point count:', stroke.pointCount)
}

The Vue package provides toolbar and floating menu components for pen strokes:

ComponentDescription
PenToolToolbar button to activate the pen tool
PenStrokeThicknessButtonFloating menu dropdown for stroke thickness (S, M, L)
<script setup lang="ts">
import { WovenCanvas, PenTool, Toolbar } from '@woven-canvas/vue'
</script>
<template>
<WovenCanvas>
<template #toolbar>
<Toolbar>
<PenTool />
</Toolbar>
</template>
</WovenCanvas>
</template>

When a pen stroke is selected, the floating menu automatically shows color and thickness controls. These are included in the default FloatingMenuBar. To customize:

<script setup lang="ts">
import {
WovenCanvas,
FloatingMenu,
FloatingMenuBar,
PenStrokeThicknessButton,
} from '@woven-canvas/vue'
</script>
<template>
<WovenCanvas>
<template #floating-menu>
<FloatingMenu>
<FloatingMenuBar>
<template #button:penStroke="{ entityIds }">
<PenStrokeThicknessButton :entity-ids="entityIds" />
</template>
</FloatingMenuBar>
</FloatingMenu>
</template>
</WovenCanvas>
</template>
PropTypeDescription
entityIdsEntityId[]Selected pen stroke entity IDs