Vue・NuxtでCanvas要素を使った処理をする方法・vue-konva & konvaの使い方まとめ
こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、Vue・NuxtでCanvas要素を使った処理をする方法・vue-konva & konvaの使い方について解説します。
Vue・Nuxtで、Canvas処理をするにはどうすればいいのか?
今回、プロジェクトの要件で、服のイメージ画像の上に、Print位置を示す赤い四角形を描画するようなCanvas処理が必要になりました。
このような服のイメージ画像に。。。
このようなPrint位置を示す赤い四角形を描画する感じの実装です。
以前に、JavaScriptで、Canvas操作をする方法は、こちらの記事で、ご紹介しました。
このような「Canvas処理を Vue・Nuxt上でするには、どうすればいいのか?」と疑問に思い。
Vue・Nuxtで、Canvas要素を使った処理をするなら、どんな方法があるのか調べていたところ、
VueでCanvas要素を使用するなら、vue-konva & konva.jsがよさそうなので、実際に使ってみた結果のまとめ記事になります。
Konva(Konva.js)とは?
Knova.jsは、JavaScriptで、グラフィックを描く際に使用するCanvas機能のフレームワークです。
詳細は、Konva 公式の概要説明が参考になります。
Konva は、デスクトップおよびモバイル アプリケーションのキャンバスの対話性を可能にすることで 2D コンテキストを拡張する HTML5 Canvas JavaScript フレームワークです。
Konva は、デスクトップおよびモバイル アプリケーションの高性能アニメーション、トランジション、ノードのネスト、階層化、フィルタリング、キャッシュ、イベント処理などを可能にします。
引用元: Konva Framework Overview
vue-konvaとは?
vue-konva
とは、グラフィックスや図形を描画および操作するためのフレームワークであるKnova.js
をVue.jsフレームワーク上で使いやすくするためのライブラリです。
具体的には、vue-konva
を使用することで、Vueコンポーネント内でキャンバス上に図形を描画したり、アニメーションを作成したりすることができます。
また、vue-konva
は、Vueのコンポーネントとして、Knova.js
の機能を提供してくれているので、Vue.jsのプロジェクトで、Knova.js
を使いたい時に、利用しやすくしてくれます。
その他の詳細事項は、vue-konva
のGetting startedから説明を引用します。
Vue Konva は、Vue を使用して複雑なキャンバス グラフィックを描画するための JavaScript ライブラリです。
これはKonva
フレームワークへの宣言型およびリアクティブなバインディングを提供します。
vue-konva
のすべてのコンポーネントは、接頭辞「v-」が付いた同じ名前のコンポーネントに対応します。
Konva
オブジェクトで使用できるすべてのパラメータは、対応するvue-konva
コンポーネントのprop
に設定として追加できます。
コア シェイプは次のとおりです: v-rect, v-circle, v-ellipse, v-line, v-image, v-text, v-text-path, v-star, v-label, v-path, v-regular-polygon.
カスタム形状を作成することもできます。
引用元: Getting started with vue and canvas via Konva
Vue・Nuxt2系に、vue-konva & konva.js を導入する(環境構築)
前提条件として、Vue.jsのバージョン 2.4 以降が必要です。
1. konva.js & vue-konva をインストールする
Vue3系の場合は、次のようにして、konva.js & vue-konva をインストールします。
npm install vue-konva konva --save
# または
yarn add vue-konva konva
Vue2系の場合は、次のようにして、konva.js & vue-konva をインストールします。
npm install vue-konva@2 konva --save
# または
yarn add vue-konva@2 konva
2. plugins/vue-konva.jsファイルを作成する
ライブラリのインストールが完了したら、plugins/vue-konva.js
ファイルを作成します。
import Vue from 'vue'
import VueKonva from 'vue-konva'
Vue.use(VueKonva)
3. nuxt.config.jsファイルのpluginsキー内にファイルパスを追加
vue-konva.js
ファイルのPluginの作成ができたら、nuxt.config.js
のplugins
キーに設定を追加します。
plugins: [
// vue-konva は、 Canvasライブラライである konva.js を Vue で扱えるようにした Vue用のライブラリです。
{
src: '~/plugins/vue-konva',
ssr: false, // SSRはしない設定
},
4. Sample Componentを作って表示確認をする
vue-konva
のREADME.mdでも紹介されているSample Componentで表示のテストをします。
SampleCodeは、次のとおりです。
<template>
<!-- 1. Stage: Canvasの最上位の領域 -->
<v-stage :config="configKonva">
<!-- 2. 1つのレイヤー(層)を作成する -->
<v-layer>
<!-- 3. Canvas内に、円を描く -->
<v-circle :config="configCircle"></v-circle>
</v-layer>
</v-stage>
</template>
<script>
export default {
data() {
return {
/** Canvasの最上位の領域を設定する */
configKonva: {
width: 200,
height: 200,
},
/** 円の設定値 */
configCircle: {
x: 100,
y: 100,
radius: 70,
fill: "red",
stroke: "black",
strokeWidth: 4,
},
};
},
};
</script>
SampleComponentを表示すると、次のような赤丸がレンダリングされるはずです。
これで、環境構築から、動作確認までが完了しました。
Print位置をCanvasで描くComponentを作成する
それでは、今回の本題であるPrint位置をCanvasで描くComponentの作成に入っていきます。
完成したSampleCodeは、次のとおりです。
今回作成したCanvas Componentでの処理の要点をまとめると、次のとおりです。
Canvas Componentでの処理の要点まとめ
- Canvasの最上位の領域であるStage領域を設定する。
- 設定は、Propsで受け取れる。
- Canvasの1つのレイヤー(層)を作成する。
- Canvas上に、ベースとなる画像を表示する。
- 設定は、Propsで受け取れる。
- 画像に関しては、Image Instanceを作成する。
- Image Instanceを作成するために、クライアントサイドonlyのComponentとなる。
- 赤い四角形をCanvas上に表示する。
- 設定は、Propsで受け取れる。
<template>
<!-- no-ssr タグで、クライアントサイドでのみのレンダリングを指定する -->
<no-ssr>
<div>
<!-- 1. Stage: Canvasの最上位の領域 -->
<v-stage :config="stageConfig">
<!-- 2. 1つのレイヤー(層)を作成する -->
<v-layer>
<!-- 3. ベースとなる画像を表示する -->
<v-image :config="imageConfig" />
<!-- 4. 赤い四角形を表示する -->
<v-rect
v-for="(rect, index) in squareConfigList"
:key="index"
:config="rect"
/>
</v-layer>
</v-stage>
</div>
</no-ssr>
</template>
<script>
export default {
props: {
/** Canvasの領域設定・Object */
canvasStageConfig: {
type: Object,
default: () => {
return { width: 278, height: 278 }
},
},
/** 表示するベース Image 画像の設定情報・Object */
imageConfigObj: {
type: Object,
default: () => {
return {
/** 表示する 商品画像の URL */
image:
'https://www.photolibrary.jp/mhd6/img326/450-20140125170616151742.jpg',
/** 画像の幅 */
width: 200,
/** 画像の高さ */
height: 200,
/** Canvas上の X座標 */
x: 0,
/** Canvas上の Y座標 */
y: 0,
}
},
/** 必須・Props */
required: true,
},
/** 四角形の設定情報・Object を 格納した List */
squareList: {
type: Array,
default: () => {
return [
{
/** Canvas上の X座標 */
x: 75,
/** Canvas上の Y座標 */
y: 60,
/** 四角形の幅 */
width: 50,
/** 四角形の高さ */
height: 50,
/** 塗りつぶし色: 半透明な赤色 */
fill: 'rgba(255, 0, 0, 0.5)',
},
]
},
/** 必須・Props */
required: true,
},
},
data() {
return {
/** Canvas の 領域設定 */
stageConfig: this.canvasStageConfig,
/** 表示する Base 画像の 設定 Object */
imageConfig: {
/** Image Instance を Set する */
image: null,
/** 画像の幅 */
width: this.imageConfigObj.width,
/** 画像の高さ */
height: this.imageConfigObj.height,
/** Canvas上の X座標 */
x: this.imageConfigObj.x,
/** Canvas上の Y座標 */
y: this.imageConfigObj.y,
},
/** 四角形の設定を格納する配列 */
squareConfigList: this.squareList,
}
},
computed: {},
watch: {},
methods: {
/**
* NOTE: createImageObject
* => Propsで受け取った Image画像を設定した Image・Object を生成する Func
*/
createImageObject() {
/** Canvasに合成したい画像のPath */
const imagePath = this.imageConfigObj.image
console.log('imagePath', imagePath)
/** Image Instance を作成する */
let image = null
/** クライアント側でしか処理させない */
if (process.client) {
image = new Image()
/** Image Instance に 画像ファイルのPathを設定する */
image.src = imagePath
}
console.log('Image Instance', image)
return image
},
},
/** LifeCycleHook: CreatedTiming */
created() {
// Data & Props を確認する
console.log('this.$data', this.$data)
console.log('this.$props', this.$props)
/** Image・Instance を作成する */
const imageInstance = this.createImageObject()
this.imageConfig.image = imageInstance
},
}
</script>
<style></style>
SampleCodeを実行すると、PropsのDefault値だけでも、次のようなベースとなる画像イメージの上に、赤い四角形をレンダリングした表示がでてきます。
まとめ
vue-konva & konvaを初めて使いましたが、使い勝手がよかったので、おすすめです。
個人で、Blogもやっています、よかったら見てみてください。
参考・引用
注意事項
この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。
求む、冒険者!
AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨
エンジニア視点での我が社のおすすめポイント
- フルリモート・フルフレックスの働きやすい環境!
- 前の会社でアサインしてた現場は、フル出社だったので、ありがたすぎる。。。
- もうフル出社には、戻れなくなります!
- 経験豊富なエンジニアの先輩方
- 私は、3年目の駆け出しエンジニアなので、これが、かなりありがたいです!
- 自社開発とR&D(受託開発)を両方している会社なので、経験できる技術が多い。
- 自社のProduct開発と、他社からの受託案件で、いろいろな技術を学ぶことができます。
- AI関連の最新の技術に触れられるチャンスが多い。
- 自社で特許を持つほど、AI技術に強い会社で、プロファイリングを得意とした技術体系があります。
- ChatGPTを自社アプリに搭載など、AIトレンドも、もちろん追っており、最新の技術に触れられるチャンスが多いです。
- たまに、札幌ラボ(東京から札幌) or 東京オフィス(札幌から東京)に出張で行ける!
- 東京と、札幌に2拠点ある会社なので、会合などで集まる際に、出張で行けます。
採用技術 (一部抜粋)
- FrontEnd: TypeScript, JavaScript, React.js, Vue.js, Next.js, Nuxt.js など
- BackEnd: Node.js, Express,Python など
- その他技術: Docker, AWS, Git, GitHub など
エントリー方法
- 私達と東京か札幌で一緒に働ける仲間を募集しています。
詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。
Webエンジニア向け説明
データサイエンティスト向け説明
人事に直通(?)・ご紹介Plan(リファラル採用)
私経由で、ご紹介もできますので、興味のある方や気軽にどんな会社なのか知りたい方は、X(旧:Twitter)にて、DMを送ってくれても大丈夫です。

AIQ 株式会社 に所属するエンジニアが技術情報をお届けします。 ※ AIQ 株式会社 社員による個人の見解であり、所属する組織の公式見解ではありません。 Wantedly: wantedly.com/companies/aiqlab
Discussion