Skip to content

Commit 771549b

Browse files
committed
オフスクリーンキャンバスのサンプルを追加(リサイズ、ビットマップ)
1 parent 57893f1 commit 771549b

7 files changed

Lines changed: 247 additions & 47 deletions

samples/offscreencanvas_simple.html

Lines changed: 0 additions & 25 deletions
This file was deleted.

samples/osc_imagebitmap.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<script>
6+
window.addEventListener('DOMContentLoaded', init);
7+
8+
function init() {
9+
// 普通のキャンバスを取得
10+
const canvasElement = document.querySelector('#myCanvas');
11+
// オフスクリーンキャンバスを取得
12+
const offscreenCanvas = canvasElement.transferControlToOffscreen();
13+
const worker = new Worker('osc_imagebitmaqp_worker.js');
14+
worker.postMessage(
15+
{
16+
canvas: offscreenCanvas
17+
},
18+
[offscreenCanvas]
19+
);
20+
}
21+
</script>
22+
</head>
23+
<body>
24+
<canvas id="myCanvas"></canvas>
25+
</body>
26+
</html>

samples/osc_imagebitmaqp_worker.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
importScripts(
2+
'https://cdnjs.cloudflare.com/ajax/libs/three.js/101/three.min.js'
3+
);
4+
5+
// メインスレッドから通達があったとき
6+
onmessage = async event => {
7+
// メインスレッドからオフスクリーンキャンバスを受け取る
8+
const canvas = event.data.canvas;
9+
// Three.jsのライブラリの内部で style.width にアクセスされてしまう
10+
// 対策しないと、エラーが発生するためダミーの値を指定
11+
canvas.style = { width: 0, height: 0 };
12+
13+
// サイズを指定
14+
const width = 960;
15+
const height = 540;
16+
17+
// レンダラーを作成
18+
const renderer = new THREE.WebGLRenderer({ canvas });
19+
renderer.setSize(width, height);
20+
21+
// シーンを作成
22+
const scene = new THREE.Scene();
23+
const camera = new THREE.PerspectiveCamera(45, width / height);
24+
camera.position.set(0, 0, +1000);
25+
const directionalLight = new THREE.DirectionalLight(0xffffff);
26+
directionalLight.position.set(0, 1, 1);
27+
scene.add(directionalLight);
28+
29+
// テクスチャーを読み込み
30+
const texture = await new Promise(resolve => {
31+
new THREE.ImageBitmapLoader().load('imgs/earthmap1k.jpg', imageBitmap => {
32+
const texture = new THREE.CanvasTexture(imageBitmap);
33+
resolve(texture);
34+
});
35+
});
36+
// マテリアルを作成
37+
const material = new THREE.MeshStandardMaterial({ map: texture });
38+
const geometry = new THREE.SphereGeometry(300, 50, 50);
39+
const mesh = new THREE.Mesh(geometry, material);
40+
scene.add(mesh);
41+
42+
tick();
43+
44+
// 毎フレーム時に実行されるループイベントです
45+
function tick() {
46+
// カメラの自動移動
47+
mesh.rotation.y += 0.01;
48+
49+
// レンダリング
50+
renderer.render(scene, camera);
51+
requestAnimationFrame(tick);
52+
}
53+
};

samples/osc_resize.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<style>
7+
body {
8+
margin: 0;
9+
overflow: hidden;
10+
}
11+
#myCanvas {
12+
/* 画面全域にしておく */
13+
width: 100vw;
14+
height: 100vh;
15+
}
16+
</style>
17+
<script>
18+
window.addEventListener('DOMContentLoaded', init);
19+
20+
function init() {
21+
// 普通のキャンバスを取得
22+
const canvasElement = document.querySelector('#myCanvas');
23+
// オフスクリーンキャンバスを取得
24+
const offscreenCanvas = canvasElement.transferControlToOffscreen();
25+
const worker = new Worker('osc_resize_worker.js');
26+
worker.postMessage(
27+
{
28+
type: 'init',
29+
canvas: offscreenCanvas,
30+
width: innerWidth,
31+
height: innerHeight,
32+
devicePixelRatio: devicePixelRatio
33+
},
34+
[offscreenCanvas]
35+
);
36+
37+
window.addEventListener('resize', event => {
38+
worker.postMessage({
39+
type: 'resize',
40+
width: innerWidth,
41+
height: innerHeight,
42+
devicePixelRatio: devicePixelRatio
43+
});
44+
});
45+
}
46+
</script>
47+
</head>
48+
<body>
49+
<canvas id="myCanvas"></canvas>
50+
</body>
51+
</html>

samples/osc_resize_worker.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
importScripts(
2+
'https://cdnjs.cloudflare.com/ajax/libs/three.js/101/three.min.js'
3+
);
4+
let renderer;
5+
let camera;
6+
7+
// メインスレッドから通達があったとき
8+
onmessage = event => {
9+
switch (event.data.type) {
10+
case 'init':
11+
init(event);
12+
break;
13+
case 'resize':
14+
resize(event.data.width, event.data.height, event.data.devicePixelRatio);
15+
break;
16+
}
17+
};
18+
19+
function init(event) {
20+
// メインスレッドからオフスクリーンキャンバスを受け取る
21+
const canvas = event.data.canvas;
22+
// スクリーン情報を受け取る
23+
const width = event.data.width;
24+
const height = event.data.height;
25+
const devicePixelRatio = event.data.devicePixelRatio;
26+
// Three.jsのライブラリの内部で style.width にアクセスされてしまう
27+
// 対策しないと、エラーが発生するためダミーの値を指定
28+
canvas.style = { width: 0, height: 0 };
29+
30+
// レンダラーを作成
31+
renderer = new THREE.WebGLRenderer({ canvas });
32+
33+
// シーンを作成
34+
const scene = new THREE.Scene();
35+
camera = new THREE.PerspectiveCamera(45, width / height);
36+
camera.position.set(0, 0, 1000);
37+
resize(width, height, devicePixelRatio);
38+
39+
// 球体を作成
40+
const geometry = new THREE.SphereGeometry(300, 30, 30);
41+
// マテリアルを作成
42+
const material = new THREE.MeshBasicMaterial({ wireframe: true });
43+
// メッシュを作成
44+
const mesh = new THREE.Mesh(geometry, material);
45+
// 3D空間にメッシュを追加
46+
scene.add(mesh);
47+
48+
tick();
49+
50+
// 毎フレーム時に実行されるループイベントです
51+
function tick() {
52+
mesh.rotation.y += 0.01;
53+
54+
// レンダリング
55+
renderer.render(scene, camera);
56+
requestAnimationFrame(tick);
57+
}
58+
}
59+
60+
function resize(width, height, devicePixelRatio) {
61+
// レンダラーのサイズを調整する
62+
renderer.setPixelRatio(devicePixelRatio);
63+
renderer.setSize(width, height);
64+
65+
// カメラのアスペクト比を正す
66+
camera.aspect = width / height;
67+
camera.updateProjectionMatrix();
68+
}

samples/osc_simple.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<script>
6+
window.addEventListener('DOMContentLoaded', init);
7+
8+
function init() {
9+
// 普通のキャンバスを取得
10+
const canvasElement = document.querySelector('#myCanvas');
11+
// オフスクリーンキャンバスを取得
12+
const offscreenCanvas = canvasElement.transferControlToOffscreen();
13+
const worker = new Worker('osc_simple_worker.js');
14+
worker.postMessage(
15+
{
16+
canvas: offscreenCanvas
17+
},
18+
[offscreenCanvas]
19+
);
20+
}
21+
</script>
22+
</head>
23+
<body>
24+
<canvas id="myCanvas"></canvas>
25+
</body>
26+
</html>
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,55 @@
1-
importScripts("https://cdnjs.cloudflare.com/ajax/libs/three.js/101/three.min.js");
1+
importScripts(
2+
'https://cdnjs.cloudflare.com/ajax/libs/three.js/101/three.min.js'
3+
);
24

5+
// メインスレッドから通達があったとき
36
onmessage = event => {
7+
// メインスレッドからオフスクリーンキャンバスを受け取る
8+
const canvas = event.data.canvas;
9+
// Three.jsのライブラリの内部で style.width にアクセスされてしまう
10+
// 対策しないと、エラーが発生するためダミーの値を指定
11+
canvas.style = { width: 0, height: 0 };
412

513
// サイズを指定
614
const width = 960;
715
const height = 540;
816

9-
// メインスレッドからオフスクリーンキャンバスを受け取る
10-
const canvas = event.data.canvas;
11-
canvas.style = { width: 0, height: 0 };
12-
1317
// レンダラーを作成
1418
const renderer = new THREE.WebGLRenderer({ canvas });
1519
renderer.setSize(width, height);
1620

1721
// シーンを作成
1822
const scene = new THREE.Scene();
19-
20-
// カメラを作成
2123
const camera = new THREE.PerspectiveCamera(45, width / height);
22-
23-
// マテリアルを作成する
24-
const material = new THREE.MeshStandardMaterial({ color: 0xffFF00 });
25-
26-
// 平行光源
2724
const directionalLight = new THREE.DirectionalLight(0xffffff);
28-
// シーンに追加
2925
scene.add(directionalLight);
3026

31-
// ビルボードを作成
27+
// マテリアルを作成
28+
const material = new THREE.MeshStandardMaterial({ color: 0xffff00 });
29+
30+
// たくさん作成
3231
for (let i = 0; i < 300; i++) {
33-
// 球体を作成
3432
const geometry = new THREE.SphereGeometry(20, 20, 20);
35-
// メッシュを作成
3633
const mesh = new THREE.Mesh(geometry, material);
37-
// 3D空間にメッシュを追加
3834
scene.add(mesh);
39-
mesh.position.set(1000 * (Math.random() - 0.5),
35+
// 適当に配置
36+
mesh.position.set(
37+
1000 * (Math.random() - 0.5),
4038
1000 * (Math.random() - 0.5),
41-
1000 * (Math.random() - 0.5));
39+
1000 * (Math.random() - 0.5)
40+
);
4241
}
4342

4443
tick();
4544

4645
// 毎フレーム時に実行されるループイベントです
4746
function tick() {
4847
// カメラの自動移動
49-
camera.position.x = 100 * Math.sin(Date.now() / 2000);
50-
camera.position.z = 100 * Math.cos(Date.now() / 2000);
51-
camera.position.y = 50 * Math.sin(Date.now() / 1000) + 60;
48+
camera.position.set(
49+
100 * Math.sin(Date.now() / 2000),
50+
100 * Math.cos(Date.now() / 2000),
51+
50 * Math.sin(Date.now() / 1000) + 60
52+
);
5253
camera.lookAt(new THREE.Vector3(0, 0, 0));
5354

5455
// レンダリング

0 commit comments

Comments
 (0)