CoffeeScriptで花火を打ち上げる このエントリをはてなブックマークに登録

2014年08月29日

ダニーダニー

はじめに

ダニーです、最近暑い日が続いてますね。
夏ですね。
夏といえば花火ですね。
ということで、花火を打ち上げてみます。

実装するにあたり

JavaScriptより簡潔に書けるので、CoffeeScriptを使います。

全体のソースコードはここに置いてあります。

https://github.com/f96q/hanabi

今回は要所を説明します。

Canvasの初期化

  initCanvas: (selector) ->
    @canvas = document.getElementById selector
    @canvas.width  = 500
    @canvas.height = 500
    @context = @canvas.getContext '2d'
    @context.fillStyle = '#000000'
    @context.fillRect 0, 0, @canvas.width, @canvas.height

Canvasを初期化します。
サイズは500×500で黒で塗りつぶしておきます。

花火の玉を中心から飛ばす方向とスピードを算出

  initSparks: ->
    x = @canvas.width  / 2
    y = @canvas.height / 2
    for i in [0..@settings.sparkQuantity]
      angle = Math.random() * (Math.PI * 2)
      speed = Math.random() * 6
      @sparks.push
        x: x
        y: y
        vx: Math.cos(angle) * speed
        vy: Math.sin(angle) * speed

花火の玉の数分、Canvasの中心から飛ばします。
vx, vyで飛ばすスピートと方向が決まります。

花火の玉を描画

  draw: (spark) ->
    @context.fillStyle = '#723057'
    @context.globalCompositeOperation = 'lighter'
    @context.beginPath();
    @context.arc spark.x, spark.y, @sparkSize, 0, Math.PI * 2, true
    @context.fill()

globalCompositeOperationをlighterにすることで、玉が重なると重なった色同士が足されるので、重なれば重なるほど白に近づいていきます。
それで光ってるように見えます。

更新処理

  update: =>
    for spark in @sparks
      spark.x += spark.vx
      spark.y += spark.vy + @settings.gravity
      spark.vx *= @settings.damping
      spark.vy *= @settings.damping
      @draw spark
    @context.globalCompositeOperation = 'source-over'
    @context.fillStyle = 'rgba(0, 0, 0, 0.3)'
    @context.fillRect 0, 0, @canvas.width, @canvas.height
    @sparkSize *= 0.97
    if @sparkSize < 0.03
      @fire()
      return
    requestAnimationFrame @update

この処理を繰り返します。

  1. 花火の玉を玉ごとに、最初に決めた飛ばす方向に向かって動かして描画します。
  2. 重力が加わるのでその分下に動かします。
  3. スピードも遠くに行くにつれて減衰して行くはずなので、その分減らします。
  4. 花火の玉の大きさは時間が経てば経つほど小さくなるはずなので小さくします。

requestAnimationFrame

for vendor in ['moz', 'webkit', 'o', 'ms']
  window.requestAnimationFrame = window["#{vendor}RequestAnimationFrame"]
  break if window.requestAnimationFrame

unless window.requestAnimationFrame
  window.requestAnimationFrame = (callback) ->
    setTimeout callback, 1000 / 60

アニメーションを実行するのにrequestAnimationFrameを使っています。
ブラウザーによってベンダープレフィックスが違うので、対応してるベンダープレフィックスの物を探して、使うようにします。
requestAnimationFrameが対応してない場合はsetTimeoutを使って代用します。

終わりに

今回は花火の打ち上げ方を書いてみました。
HTML5のCanvasでアニメーションするのは楽しいですね。

参考

HTML花火大会

  1. メモからはじめる情報共有 DocBase 無料トライアルを開始
  2. DocBase 資料をダウンロード

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント

コメントはまだありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


トラックバック

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ