Vue.jsでp5.jsを使ってみる
Vue.jsでp5.jsを使ってみる:
p5.jsをVueのフレームワークを使って描画するためにリサーチした時のメモです。p5.jsはProcessingから派生したライブラリで、ビジュアル表現やGenerative Designをする時に便利です。OpenProcessingというWeb上で開発できる環境があり、プログラムを書いてすぐにビジュアルを確認できます。今回はここで書いたコードをVueを使って表示する方法を調べました。
Vueのプロジェクトを作成したら、p5.jsのライブラリをインストールします。
(私はNuxtで作成しましたが、通常のvue-cliでも同じだと思います。)
これですぐにp5.jsを使うことができるのですが、p5.jsであらかじめ用意されている関数やプロパティはグローバルで展開されてしまうようで、うまく扱うことができません。そこで、p5.jsにinstance modeと呼ばれるモードで、p5.jsを単体のオブジェクトとして生成して、グローバルとの競合を防ぐことができます(参考)。
mountedした時に描画するような記述は以下の通りです。p5.jsの実質的な実装コードを関数内に書いていき、その関数をP5クラスに渡しています。
このままだとp5.jsの表示は左上に表示されてしまうので、html内の任意のCanvasの位置に表示させます(参考)。
任意のCanvasにidをつけ、p5.js内で作成したCanvasの親コンテナに割り当てることで任意のCanvas内に表示できます。
本末転倒かもしれませんが、基本的にp5.js部分の記述はJavaScriptなので、Vue内に書かなくても良いと思いました。そこで、p5.jsの記述部分だけ抜き出して別ファイル(Radar.js)にし、それをVue側から呼び出して使用するように変更しました。
export文でp5.js部分(main関数)にアクセスできるようにして、
もう少しVueの特徴を活かせられるように、p5.jsからコールバックを受け取って、その内容を表示させてみます。
callback関数をあらかじめp5.js側のソースコードに渡しておき、任意のタイミングでコールバック関数を呼び出し、データバインディングしているmessageプロパティを更新させています。
冒頭のデモはgithubに置いています。
元となっているOpenProcessingでのソースコードはこちらです
p5.jsをVueのフレームワークを使って描画するためにリサーチした時のメモです。p5.jsはProcessingから派生したライブラリで、ビジュアル表現やGenerative Designをする時に便利です。OpenProcessingというWeb上で開発できる環境があり、プログラムを書いてすぐにビジュアルを確認できます。今回はここで書いたコードをVueを使って表示する方法を調べました。
ライブラリをインポート
Vueのプロジェクトを作成したら、p5.jsのライブラリをインストールします。(私はNuxtで作成しましたが、通常のvue-cliでも同じだと思います。)
npm install --save p5
mountedした時に描画するような記述は以下の通りです。p5.jsの実質的な実装コードを関数内に書いていき、その関数をP5クラスに渡しています。
mounted内
mounted() { const script = function (p5) { var speed = 2; var posX = 0; p5.setup = _ => { p5.createCanvas(500, 500); p5.ellipse(p5.width / 2, p5.height / 2, 500, 500); } p5.draw = _ => { p5.background(0); const degree = p5.frameCount * 3; const y = p5.sin(p5.radians(degree)) * 50; p5.push(); p5.translate(0, p5.height / 2); p5.ellipse(posX, y, 50, 50); p5.pop(); posX += speed; if (posX > p5.width || posX < 0) { speed *= -1; } } } const P5 = require('p5') new P5(script) }
任意のCanvas内に表示
このままだとp5.jsの表示は左上に表示されてしまうので、html内の任意のCanvasの位置に表示させます(参考)。template
<template> <div class="container border"> <div class="d-flex justify-content-center" id="p5Canvas"></div> </div> </template>
mounted内の修正箇所
// p5.createCanvas(500, 500); var canvas = p5.createCanvas(500, 500) canvas.parent("p5Canvas");
外部リソースにする
本末転倒かもしれませんが、基本的にp5.js部分の記述はJavaScriptなので、Vue内に書かなくても良いと思いました。そこで、p5.jsの記述部分だけ抜き出して別ファイル(Radar.js)にし、それをVue側から呼び出して使用するように変更しました。mounted内の実装
var radar = require('@/js/Radar.js') const P5 = require('p5') new P5(radar.main)
Radar.js
let p5; export function main(_p5) { p5 = _p5 ... 以下同じ }
new P5(radar.main)
でオブジェクトを生成する時にその関数を渡しています。
コールバックを受け取る
もう少しVueの特徴を活かせられるように、p5.jsからコールバックを受け取って、その内容を表示させてみます。methodsを追加
methods: { callbackOnP5: function(timeStr) { this.message = timeStr; } }
templateに追加
<div class="message d-flex justify-content-center"> {{message}} </div>
dataを追加
data() { return { message: "" } },
mounted
// NOTE: p5.jsからのコールバックを受け取る radar.setDelegate(this.callbackOnP5);
Radar.js
let delegate; let p5; export function main(_p5) { p5 = _p5 p5.draw = _ => { notifyCurrentTime(); } } export function setDelegate(_delegate) { delegate = _delegate; } function notifyCurrentTime() { if (delegate !== undefined) { const message = p5.hour() + ":" + p5.minute() + ":" + p5.second(); delegate(message); } }
冒頭のデモはgithubに置いています。
元となっているOpenProcessingでのソースコードはこちらです
コメント
コメントを投稿