タイマーを使わない
HTML5でアニメーションを実現する方法を調べてみたら、タイマーを使う必要が無くなったらしい(タイマー間隔をブラウザ任せに出来る)のでやってみました。それぞれのブラウザ用にAPIが分かれているようで今後どうなるかわかりません(HTML5自体がまだまだ流動的だと思いますが)が、結構以前(HTML5リリース当初)からこのやり方は定着しているらしいです。手元のAndroid4.1.2の端末(GL07S)でも問題なく動きました。IEでHTML5を利用するにはIE9以上が必要です。
二点の座標をクリックして直線を引くサンプル
要するにRequestAnimationFrameというAPIを使えばいいという話なのですがネットでandroidの対応状況は4.1以上でも全滅という書き込みをちらほら見かけます。でも、実際にやってみると以下のCoffeeScriptをコンパイルしたanimation.jsとanimation.htmlをandroid端末(GL07s)にコピーしてURL指定すれば標準ブラウザでふつうに動作しました。ネットではjQueryといっしょに使用することで問題が出るという書き込みも見かけましたが無視することにしました。知らないうちに解決されたのでしょう1
実際にアニメーションを駆使するスマホアプリを作るときは、既存のいろんなライブラリを使うことが多いのかもしれませんがHTML5だけで出来るほうがシンプルでいいですね。
#animation.coffee
$ ->
return new Animation()
class Animation
constructor: ->
@canvas = document.getElementById("canvasMain")
@areaStartX = document.getElementById("spanStartX")
@areaStartY = document.getElementById("spanStartY")
@areaEndX = document.getElementById("spanEndX")
@areaEndY = document.getElementById("spanEndY")
@start = {x:0, y:0}
@end = {x:100, y:100}
@request = null
@amount = 0
@startflg = true
@setEventListener()
@touch(@start.x, @start.y)
@touch(@end.x, @end.y)
touch: (clientX, clientY) =>
if @startflg
@startflg = false
@start.x = clientX; @areaStartX.innerHTML = clientX
@start.y = clientY; @areaStartY.innerHTML = clientY
else
@startflg = true
@end.x = clientX; @areaEndX.innerHTML = clientX
@end.y = clientY; @areaEndY.innerHTML = clientY
setEventListener: =>
$('#canvasMain').on 'click', (e) =>
@touch(e.clientX, e.clientY)
$('#btnStart').on 'click', (e) =>
@animate()
animate: =>
@request = requestAnimFrame(@animate, @canvas)
@drawanimation()
drawanimation: =>
@context = @canvas.getContext('2d')
@context.clearRect(0, 0, @canvas.width, @canvas.height)
@amount += 0.02
@amount = 1 if @amount > 1
@context.beginPath()
@context.moveTo @start.x, @start.y
@context.strokeStyle = 'rgba(255, 105, 180, 0.7)'
@context.lineWidth = 12
newX = @start.x + (@end.x - @start.x) * @amount
newY = @start.y + (@end.y - @start.y) * @amount
@context.lineTo newX, newY
@context.stroke()
if newX is @end.x and newY is @end.y
cancelRequestAnimFrame @request
@request = null
@amount = 0
window.Animation = window.Animation || Animation
window.requestAnimFrame = (->
window.requestAnimationFrame or window.webkitRequestAnimationFrame or window.mozRequestAnimationFrame or window.oRequestAnimationFrame or window.msRequestAnimationFrame or (callback, element) ->
window.setTimeout callback, 1000 / 60
)()
window.cancelRequestAnimFrame = (->
window.cancelAnimationFrame or window.webkitCancelRequestAnimationFrame or window.mozCancelRequestAnimationFrame or window.oCancelRequestAnimationFrame or window.msCancelRequestAnimationFrame or clearTimeout
)()
<!-- animation.html -->
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="js/jquery-1.11.2.min.js"> </script>
<script type="text/javascript" src="animation.js"> </script>
<title>アニメーションのテスト</title>
</head>
<body>
<div>
<canvas id="canvasMain" width="400" height="400" style="background-color: #2f4f4f;"></canvas>
<form>
<p>
開始点 X=<span id="spanStartX"></span>:
Y=<span id="spanStartY"></span><br />
終了点 X=<span id="spanEndX"></span>:
Y=<span id="spanEndY"></span>
</p>
<p>
<input id="btnStart" type="button" value="描画">
</p>
</form>
</div>
</body>
</html>
- 黒板に赤チョークのイメージです(赤チョークって確かこういうピンクっぽい色だった記憶があります)