2016-11-01 5 views
0

私は、キーボード上の各キーが新しいサウンド/アニメーションを生成するWebページを作成しています。私は現時点で私の最初のキーにしかいませんが、最初のキーを押した後、アニメーションがちょっと邪魔になるという問題があります。アニメーションをもう一度開始するか、どのキーが押されたかに応じて新しいアニメーションを開始する代わりに、矩形(この場合)はちょうどちらつきを開始します。以下は私のコードの一部です。OOPメソッドを使用してキャンバスアニメーションを再開する

class Drawable{ 
constructor(context, x = 0, y = 0, fillStyle = "#000", strokeStyle = "transparent", lineWidth = 0){ 
this.context = context; 
if(!(this.context instanceof CanvasRenderingContext2D)){ 
    throw new Error("You must provide a valid canvas context to Drawables."); 
} 
this.x = x; 
this.y = y; 
this.fillStyle = fillStyle; 
this.strokeStyle = strokeStyle; 
this.lineWidth = lineWidth; 
this.deltas = new Map(); 

this.limits = { 
    max: new Map(), 
    min: new Map() 
}; 
} 
draw(){ 
    this.context.save(); 
    this.context.translate(this.x, this.y); 
    this.context.scale(2,1.5); 
    this.context.fillStyle = this.fillStyle; 
    this.context.strokeStyle = this.strokeStyle; 
    this.context.lineWidth = this.lineWidth; 
} 
afterDraw(){ 
    this.context.restore(); 
} 
applyAnimation(secondsElapsed){ 
    for(const[propertyName, valueChangePerSecond] of this.deltas){ 
     const changedAmount = secondsElapsed * valueChangePerSecond; 
     this[propertyName] += changedAmount; 
     if(this.limits.max.has(propertyName)){ 
      this[propertyName] =  Math.min(this[propertyName],this.limits.max.get(propertyName)); 
     } else if(this.limits.min.has(propertyName)){ 
      this[propertyName] = Math.max(this[propertyName],this.limits.min.get(propertyName)); 
     } 
    } 
    } 
} 
    class Rectangle extends Drawable{ 
constructor(context, x = 0, y = 0, fillStyle = "#000", strokeStyle = "transparent", lineWidth = 0, deltas = new Map(), width = 100, height = 100){ 
super(context, x, y, fillStyle, strokeStyle, lineWidth, deltas); 
this.width = width; 
this.height = height; 
} 

draw(){ 
super.draw(); 
this.context.fillRect(this.width/-2, this.height/-2, this.width, this.height); 
this.context.strokeRect(this.width/-2, this.height/-2, this.width, this.height); 
super.afterDraw(); 
} 
loopDraw(){ 
    super.draw(); 
    let rectSize = 30; 
    for(let i = 0; i < 3; i++){ 
     let yPos = (rectSize - 10)*i; 
     for(let j = 0; j < 6; j++){ 
       this.context.fillRect((rectSize+10)*j,yPos,this.width/-2,this.height/-2); 
      this.context.strokeRect(this.width/-2, this.height/-2, this.width, this.height); 
     } 
    } 
    super.afterDraw(); 
} 
} 
const canvas = document.getElementById("soundBoardCanvas"); 
const context = canvas.getContext("2d"); 
    const animationAObjects = new Set(); 
// Creating the rectangle and setting the animation properties of the rectangle 
let animationARect = new Rectangle(context,canvas.width/1.5,canvas.height/2, randomColour(), "transparent", 0, new Map() ,50,50); 

animationARect.deltas.set("y",100); 
animationARect.deltas.set("height",50); 
animationARect.deltas.set("width",50); 
animationARect.deltas.set("x",100); 
animationARect.limits.max.set("y", canvas.height/2); 
animationARect.limits.max.set("x", canvas.width/2.5); 
animationARect.limits.max.set("height",randomBetween(100,170)); 
animationARect.limits.max.set("width",randomBetween(100,170)); 

animationAObjects.add(animationARect); 


function randomBetween(min,max){ 
let range = max - min; 

let random = Math.random(); 
random = random * (range + 1); 
random = random + min; 

return random; 
} 

// Animates all of the objects in the selected set 
function animationA(){ 
    requestAnimationFrame(animationA); 
    context.clearRect(0,0,canvas.width,canvas.height); 

    const diffSeconds = (Date.now() - lastTime)/1000; 
    lastTime = Date.now(); 

    if(diffSeconds > 0){ 
     for(const animationAObject of animationAObjects){ 
      animationAObject.applyAnimation(diffSeconds); 
      animationAObject.draw(); 
     } 
    } 
} 
document.addEventListener("keydown", (e) => { 
e.preventDefault(); 
cancelAnimationFrame(requestId); 
if(e.keyCode == 65){ 
    window.requestAnimationFrame(animationA); 
} 
}); 
+1

コードがありません。あなたが与えていることから、あなたが説明する問題の理由はありません。 BTW requestAnimationFrameは、最初の引数としてコールバックに、1/1,000,000秒の最小分解能0.001msを1/1,000,000秒で渡します。 'function animationA(time){' – Blindman67

+0

@ Blindman67これですべてのコードが上記の編集に追加されました。うまくいけばそれはそれをより良く説明するはずです。あなたはrequestAnimationFrameについてあなたが作ったコメントを詳しく説明できますか、私はあなたにあまり追いついていません。 – seanrs97

+0

ブラウザが「requestAnimationFrame」に渡す「コールバック」関数をコールすると、コールバックに渡された最初の引数が時刻になります。例えば ​​'function callback(time){// RAFによって渡された時刻引数' 'requestAnimationFrame(callback); // RAFコールバック関数を設定する ' – Blindman67

答えて

1

あなたは決して作成されていないことが(少なくともstrictモードで)エラーをスローする必要がありますのでrequestId、(あるいはどこにでもそれを宣言)。 を押すたびに新しいアニメーションを作成しているだけで、お互いに干渉してちらつきが発生する可能性があります(私は正確にはわかりませんが)。

let requestId = 0; // declare this! 
let lastTime = Date.now(); // important initialisation 

function animationA(){ 
    requestId = requestAnimationFrame(animationA); 
// ^^^^^^^^ 
    … 
} 
document.addEventListener("keydown", (e) => { 
    e.preventDefault(); 
    cancelAnimationFrame(requestId); 
    if (e.keyCode == 65) { 
     requestId = window.requestAnimationFrame(animationA); 
//  ^^^^^^^^^ 
    } 
}); 
+0

私は自分のコードにこれらの変更を加えたばかりで、まだ違いはありません。キーを繰り返し押すと、シェイプは再描画されず、アニメーションは繰り返されません。その代わりにその形はちょうど静的に座っています – seanrs97

+0

@ seanrs97何か間違えていますか?アニメーションをデバッグしましたか? 'animationA'は定期的に呼び出されますか? 'applyAnimation'はあなたが望むことをしますか? 'loopDraw'はどこにも呼び出されないのはなぜですか?いくつかのログを追加して、キャンバス上で何が起こるかだけでなく、オブジェクトに何が起こるかを確認します。 – Bergi

+0

私はエラーを確認しましたが、まったくありません。 LoopDrawは、まだ必要ではない別の描画メソッドです。コードには影響しません。アニメーションを適用することは私が知りたいことをしている。私はいくつかのconsole.logを入れて、これがまったく役立つかどうかを見てみましょう。 – seanrs97

関連する問題