Vue
@veyrajs/vue wraps the imperative engine in Vue 3 components and composables. Install it alongside
the core (see Installation); vue ^3.4 is a peer dependency.
The scene above is a live Vue island — @veyrajs/vue components actually running. Click the
rectangle (it moves via a ref) and drag the selection handles.
npm install @veyrajs/core @veyrajs/vueQuick start
Section titled “Quick start”<script setup lang="ts">import { ref } from 'vue'import { ACStage, ACLayer, ACRect, ACCircle } from '@veyrajs/vue'
const x = ref(40)</script>
<template> <ACStage :width="800" :height="480" background="#0b1220" selectable> <ACLayer> <ACRect :x="x" :y="40" :width="150" :height="90" fill="#38bdf8" @click="x += 20" /> <ACCircle :x="300" :y="100" :radius="50" fill="#f472b6" /> </ACLayer> </ACStage></template>selectable wires a SelectionController + History (click-select, transform handles, undo/redo).
Components
Section titled “Components”ACStage (root), ACLayer / ACGroup (containers), and ACRect, ACCircle, ACEllipse,
ACLine, ACPolygon, ACText, ACImage (shapes). Bind node properties with :prop and listen to
engine events with @event — see the Adapters Overview
for the full prop table.
Props & events
Section titled “Props & events”Props are controlled — they drive the node. Sync your reactive state from events when users edit:
<ACRect :x="x" :y="40" :width="150" :height="90" fill="#38bdf8" @click="onClick" @dragmove="(e) => (x = e.target.x)" @pointerenter="hover = true"/>The events: @pointerdown, @pointermove, @pointerup, @pointerenter, @pointerleave, @click,
@dblclick, @wheel, @dragstart, @dragmove, @dragend — each handed a
SceneEvent.
Composables
Section titled “Composables”Inside <ACStage>, reach engine services reactively:
<script setup lang="ts">import { useStage, useCamera, useSelection, useHistory } from '@veyrajs/vue'
const history = useHistory() // Ref<History | null>const camera = useCamera() // ComputedRef<Camera | null></script>
<template> <button @click="history?.undo()">Undo</button> <button @click="camera?.reset()">Reset view</button></template>useStage()→Ref<Stage | null>useCamera()→ComputedRef<Camera | null>useSelection()→Ref<SelectionManager | null>(only underselectable)useHistory()→Ref<History | null>(only underselectable)
The escape hatch — template refs
Section titled “The escape hatch — template refs”Every component exposes its underlying engine node; <ACStage> exposes stage / selection /
history:
<script setup lang="ts">import { ref, onMounted } from 'vue'import { ACStage, ACRect } from '@veyrajs/vue'
const rect = ref()onMounted(() => rect.value?.node.on('click', () => console.log('imperative')))</script>
<template> <ACStage @ready="(stage) => console.log('ready', stage)"> <ACLayer><ACRect ref="rect" :x="40" :y="40" :width="150" :height="90" fill="#38bdf8" /></ACLayer> </ACStage></template>Conventions & gotchas
Section titled “Conventions & gotchas”- Composables aren’t reactive to engine-internal changes. Mutating a node doesn’t re-render Vue; subscribe to engine events (or lift state) when the UI must track interactive edits.
ACImagetakes a loaded:imagesource; the adapter doesn’t load it for you.
Related
Section titled “Related”- Adapters Overview — the shared model and full prop table.
- Events — the
SceneEventevery handler receives. - Camera — what
useCamera()returns.