質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

633閲覧

canvasの描画内容をWebWorkerに対応させる

s-hori

総合スコア2

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2022/11/15 07:02

前提

jsでcanvasを描画していたのですが
処理速度があまりに遅くWebWorkerというものがあると知り実装をさせたく思っているのですが難航しております。

実現したいこと

エラーなくworker.jsからhero.jsに処理結果を渡してcanvasに描画をしたいです。

発生している問題・エラーメッセージ

hero.js:38 Uncaught ReferenceError: balls is not defined

とでてしまっていてmessegeの引き渡しがうまく行っていないのか?と思っています。

該当のソースコード

hero.js(書き換え前)

1/* 2 * グローバル変数 3 */ 4let wrapper = null; // キャンバスの親要素 5let canvas = null; // キャンバス 6let g = null; // コンテキスト 7let $id = function(id){ 8 return document.getElementById(id); 9 }; // DOM取得用 10const speed1 = -0.8; 11let balls = []; 12/* 13 * キャンバスのサイズをウインドウに合わせて変更 14 */ 15function getSize(){ 16 // キャンバスのサイズを再設定 17 canvas.width = wrapper.offsetWidth; 18 canvas.height = wrapper.offsetHeight; 19 balls.forEach(ball => ball.r = canvas.width/8); 20} 21 22 23// ボール1 24let ball1 = { 25 x: 300, 26 y: 300, 27 vx: speed1, 28 vy: speed1, 29 color: "#c1a868", 30}; 31 32// ボール2 33let ball2 = { 34 x: 800, 35 y: 220, 36 vx: speed1, 37 vy: speed1, 38 color: "#000", 39}; 40 41//let x, y, r; // ●のx座標、y座標、半径 42//let vx, vy; // x方向の速度、y方向の速度 43 44function drawAnim(){ 45 // 背景をグレーに 46 g.fillStyle = "rgba( 30, 38, 64 , 0)"; 47 g.fillRect(0, 0, canvas.width, canvas.height); 48 49 // ballを描画 50 for(let ball of balls){ 51 g.beginPath(); 52 g.fillStyle = ball.color; // 塗りつぶす色 53 g.arc(ball.x, ball.y, ball.r, 0, Math.PI*2, false); 54 g.fill(); 55 56 // ●の移動 57 ball.x += ball.vx; 58 ball.y += ball.vy; 59 // 壁に当たったら跳ね返る(●のxy座標は中心点のため、半径を考慮) 60 if(ball.x < 0+ball.r || ball.x > canvas.width-ball.r){ 61 ball.vx = -ball.vx; 62 } 63 if(ball.y < 0+ball.r || ball.y > canvas.height-ball.r){ 64 ball.vy = -ball.vy; 65 } 66 } 67 // 再帰呼び出しでアニメーションさせる 68 requestAnimationFrame(drawAnim); 69} 70 71 72 73window.addEventListener("load", function(){ 74 // キャンバスの親要素情報取得(親要素が無いとキャンバスのサイズが画面いっぱいに表示できないため) 75 wrapper = $id("heroBg"); 76 // キャンバス情報取得 77 canvas = $id("canvas"); 78 g = canvas.getContext("2d"); 79 80 balls.push(ball1); 81 balls.push(ball2); 82 // アニメーション開始 83 drawAnim(); 84 // キャンバスをウインドウサイズにする 85 getSize(); 86 87}); 88 89/* 90 * リサイズ時 91 */ 92window.addEventListener("resize", function(){ 93 getSize(); 94}); 95

試したこと

hero.js

1/* 2 * グローバル変数 3 */ 4let wrapper = null; // キャンバスの親要素 5let canvas = null; // キャンバス 6let g = null; // コンテキスト 7let $id = function(id){ 8 return document.getElementById(id); 9 }; // DOM取得用 10 11/* 12 * キャンバスのサイズをウインドウに合わせて変更 13 */ 14 15 16 17// Workerの作成 18var worker = new Worker("/wp-content/themes/ryowan/assets/js/worker.js"); 19 20 21 // Workerからのメッセージをリッスン 22 worker.addEventListener('message', function (e) { 23 console.log(e.data); 24 }, false); 25 26 27 28 29 30 31window.addEventListener("load", function(){ 32 // キャンバスの親要素情報取得(親要素が無いとキャンバスのサイズが画面いっぱいに表示できないため) 33 wrapper = $id("heroBg"); 34 // キャンバス情報取得 35 canvas = $id("canvas"); 36 g = canvas.getContext("2d"); 37 38 balls.push(ball1); 39 balls.push(ball2); 40 // アニメーション開始 41 drawAnim(); 42 // キャンバスをウインドウサイズにする 43 getSize(); 44 45}); 46 47/* 48 * リサイズ時 49 */ 50window.addEventListener("resize", function(){ 51 getSize(); 52}); 53

woker.js

1 2 3 4 5 // Main Threadからのメッセージをリッスン 6 self.addEventListener('message', function (e) { 7 var result; 8 9 const speed1 = -0.8; 10let balls = []; 11 12function getSize(){ 13 // キャンバスのサイズを再設定 14 canvas.width = wrapper.offsetWidth; 15 canvas.height = wrapper.offsetHeight; 16 balls.forEach(ball => ball.r = canvas.width/8); 17} 18// ボール1 19let ball1 = { 20 x: 300, 21 y: 300, 22 vx: speed1, 23 vy: speed1, 24 color: "#c1a868", 25}; 26 27// ボール2 28let ball2 = { 29 x: 800, 30 y: 220, 31 vx: speed1, 32 vy: speed1, 33 color: "#000", 34}; 35 36//let x, y, r; // ●のx座標、y座標、半径 37//let vx, vy; // x方向の速度、y方向の速度 38 39 function drawAnim(){ 40 // 背景をグレーに 41 g.fillStyle = "rgba( 30, 38, 64 , 0)"; 42 g.fillRect(0, 0, canvas.width, canvas.height); 43 44 // ballを描画 45 for(let ball of balls){ 46 g.beginPath(); 47 g.fillStyle = ball.color; // 塗りつぶす色 48 g.arc(ball.x, ball.y, ball.r, 0, Math.PI*2, false); 49 g.fill(); 50 51 // ●の移動 52 ball.x += ball.vx; 53 ball.y += ball.vy; 54 // 壁に当たったら跳ね返る(●のxy座標は中心点のため、半径を考慮) 55 if(ball.x < 0+ball.r || ball.x > canvas.width-ball.r){ 56 ball.vx = -ball.vx; 57 } 58 if(ball.y < 0+ball.r || ball.y > canvas.height-ball.r){ 59 ball.vy = -ball.vy; 60 } 61 } 62 // 再帰呼び出しでアニメーションさせる 63 requestAnimationFrame(drawAnim); 64 } 65 66 67 68 self.postMessage(result); 69 }, false);

何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

通常のJavaScript環境とワーカー環境では変数の共有はできません。共有する必要のあるデータはお互いに postMessage() で送る必要があります。

おそらくやりたいことは OffscreenCanvas のワーカーでの描画 でしょう。Safari はまだ対応していませんが。

投稿2022/11/15 07:12

編集2022/11/15 07:40
int32_t

総合スコア20670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問