Skip to main content

使用 Konva 开始使用 Vue 和 Canvas

如何在 Vue 中使用 canvas?

VueKonva Logo

Vue Konva 是一个用于通过 Vue 绘制复杂 Canvas 图形的 JavaScript 库。

它提供了对 Konva 框架 的声明性和响应式绑定。

所有 vue-konva 组件都对应于同名的 Konva 组件,前缀为 'v-'。所有可用于 Konva 对象的参数可以作为 config 添加到相应 vue-konva 组件的属性中。

核心图形包括:v-rectv-circlev-ellipsev-linev-imagev-textv-text-pathv-starv-labelv-pathv-regular-polygon。 你还可以创建 自定义形状

要获得有关 Konva 的更多信息,可以阅读 Konva 概述

快速开始

需要 Vue.js 版本 3。

1. 通过 npm 安装

npm install vue-konva konva --save

2. 导入并使用 VueKonva

import { createApp } from 'vue';
import App from './App.vue';
import VueKonva from 'vue-konva';

const app = createApp(App);
app.use(VueKonva);
app.mount('#app');

3. 在组件中使用

说明:尝试拖动星星。它们在被拖动时会放大,并在释放时恢复到正常大小。

<template>
  <v-stage
    ref="stage"
    :config="stageSize"
    @dragstart="handleDragstart"
    @dragend="handleDragend"
  >
    <v-layer ref="layer">
      <v-star
        v-for="item in list"
        :key="item.id"
        :config="{
          x: item.x,
          y: item.y,
          rotation: item.rotation,
          id: item.id,
          numPoints: 5,
          innerRadius: 30,
          outerRadius: 50,
          fill: '#89b717',
          opacity: 0.8,
          draggable: true,
          scaleX: dragItemId === item.id ? item.scale * 1.2 : item.scale,
          scaleY: dragItemId === item.id ? item.scale * 1.2 : item.scale,
          shadowColor: 'black',
          shadowBlur: 10,
          shadowOffsetX: dragItemId === item.id ? 15 : 5,
          shadowOffsetY: dragItemId === item.id ? 15 : 5,
          shadowOpacity: 0.6
        }"
      />
    </v-layer>
  </v-stage>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const stageSize = {
  width: window.innerWidth,
  height: window.innerHeight
};

const list = ref([]);
const dragItemId = ref(null);

const handleDragstart = (e) => {
  // 保存拖动的元素:
  dragItemId.value = e.target.id();
  // 将当前元素移动到顶部:
  const item = list.value.find(i => i.id === dragItemId.value);
  const index = list.value.indexOf(item);
  list.value.splice(index, 1);
  list.value.push(item);
};

const handleDragend = () => {
  dragItemId.value = null;
};

onMounted(() => {
  for (let n = 0; n < 30; n++) {
    list.value.push({
      id: Math.round(Math.random() * 10000).toString(),
      x: Math.random() * stageSize.width,
      y: Math.random() * stageSize.height,
      rotation: Math.random() * 180,
      scale: Math.random()
    });
  }
});
</script>

或者使用 CDN

<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
</head>
<body>
<div id="app">
<v-stage ref="stage" :config="configKonva">
<v-layer ref="layer">
<v-circle :config="configCircle" />
</v-layer>
</v-stage>
</div>
<!--1. 链接 Vue Javascript 和 Konva-->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/konva@9/konva.min.js"></script>
<!--2. 链接 VueKonva Javascript(插件自动安装)-->
<script src="https://unpkg.com/vue-konva@3/dist/vue-konva.umd.js"></script>
<script>
// 3. 创建 Vue 实例
const { createApp, ref } = Vue;
const VueKonva = window['vue-konva'].default;

const app = createApp({
setup() {
const configKonva = {
width: 200,
height: 200
};

const configCircle = {
x: 100,
y: 100,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
};

return {
configKonva,
configCircle
};
}
});

app.use(VueKonva);
app.mount('#app');
</script>
</body>
</html>