canvasとCoffeeScriptの勉強に笑い男を描いてみた。 巷では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)