@adraw/vue

Vue bindings for adraw — composables and components for building canvas-based drawing and whiteboard UIs.
1,066 3
Install
npm install @adraw/vue
Latest Version:0.2.0
Vue:3
License:MIT
Last Updated:Oct 22, 2026
Links: GitHub  ·  npm
Maintainer: vladiantio

@adraw/vue

Vue bindings for adraw — composables and components for building canvas-based drawing and whiteboard UIs.

Installation

pnpm add @adraw/vue

# npm
npm install @adraw/vue

Vue 3.0 or later is required as a peer dependency.

Quick start

Wrap your app (or the part that needs the canvas) with CanvasProvider, then render the Canvas component wherever you want the drawing surface. Composables access the canvas state anywhere inside that provider.

<script setup lang="ts">
import { Canvas, CanvasProvider, useTool } from "@adraw/vue"
</script>

<template>
  <CanvasProvider>
    <Toolbar />
    <Canvas style="flex: 1" />
  </CanvasProvider>
</template>
<!-- Toolbar.vue -->
<script setup lang="ts">
import { useTool } from "@adraw/vue"

const { tool, setTool } = useTool()
</script>

<template>
  <div>
    <button :class="{ active: tool === 'select' }" @click="setTool('select')">
      Select
    </button>
    <button :class="{ active: tool === 'draw' }" @click="setTool('draw')">
      Draw
    </button>
    <button
      :class="{ active: tool === 'rectangle' }"
      @click="setTool('rectangle')"
    >
      Rectangle
    </button>
  </div>
</template>

Multiple canvases

Each CanvasProvider creates its own isolated canvas instance, so nesting several CanvasProvider/Canvas pairs on the same page gives you independent canvases — composables called inside a given subtree always resolve to the nearest ancestor provider.

<template>
  <CanvasProvider>
    <Canvas />
  </CanvasProvider>
  <CanvasProvider>
    <Canvas />
  </CanvasProvider>
</template>

Components

CanvasProvider

Creates the underlying canvas instance and makes it available to Canvas and all composables rendered inside it.

<CanvasProvider
  :options="{
    snapping: { threshold: 8 },
    tools: { draw: { strokeWidth: 4 }, rectangle: { cornerRadius: 8 } },
  }"
>
  ...
</CanvasProvider>
Prop Type Description
options CanvasVueOptions Snapping / viewport / per-tool styles and initial document
onReady (engine: AdrawCanvas) => void Called once after <Canvas> mounts the engine

options accepts initialElements and initialDocument from @adraw/core; the latter takes precedence. Initial content is applied when the provider creates the engine, before the first render. Options are captured at that point; changing the prop later does not recreate the engine, so in-progress content is preserved.

Canvas

Mounts the drawing surface inside a div that fills its parent. Must be rendered inside a CanvasProvider.

<Canvas class="my-canvas" :style="{ borderRadius: '8px' }" />
Prop Type Description
class string CSS class
style Record<string, any> Inline styles

Composables

All composables must be called inside a CanvasProvider — they throw if no provider is found in the ancestor tree.

createCanvas(options?, onReady?)

Low-level factory used internally by CanvasProvider. Returns { core, isReady, markUnmounted, notifyReady, state, vanilla }.

  • core — the AdrawCanvas instance, created headless immediately
  • state — a Vue reactive object with elements, viewport, activeTool, and selectedIds
  • vanilla — a ref to the mounted AdrawCanvas instance (set after core.mount())
  • isReady — a ref that flips after notifyReady() / markUnmounted()

Call this directly only if you want to manage mounting/destruction yourself instead of using CanvasProvider/Canvas.

useCanvas()

Returns the canvas context ({ core, isReady, state, vanilla, … }) provided by the nearest CanvasProvider. Throws if called outside one. core is available before the canvas is mounted and carries core-only APIs too, such as the clipboard (copy(), cut(), paste()).

useCanvasEngine()

Returns { engine, isReady }, where isReady is a reactive getter. The engine exists as soon as the provider is created, so composables and effects do not need to wait for a template ref.

const { engine, isReady } = useCanvasEngine()
// engine: AdrawCanvas
// isReady: boolean getter — true after <Canvas> mounts

useTool()

const { tool, setTool } = useTool()
// tool: getter — "select" | "hand" | "draw" | "eraser" | "rectangle" | "ellipse" | "line" | "text" | "arrow"
setTool("draw")

useViewport()

const { viewport, setViewport, zoomIn, zoomOut, resetZoom, zoomToFit } =
  useViewport()
// viewport: getter — { x: number, y: number, zoom: number }

useHistory()

const { undo, redo, canUndo, canRedo } = useHistory()

useSelection()

const { selectedIds, elements, selectAll, clearSelection, deleteSelected } =
  useSelection()

useToolOptions()

const { toolOptions, setToolOptions } = useToolOptions()
// toolOptions: getter — resolved styles for every configurable tool
setToolOptions("rectangle", { cornerRadius: 12 })

useStyle(tool?)

Reactive getters for one tool. Omit tool to infer it from a homogeneous selection (or the active tool):

<script setup lang="ts">
import { useStyle } from "@adraw/vue"

const styles = useStyle()
// or: const styles = useStyle("rectangle")
</script>

<template>
  <input
    v-if="styles.style"
    type="range"
    :value="styles.style.strokeWidth"
    @input="styles.setStyle({ strokeWidth: Number($event.target.value) })"
  />
</template>

All tools share strokeColor, strokeWidth and opacity; fillColor applies to rectangle and ellipse (combine it with opacity < 1 for translucent highlights). Tool-specific fields: cornerRadius (rectangle), fontSize (text), smoothing (draw). Changes also restyle matching selected elements.

useTransformOverlay()

const { hideWhileTransforming, setHideWhileTransforming } =
  useTransformOverlay()
// hideWhileTransforming: getter — whether the selection bounding box +
// resize/rotation handles are hidden while a resize/rotation gesture is in
// progress (defaults to true; set via the hideOverlayWhileTransforming option)
setHideWhileTransforming(false)

License

MIT

Related Packages

@bimetal/whiteboard-vue-components

Default Vue 3 whiteboard — infinite-canvas pan/zoom, shapes, drag/resize/rotate,...

2,250
@kritzel/vue-engine

Kritzel engine wrapper for Vue.

2,165
@kritzel/vue-editor

Kritzel helps you build infinite canvas experiences with Vue.

2,117
@lemonyc/region-editor

基于 Vue 3 的区域绘图编辑器,支持 Canvas 绘制直线/矩形,自动识别封闭区域并设置颜...

1,435
vue-quick-loadmore

基于vue的移动端下拉刷新上拉无限滚动加载支持自定义文案自定义gif图的插件

919 132

Version History

Version Released Vue License
0.2.0 >=3.0.0 MIT
0.1.4 >=3.0.0 MIT
0.1.3 >=3.0.0 MIT
0.1.2 >=3.0.0 MIT
0.1.1 >=3.0.0 MIT