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

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

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

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

JavaScript

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

Q&A

解決済

1回答

1008閲覧

canvasでプリレンダリングを使いながらアニメーションを実現したいのですが clearRect() が機能しません。

9nahito

総合スコア45

canvas

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

JavaScript

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

0グッド

0クリップ

投稿2021/06/19 05:15

編集2021/06/19 06:16

パフォーマンス向上のためアニメーションのシーンでプリレンダリングを使いたいのですが
プリレンダリングを使うと clearRect() が機能しません。
clearRect() が機能しないせいで 図形 をアニメーションさせると図形の軌跡が消えません!
どうしたら プリレンダリングを行いながら clearRect() が機能するようになりますか?

HTML

1<body> 2 <canvas id = "game"> 3 </canvas> 4</body> 5 6<script> 7// 可視領域のCanvas 8const canvas = document.getElementById('game'); 9const ctx = canvas.getContext('2d'); 10 11// オフスクリーン 12const offscreen = document.createElement('canvas'); 13offscreen.width = canvas.width; 14offscreen.height = canvas.height; 15const offscreenCtx = offscreen.getContext('2d'); 16 17var speed = 10 18 19function clear(){ 20 ctx.clearRect(0,0,30,300) 21 22 requestAnimationFrame(clear) 23} 24 25function animation() { 26speed+=1 27 28offscreenCtx.fillRect(0, 0, 30, 30+speed) 29 30// 可視領域のCanvasにコピーして描画する 31 32ctx.drawImage(offscreen, 0, 0) 33 34 35requestAnimationFrame(animation) 36} 37clear() 38animation() 39 40</script>

clearRect() を animation() に入れて offscreenCtx.でもしてみたのですがなりませんでした。
回答よろしくお願いします!

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

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

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

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

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

m.ts10806

2021/06/19 05:21

これが機能することによりどうなるのかは想定の上でしょうか。 「想定する動作」と「実際に起きていること」を提示してください。 あとできれば確認したブラウザとバージョンも。
9nahito

2021/06/19 05:47

Google Chromeで実行しています。 バージョンは バージョン: 91.0.4472.106(Official Build) (64 ビット) です。 これが動作すると進んだ図形の軌跡が見えなくなります。 下のコードはプリレンダリングを使用していません。 下のコードはclearRect()が機能します。そのため図形の軌跡が見えません。 <html> <!-- id 'can' で JS と canvas を紐づけ --> <canvas id = "can"> </canvas> <script> var canvas = document.getElementById("can");//id 'can'で HTML と canvas を 紐づけ var context = canvas.getContext("2d");//そのままでok var dw = screen.width; //ディスプレイサイズ横 var dh = screen.height;//ディスプレイサイズ縦 canvas.width = dw;//canvasサイズをディスプレイサイズに合わせる x canvas.height = dh;//canvasサイズをディスプレイサイズに合わせる y var py = 0//プレーヤーの y 座標 var px = 0//プレーヤーの x 座標 var by = py - 20//自機弾幕座標 ちょうどプレーヤーの下に描画して打たないときは見えなくする var bx = px + 20// var bx2 = bx;// var by2 = by; var speed0 = 0//自機弾速度 //初期状態では押されてないので "false" var w = "false" var a = "false" var s = "false" var d = "false" var j = "false" // キー入力を検知する document.addEventListener("keydown", function(event0){ //キー の 入力を検知したら roop0() 内で処理する //roop0()は requestAnimationFrame によってループしているためここで実行するよりより滑らかに動くようになる if(event0.key === "w") { w = "true" } if(event0.key === "a") { a = "true" } if(event0.key === "s") { s = "true" } if(event0.key === "d") { d = "true" } if(event0.key === "j") { j = "true" } }); // キー が離されたことを検知する document.addEventListener("keyup", function(event0){ if(event0.key === "w") { w = "false" } if(event0.key === "a") { a = "false" } if(event0.key === "s") { s = "false" } if(event0.key === "d") { d = "false" } if(event0.key === "j") { //jはfalseいらない } }); //MyShot0() は roop0() に入れない function roop0() {//毎フレームごとに更新が必要な処理はこの関数内に書く context.clearRect( 0, 0, dw, dh); context.fillStyle = "red";//プレーヤーの色 context.fillRect(px,py,50,50);//プレーヤーの描画 //間接的にwasdが押されたことを判定する if(w == "true"){ //wが押されたら プレーヤー の y 座用を - する //画面上方向は - py = py - 10; } if(a == "true"){ //aが押されたら プレーヤー の x 座用を - する px = px - 10; } if(s == "true"){ //sが押されたら プレーヤー の y 座用を + する //画面下方向は + py = py + 10; } if(d == "true"){ //dが押されたら プレーヤー の x 座用を + する px = px + 10; } roop1();//ループさせる } //ブラウザが更新する度に更新してアニメーションを実現させる function roop1() { requestAnimationFrame(roop0) //roop0()の中でさらに この roop1() を呼び出して ループさせる } roop1();//メイン処理の初回実行 </script> </html>
m.ts10806

2021/06/19 05:48

質問は編集できるので適宜調整してください。
9nahito

2021/06/19 05:54

質問を書き直しましたがこれで良いですか?
9nahito

2021/06/19 06:02

いまの質問内容だと伝わりずらいということですか?
m.ts10806

2021/06/19 06:06 編集

「ずらい」というより「伝わらない」です。 2021/06/19 14:47 のコメント内容をほぼそのまま質問本文に追記してもらえれば良いのですけど。 「どうなったらゴールか」が見えません。 clearRect()の採用で本当に要件を満たせるかが見えないという意味ですね。 もっと言えば「どういうアニメーションか」とか現在の状態や前提背景がきちんと説明されていた方が応えやすいです。 見てる人は赤の他人ですから。
guest

回答1

0

ベストアンサー

30x30の四角形が下がるアニメーションをしたいという解釈でよろしいでしょうか。

オフスクリーンcanvasを通常のcanvasに drawImage() した場合、透明のピクセルは上書きされずにスキップされ、通常canvasの描画結果が残ります。ですので、clearRect()を使う方針であるならば、

  • 前に書いた四角形を消すために、fillRect()の前に offscreenCtx.clearRect() が必要
  • 前に書いたオフスクリーンcanvasの内容を消すために、ctx.drawImage() の前に ctx.clearRect() が必要

です。

clearRect()を使わずオフスクリーンcanvasを不透明色で塗りつぶす方がプリレンダリングらしいと言えるかもしれません。

投稿2021/06/21 06:09

編集2021/06/21 15:10
int32_t

総合スコア21597

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

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

9nahito

2021/06/27 01:08

回答ありがとうございます! int32_tさんの教えてくださったとおり clearRect()を使わずオフスクリーンcanvasを不透明色で塗りつぶしたら動作しました! <html> <!-- Canvas と JavaScript で 2Dシューティング --> <!-- ↑canvas要素 より上に置きたい要素とか --> <canvas id = "test"> </canvas> <!--JavaScript宣言--> <script> var canvas = document.getElementById("test")//id 'can'で HTML と canvas を 紐づけ var context = canvas.getContext("2d") //オフスクリーン var offcanvas = document.createElement("canvas") offcanvas.width = canvas.width offcanvas.height = canvas.height var offcontext = offcanvas.getContext("2d") var speed = 10 function draw(){ context.fillStyle = "white" context.fillRect(0,0,offcanvas.width,offcanvas.height) context.fillStyle = "black" context.fillRect(0,speed+=1,30,30) context.drawImage(offcanvas,0,0) requestAnimationFrame(draw) } draw() </script> </html> ただ自分のコードが良くなかったようでパフォーマンスの向上にはつながりませんでした。 なのでcanvasのサイズ縮小など違うことでパフォーマンスの向上を目指そうと思います! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問