--- title: 高度なアニメーション slug: Web/API/Canvas_API/Tutorial/Advanced_animations tags: - Canvas - Graphics - Tutorial translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations original_slug: Web/Guide/HTML/Canvas_tutorial/Advanced_animations ---
前の章では、いくつかの基本的なアニメーションを作成して、物の動かし方を学びました。このパートでは、 運動そのものをより詳細に見て、 アニメーションをより高度にするための物理を追加していきましょう。
アニメーションの勉強のために、ボールを使おうと思うので、最初にボールを canvas 上に描きましょう。次のコードは私たちの準備をしてくれるでしょう。
<canvas id="canvas" width="600" height="300"></canvas>
普通は、まず描画コンテキストが必要になります。 ボールを描くため、 プロパティと canvas にボールを描くための draw()
メソッドを持つ ball オブジェクトを作りましょう。
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var ball = { x: 100, y: 100, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; ball.draw();
ここでは特別なことはなく、ball は本当に単純な円で、{{domxref("CanvasRenderingContext2D.arc()", "arc()")}} メソッドの助けを借りて描かれています。
ボールが手に入りましたので、このチュートリアルの前の章で習ったように、基本的なアニメーションを加えていきましょう。また {{domxref("window.requestAnimationFrame()")}} がアニメーションの制御を手助けしてくれます。The ball gets moving by adding a velocity vector to the position. For each frame, we also {{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}} the canvas to remove old circles from prior frames.
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function draw() { ctx.clearRect(0,0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mouseover', function(e){ raf = window.requestAnimationFrame(draw); }); canvas.addEventListener("mouseout",function(e){ window.cancelAnimationFrame(raf); }); ball.draw();
Without any boundary collision testing our ball runs out of the canvas quickly. We need to check if the x
and y
position of the ball is out of the canvas dimensions and invert the direction of the velocity vectors. To do so, we add the following checks to the draw
method:
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { ball.vx = -ball.vx; }
これまでで、実際にどのように動くか見てみましょう。canvas にマウスを移動させて、アニメーションを開始してます。
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function draw() { ctx.clearRect(0,0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mouseover', function(e){ raf = window.requestAnimationFrame(draw); }); canvas.addEventListener("mouseout",function(e){ window.cancelAnimationFrame(raf); }); ball.draw();
{{EmbedLiveSample("First_demo", "610", "310")}}
動きをよりリアルにするために、このような速度で再生できます。たとえば:
ball.vy *= .99; ball.vy += .25;
This slows down the vertical velocity each frame, so that the ball will just bounce on the floor in the end.
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function draw() { ctx.clearRect(0,0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; ball.vy *= .99; ball.vy += .25; if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mouseover', function(e){ raf = window.requestAnimationFrame(draw); }); canvas.addEventListener("mouseout",function(e){ window.cancelAnimationFrame(raf); }); ball.draw();
{{EmbedLiveSample("Second_demo", "610", "310")}}
Until now we have made use of the {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}} method when clearing prior frames. If you replace this method with a semi-transparent {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}, you can easily create a trailing effect.
ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.fillRect(0,0,canvas.width,canvas.height);
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function draw() { ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.fillRect(0,0,canvas.width,canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; ball.vy *= .99; ball.vy += .25; if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mouseover', function(e){ raf = window.requestAnimationFrame(draw); }); canvas.addEventListener("mouseout",function(e){ window.cancelAnimationFrame(raf); }); ball.draw();
{{EmbedLiveSample("Third_demo", "610", "310")}}
ボールに対するちょっとした制御をするために、たとえば mousemove
イベントを使用してボールをマウスの動きに従わせる。といったことができます。click
イベントでボールを開放して、またバウンドさせる。といったことも可能です。
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var raf; var running = false; var ball = { x: 100, y: 100, vx: 5, vy: 1, radius: 25, color: 'blue', draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); } }; function clear() { ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.fillRect(0,0,canvas.width,canvas.height); } function draw() { clear(); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { ball.vy = -ball.vy; } if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw); } canvas.addEventListener('mousemove', function(e){ if (!running) { clear(); ball.x = e.clientX; ball.y = e.clientY; ball.draw(); } }); canvas.addEventListener("click",function(e){ if (!running) { raf = window.requestAnimationFrame(draw); running = true; } }); canvas.addEventListener("mouseout",function(e){ window.cancelAnimationFrame(raf); running = false; }); ball.draw();
マウスを使ってボールを動かして、クリックで開放してください。
{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}
This short chapter only explains some techniques to create more advanced animations. There are many more! How about adding a paddle, some bricks, and turn this demo into a Breakout game? Checkout our Game development area for more gaming related articles.
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}