undefined

bokuweb.me

CoffeeScriptで笑い男を書いてみる

canvasCoffeeScriptの勉強に笑い男を描いてみた。 巷ではcssアニメーションで描いたものなんかもあり、周回遅れ感は否めませんが一応記録として残しておく。 描画したものは以下。

ソースは以下

laughingMan = (canvas, x, y, r) ->

      message = " I thought what I'd do was, I'd pretend I was one of those deaf-mutes"
      count = 0
      baseR = 265
      FPS = 24
  
      canvas = document.getElementById(canvas)
      ctx = canvas.getContext("2d")

      drawEye = (ctx, x, y, w, h, scale) ->
        ctx.save()
        ctx.beginPath()
        ctx.fillStyle = "blue"
        ctx.moveTo(x * scale, y * scale)
        ctx.quadraticCurveTo((x + (w / 2)) * scale, (y - 2 * h) * scale, (x + w) * scale, y * scale)
        ctx.quadraticCurveTo((x + (w / 2)) * scale, (y - h) * scale, x * scale, y * scale)
        ctx.closePath()
        ctx.fill()
        ctx.restore()

      drawMouth = (ctx, lw, x, y, w, h, scale) ->
        ctx.save()
        ctx.beginPath()
        ctx.strokeStyle = "blue"
        ctx.lineWidth = lw * scale
        ctx.moveTo(x * scale, y * scale)
        ctx.lineTo((x + w) *scale, y * scale)
        ctx.bezierCurveTo((x + (9 * w / 10)) * scale, (y + h) *scale, (x + (w / 10)) * scale, (y + h) * scale, x * scale, y * scale)
        ctx.closePath()
        ctx.stroke()
        ctx.restore()

      drawCircle = (ctx, lw, x, y, r, scale) ->
        ctx.save()
        ctx.beginPath()
        ctx.strokeStyle = "blue"
        ctx.fillStyle = "white"
        ctx.lineWidth = lw * scale
        ctx.arc(x * scale, y * scale, r * scale, 0, Math.PI*2, false)
        ctx.closePath()
        ctx.fill()
        ctx.stroke()
        ctx.restore()

      rotateText = (ctx, x, y, size, rad, chr) ->
        halfSize = size / 2
        ctx.fillStyle = "blue"
        ctx.textAlign = "left"
        ctx.font = size + "px" + "'Impact";
        ctx.textBaseline = "top"
        ctx.setTransform(1, 0, 0, 1, 0, 0)
        ctx.translate(x + halfSize, y + halfSize)
        ctx.rotate(rad)
        ctx.fillText(chr, -halfSize, -halfSize)

      drawMessage = (ctx, x, y, r, str, startRad, fsz, scale) ->
        ctx.save()
        baseRad = 2.0 * Math.PI / str.length
        for i in [0..str.length - 1]
          rad = baseRad * i + startRad
          textX = (r * Math.cos(rad) + x) * scale
          textY = (r * Math.sin(rad) + y) * scale
          rotateText(ctx, textX, textY, fsz * scale, rad + (0.5 * Math.PI), str[i])
        ctx.restore()

      drawLine = (ctx, x0, y0, x1, y1, lw, color, scale) ->
        ctx.save()
        ctx.beginPath()
        ctx.strokeStyle = color
        ctx.lineWidth = lw * scale
        ctx.moveTo(x0 * scale, y0 * scale)
        ctx.lineTo(x1 * scale, y1 * scale)
        ctx.closePath()
        ctx.stroke()
        ctx.restore()

      update = (ctx) ->
        ctx.save()
        ctx.clearRect(0, 0, 900, 600)
        count++

        drawCircle(ctx, 15, 325 + x, 290 + y, 265, r / baseR)
        drawCircle(ctx, 30, 325 + x, 290 + y, 190, r / baseR)

        # 左の隙間
        drawLine(ctx, 100 + x, 280 + y, 200 + x, 280 + y, 10, "white", r / baseR)

        drawMessage(ctx, 305 + x, 272 + y, 236, message, count/30, 40, r / baseR)
        drawEye(ctx, 220 + x, 310 + y, 70, 30, r / baseR)
        drawEye(ctx, 360 + x, 310 + y, 70, 30, r / baseR)
        drawMouth(ctx, 25, 200 + x, 340 + y, 250, 120, r / baseR)

        # 帽子のツバ
        drawLine(ctx, 480 + x, 297 + y, 635 + x, 297 + y, 48, "white", r / baseR)
        drawLine(ctx, 130 + x, 260 + y, 635 + x, 260 + y, 30, "blue", r / baseR)
        drawLine(ctx, 510 + x, 336 + y, 635 + x, 336 + y, 30, "blue", r / baseR)

        ctx.save()
        ctx.beginPath()
        ctx.strokeStyle = "blue"
        ctx.fillStyle = "white"
        ctx.lineWidth = 30 * r / baseR
        ctx.moveTo((630 + x) * r / baseR, (260 + y) * r / baseR)
        ctx.bezierCurveTo((680 + x) * r / baseR, (270 + y) * r / baseR, (680 + x) * r / baseR, (326 + y) * r / baseR, (630 + x) * r / baseR, (336 + y) * r / baseR)
        ctx.fill()
        ctx.stroke()
        ctx.restore()

      setInterval (()-> update(ctx)), (1 / FPS) * 1000

    laughingMan('laughingman', 0, 0, 100)