Production Level Knowledge & Tips

  1. プログラミング
  2. 28 view

[CoffeeScript]HTML5のCanvasでアニメーション

とある統計のアルゴリズムの動きを視覚的に確認したいがために、
それの全段階としてCoffeeScriptとHTML5のCanvasでアニメーション処理を書いてみた。 まずmain.coffee。
Point2D = require('../src/point2d').Point2D

main = ()->
    canvas = document.getElementById('canvas')
    context = canvas.getContext('2d')

    num_points = 9
    labels = ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]
    points = []
    for i in [0..num_points]
        x = canvas.width /2 + Math.floor(Math.random() * 200) - 100
        y = canvas.height /2 + Math.floor(Math.random() * 200) - 100
        vx = Math.random() * 5.0 - 2.5
        vy = Math.random() * 5.0 - 2.5

        points.push new Point2D(x, y, 10, vx, vy, labels[i], canvas.width, canvas.height, context)
        points[i].draw()

    mainloop = ()->
        context.save()
        context.beginPath()
        context.clearRect(0, 0, canvas.width, canvas.height)
        context.restore()

        for i in [0..num_points]
            points[i].update_position()
            points[i].reflect()
            points[i].draw()

        setTimeout(mainloop, 30)

    mainloop()

window.onload = main
次に、2次元のデータ点を表現するpoint2d.coffee。
class Point2D
    constructor: (x, y, r, vx, vy, label, wnd_width, wnd_height, context) ->
        @x = x
        @y = y
        @r = r
        @vx = vx
        @vy = vy
        @label = label
        @wnd_width = wnd_width
        @wnd_height = wnd_height
        @context = context

    update_position: ->
        @x += @vx
        @y += @vy

    reflect: ->
        if @x - @r < 0
            @x = @r
            @vx *= -1.0

        if @x + @r > @wnd_width
            @x = @wnd_width - @r
            @vx *= -1.0

        if @y - @r < 0
            @y = @r
            @vy *= -1.0

        if @y + @r > @wnd_height
            @y = @wnd_height - @r
            @vy *= -1.0

    draw: ->
        @context.beginPath()
        @context.strokeStyle = '#00F'
        @context.fillStyle = '#00F'
        @context.arc(@x, @y, @r, 0, Math.PI * 2, false)
        @context.fill()
        @context.stroke()
        @context.restore()

        @context.beginPath()
        @context.font = "18px 'MS Pゴシック'"
        @context.fillStyle = "blue"
        @context.fillText(@label, @x, @y-@r)
        @context.restore()

exports.Point2D = Point2D
無駄にテストコードも書いてしまった。
ちなみにjasmine-nodeを使っております。
Point2D = require('../src/point2d').Point2D

describe "Point2D", ->
    p1 = undefined
    p2 = undefined
    p3 = undefined
    p4 = undefined
    p5 = undefined
    p6 = undefined

    beforeEach ->
        p1 = new Point2D(0, 0, 0, 0, 0, "", 0, 0, undefined)
        p2 = new Point2D(100, 200, 30, 2.0, 2.0, "test", 640, 480, undefined)
        p3 = new Point2D(5, 200, 30, 2.0, 2.0, "test", 640, 480, undefined)
        p4 = new Point2D(630, 200, 30, 2.0, 2.0, "test", 640, 480, undefined)
        p5 = new Point2D(100, 10, 30, 2.0, 2.0, "test", 640, 480, undefined)
        p6 = new Point2D(100, 470, 30, 2.0, 2.0, "test", 640, 480, undefined)

    it "should be x and y axis value are 0", ->
        expect(p1.x).toEqual 0
        expect(p1.y).toEqual 0
        expect(p1.r).toEqual 0
        expect(p1.vx).toEqual 0
        expect(p1.vy).toEqual 0
        expect(p1.wnd_width).toEqual 0
        expect(p1.wnd_height).toEqual 0
        expect(p1.label).toEqual ""

    it "should be x and y axis value are 5, 10", ->
        expect(p2.x).toEqual 100
        expect(p2.y).toEqual 200
        expect(p2.r).toEqual 30
        expect(p2.vx).toEqual 2.0
        expect(p2.vy).toEqual 2.0
        expect(p2.wnd_width).toEqual 640
        expect(p2.wnd_height).toEqual 480
        expect(p2.label).toEqual "test"

    it "should add velocity for x and y to 102.0 and 202.0", ->
        p2.update_position()
        expect(p2.x).toEqual 102.0
        expect(p2.y).toEqual 202.0

    it "should reflect with left side", ->
        p3.reflect()
        expect(p3.x).toEqual 30
        expect(p3.vx).toEqual -2.0

    it "should reflect with right side", ->
        p4.reflect()
        expect(p4.x).toEqual 610
        expect(p4.vx).toEqual -2.0

    it "should reflect with left side", ->
        p5.reflect()
        expect(p5.y).toEqual 30
        expect(p5.vy).toEqual -2.0

    it "should reflect with left side", ->
        p6.reflect()
        expect(p6.y).toEqual 450
        expect(p6.vy).toEqual -2.0
animation
ここまでの実行結果はこんな感じ。
さて、後は多次元尺度構成法のアルゴリズムを乗っければ完成だ。I want to watch a statistical algorithm’s behavior,
so I wrote animation program with Coffee Script and Canvas on HTML5 before it.

プログラミングの最近記事

  1. How to bring columns not GROUP BY key from ne…

  2. HiveでGROUP BYを伴うサブクエリのネストからGROUP BYのキー以外のカラムを…

  3. How to drop Hive’s External Table

  4. HiveでExternal Tableを削除する方法メモ

  5. [触ってみた]Microsoft Quantum Development Kit

関連記事

PAGE TOP