この記事の内容は、タイトルのとおり、p5.js Web Editor上で PlayCanvas のシンプルな Hello World のサンプルを動かしてみた話です。
余談
余談ですが、他に PixiJS・three.js と、p5.js とを組み合わせるというのを試してみたことがあります。
- PixiJS でパーティクルを描画して p5.js で扱うための下準備(まずは独立したキャンバスでシンプルな描画から) - Qiita
- three.js の公式サンプルを p5.js Web Editor上で扱うための下準備(独立したキャンバスでシンプルな描画から) - Qiita
PlayCanvas のシンプルな Hello World のサンプル
今回のメインとなる、PlayCanvas のシンプルな Hello World のサンプルについて、まずは記載します。具体的には、以下に掲載されたサンプルです。
●engine/README-ja.md at main · playcanvas/engine · GitHub
https://github.com/playcanvas/engine/blob/main/README-ja.md
具体的には、以下の内容です。また、この内容は「The Hello World of 3D」というタイトルの CodePen のページにアクセスすれば、簡単に動作を確認することもできます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PlayCanvas Hello Cube</title>
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no' />
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src='https://code.playcanvas.com/playcanvas-stable.min.js'></script>
</head>
<body>
<canvas id='application'></canvas>
<script>
// create a PlayCanvas application
const canvas = document.getElementById('application');
const app = new pc.Application(canvas);
// fill the available space at full resolution
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
// ensure canvas is resized when window changes size
window.addEventListener('resize', () => app.resizeCanvas());
// create box entity
const box = new pc.Entity('cube');
box.addComponent('model', {
type: 'box'
});
app.root.addChild(box);
// create camera entity
const camera = new pc.Entity('camera');
camera.addComponent('camera', {
clearColor: new pc.Color(0.1, 0.1, 0.1)
});
app.root.addChild(camera);
camera.setPosition(0, 0, 3);
// create directional light entity
const light = new pc.Entity('light');
light.addComponent('light');
app.root.addChild(light);
light.setEulerAngles(45, 0, 0);
// rotate the box according to the delta time since the last frame
app.on('update', dt => box.rotate(10 * dt, 20 * dt, 30 * dt));
app.start();
</script>
</body>
</html>
これを p5.js Web Editor で動かしていきます。
p5.js Web Editor でとりあえず動作させる
上記のサンプルを p5.js Web Editor で動かす際に、HTML・JavaScript(index.html と sketch.js)を書きかえます。
HTML
p5.js Web Editor のデフォルトの HTML に関して、変更した部分は以下の 2つです。
- CDN からのライブラリの読み込みの実行
- PlayCanvas用のキャンバス要素の追加
具体的には、以下のとおりです。
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<script src="https://code.playcanvas.com/playcanvas-stable.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<meta charset="utf-8" />
</head>
<body>
<main><canvas id="application"></canvas></main>
<script src="sketch.js"></script>
</body>
</html>
JavaScript
p5.js Web Editor でデフォルトで用意される JavaScript に関して、変更した主な内容は以下のとおりです。
- 上記の PlayCanvas のサンプルのほとんどを、setup() の中に記載
- オブジェクトを回転させる処理を draw() の中に記載
let box;
function setup() {
createCanvas(20, 20);
const canvas = document.getElementById("application");
const app = new pc.Application(canvas);
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
window.addEventListener("resize", () => app.resizeCanvas());
box = new pc.Entity("cube");
box.addComponent("model", {
type: "box",
});
app.root.addChild(box);
const camera = new pc.Entity("camera");
camera.addComponent("camera", {
clearColor: new pc.Color(0.1, 0.1, 0.1),
});
app.root.addChild(camera);
camera.setPosition(0, 0, 3);
const light = new pc.Entity("light");
light.addComponent("light");
app.root.addChild(light);
light.setEulerAngles(45, 0, 0);
app.start();
}
function draw() {
background(220);
box.rotate(0.5, 1, 1.5);
}
ここまでは、p5.js のキャンバスは利用せず、PlayCanvas用に用意したキャンバス上での描画を行っています。これを、p5.js のキャンバスに描画する形に変更していきます。
p5.js のキャンバス上で描画させる
PlayCanvas の描画結果を、p5.js のキャンバス上で描画させてみます。
HTML はそのままで、JavaScript に少し変更を加えます。
let canvasPS;
let box;
function setup() {
createCanvas(windowWidth, windowHeight);
canvasPS = document.getElementById("application");
canvasPS.style.visibility = "hidden";
canvasPS.style.position = "absolute";
const app = new pc.Application(canvasPS);
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
window.addEventListener("resize", () => app.resizeCanvas());
box = new pc.Entity("cube");
box.addComponent("model", {
type: "box",
});
app.root.addChild(box);
const camera = new pc.Entity("camera");
camera.addComponent("camera", {
clearColor: new pc.Color(0.1, 0.1, 0.1),
});
app.root.addChild(camera);
camera.setPosition(0, 0, 3);
const light = new pc.Entity("light");
light.addComponent("light");
app.root.addChild(light);
light.setEulerAngles(45, 0, 0);
app.start();
}
function draw() {
background(220);
drawingContext.drawImage(canvasPS, 0, 0, width, height);
box.rotate(0.5, 1, 1.5);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
上記で行った主な対応は以下の通りです。
- p5.js のキャンバスのサイズを、PlayCanvas のキャンバスと同様に画面いっぱいになるように変更(リサイズ時のサイズ変更も追加)
- PlayCanvas のキャンバスを不可視に
- PlayCanvas のキャンバスの描画内容を、
drawingContext.drawImage()
で p5.js のキャンバスに描画
実行結果
実行結果は、このようになりました。