Facebookタイムラインのカバー画像をCanvasで作る

Standard

.cover-gen

class Global
  constructor: () ->
    @canvas
    @context
  init: () ->
    @canvas = document.getElementById 'myCanvas'
    @context = @canvas.getContext '2d'

class Drawer
  constructor: () ->
    @bgImage = "img/def.png"
    @bgShadowBlur = 50
    @circleRadius = 20
    @mainColor = "#000000"
    @anotherColor = "#000000"
    @main = 1
    @sub = 2

  drawCircles: () ->
    x = @circleRadius * 1.8
    y = @circleRadius * 2
    cnt = 0
    for r in [0..5]
      for c in [0..12]
        if cnt % 9 is 0
          switch @sub
            when 1 then this.drawCircle(x, y, @anotherColor)
            when 2 then this.drawSpade(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @anotherColor)
            when 3 then this.drawDiamond(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @anotherColor)
            when 4 then this.drawHeart(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @anotherColor)
            when 5 then this.drawClub(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @anotherColor)
            else this.drawCircle(x, y, @anotherColor)

        else
          switch @main
            when 1 then this.drawCircle(x, y, @mainColor)
            when 2 then this.drawSpade(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @mainColor)
            when 3 then this.drawDiamond(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @mainColor)
            when 4 then this.drawHeart(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @mainColor)
            when 5 then this.drawClub(x, y-@circleRadius, @circleRadius*2, @circleRadius*2, @mainColor)
            else this.drawCircle(x, y, @mainColor)

        x += @circleRadius*3.8
        cnt += 1
      x = if r%2 is 0 then -1*@circleRadius*2 + @circleRadius*1.8 else @circleRadius*1.8
      y += @circleRadius*4

  drawCircle: (x, y, color) ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    ctx.save()
    ctx.fillStyle = color
    ctx.shadowColor = "rgba(0,0,0,1)"
    ctx.shadowBlur = getBlurValue(me.circleRadius)
    ctx.shadowOffsetX = 0
    ctx.shadowOffsetY = 0
    ctx.beginPath()
    ctx.arc(x, y, me.circleRadius, 0 , 2*Math.PI, false)
    ctx.fill()
    ctx.restore()

  drawDiamond: (x, y, width, height, color) ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    ctx.save()
    ctx.beginPath()
    ctx.moveTo(x, y)
    ctx.lineTo(x - width/2, y + height/2)
    ctx.lineTo(x, y + height)
    ctx.lineTo(x + width/2, y + height/2)
    ctx.closePath()
    ctx.fillStyle = color
    ctx.shadowColor = "rgba(0,0,0,1)"
    ctx.shadowBlur = getBlurValue(me.circleRadius)
    ctx.shadowOffsetX = 0
    ctx.shadowOffsetY = 0
    ctx.fill()
    ctx.restore()

  drawSpade: (x, y, width, height, color) ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    ctx.save()
    bottomWidth = width * 0.7
    topHeight = height * 0.7
    bottomHeight = height * 0.3
    ctx.fillStyle = color
    ctx.shadowColor = "rgba(0,0,0,1)"
    ctx.shadowBlur = getBlurValue(me.circleRadius)
    ctx.shadowOffsetX = 0
    ctx.shadowOffsetY = 0

    ctx.beginPath()
    ctx.moveTo(x,y)

    ctx.bezierCurveTo(x, y + topHeight/2, x - width/2, y + topHeight/2, x - width/2, y + topHeight)
    ctx.bezierCurveTo(x - width/2, y + topHeight * 1.3, x, y + topHeight*1.3, x, y + topHeight)
    ctx.bezierCurveTo(x, y + topHeight*1.3, x + width/2, y + topHeight*1.3, x + width/2, y + topHeight)
    ctx.bezierCurveTo(x + width/2, y + topHeight/2, x, y + topHeight/2, x, y)
    ctx.closePath()
    ctx.fill()

    ctx.beginPath()
    ctx.moveTo(x, y + topHeight)
    ctx.quadraticCurveTo(x, y + topHeight + bottomHeight, x - bottomWidth/2, y + topHeight + bottomHeight)
    ctx.lineTo(x + bottomWidth/2, y + topHeight + bottomHeight)
    ctx.quadraticCurveTo(x, y + topHeight + bottomHeight, x, y + topHeight)
    ctx.closePath()
    ctx.fill()
    ctx.restore()

  drawClub: (x, y, width, height, color) ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    ctx.save()
    circleRadius = width * 0.3
    bottomWidth = width * 0.5
    bottomHeight = height * 0.35
    ctx.shadowColor = "rgba(0,0,0,1)"
    ctx.shadowBlur = getBlurValue(me.circleRadius)
    ctx.shadowOffsetX = 0
    ctx.shadowOffsetY = 0
    ctx.fillStyle = color

    ctx.beginPath()
    ctx.arc(x, y + circleRadius + (height * 0.05), circleRadius, 0, Math.PI * 2, false)
    ctx.fill()

    ctx.beginPath()
    ctx.arc(x + circleRadius, y + (height * 0.6), circleRadius, 0, Math.PI * 2, false)
    ctx.fill()

    ctx.beginPath()
    ctx.arc(x - circleRadius, y + (height * 0.6), circleRadius, 0, Math.PI * 2, false)
    ctx.fill()

    ctx.beginPath()
    ctx.arc(x, y + (height * 0.5), circleRadius/2, 0, Math.PI * 2, false)
    ctx.fill()

    ctx.moveTo(x, y + (height * 0.6))
    ctx.quadraticCurveTo(x, y + height, x - bottomWidth/2, y + height)
    ctx.lineTo(x + bottomWidth/2, y + height)
    ctx.quadraticCurveTo(x, y + height, x, y + (height * 0.6))
    ctx.closePath()
    ctx.fill()

    ctx.restore()

  drawHeart: (x, y, width, height, color) ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    ctx.save()
    ctx.shadowColor = "rgba(0,0,0,1)"
    ctx.shadowBlur = getBlurValue(me.circleRadius)
    ctx.shadowOffsetX = 0
    ctx.shadowOffsetY = 0
    ctx.beginPath()
    topCurveHeight = height * 0.3
    ctx.moveTo(x, y + topCurveHeight)
    ctx.bezierCurveTo(x, y, x - width/2, y , x - width/2, y + topCurveHeight)
    ctx.bezierCurveTo(x - width/2, y + (height + topCurveHeight)/2 , x, y + (height + topCurveHeight)/2, x, y + height)
    ctx.bezierCurveTo(x, y + (height + topCurveHeight)/2, x + width/2, y + (height + topCurveHeight)/2, x + width/2, y + topCurveHeight)
    ctx.bezierCurveTo(x + width/2, y, x, y , x, y + topCurveHeight)
    ctx.closePath()
    ctx.fillStyle = color
    ctx.fill()
    ctx.restore()

  redraw: () ->
    _g.context.clearRect(0, 0, _g.canvas.width, _g.canvas.height)
    this.draw()

  draw: () ->
    me = this
    ctx = _g.context
    canvas = _g.canvas
    img = new Image()
    img.onload = () ->
      ctx.save()
      pattern = _g.context.createPattern(img, "repeat")
      ctx.fillStyle = pattern
      ctx.beginPath()
      ctx.rect(0, 0, canvas.width, canvas.height)
      ctx.fill()
      ctx.shadowColor = "rgba(0,0,0,1)"
      ctx.shadowBlur = getBlurValue(me.bgShadowBlur)
      ctx.shadowOffsetX = 0
      ctx.shadowOffsetY = 0
      #inset shadow on top
      ctx.translate(0, -1 * canvas.height)
      ctx.beginPath()
      ctx.rect(0, 0, canvas.width, canvas.height)
      ctx.fill()
      #inset shadow on bottom
      ctx.translate(0, 2*canvas.height)
      ctx.beginPath()
      ctx.rect(0, 0, canvas.width, canvas.height)
      ctx.fill()
      #inset shadow on left
      ctx.translate(-1 * canvas.width, -1 * canvas.height)
      ctx.beginPath()
      ctx.rect(0, 0, canvas.width, canvas.height)
      ctx.fill()
      #inset shadow on right
      ctx.translate(2 * canvas.width, 0)
      ctx.beginPath()
      ctx.rect(0, 0, canvas.width, canvas.height)
      ctx.fill()
      ctx.restore()

      me.drawCircles()

    img.src = @bgImage

_g = new Global()
_drawer = new Drawer()

$ ->
  _g.init()
  _drawer.draw()

  $("#colorSelector").ColorPicker {
    color: '#000000',
    onShow: (colpkr) ->
      $(colpkr).fadeIn(500)
      return false
    onHide: (colpkr) ->
      $(colpkr).fadeOut(500)
      _drawer.redraw()
      return false
    onChange: (hsb, hex, rgb) ->
      $("#colorSelector div").css('background-color', "##{hex}")
      _drawer.mainColor = "##{hex}"
  }

  $("#colorSelector2").ColorPicker {
    color: '#000000',
    onShow: (colpkr) ->
      $(colpkr).fadeIn(500)
      return false
    onHide: (colpkr) ->
      $(colpkr).fadeOut(500)
      _drawer.redraw()
      return false
    onChange: (hsb, hex, rgb) ->
      $("#colorSelector2 div").css('background-color', "##{hex}")
      _drawer.anotherColor = "##{hex}"
  }

  $("#selectorMain").change ()->
    _drawer.main = parseInt($("#selectorMain").val())
    _drawer.redraw()

  $("#selectorSub").change ()->
    _drawer.sub = parseInt($("#selectorSub").val())
    _drawer.redraw()

  $("#dropBox").popover {
    title: "Change background"
    content: "You can change background image to drag some image from you local PC and drop it to this area."
  }

  $("#colorSelector").popover {
    title: "Change main color"
    content: "You can change main color. The main color is circles' color in this canvas now."
  }

  $("#colorSelector2").popover {
    title: "Change sub color"
    content: "You can change sub color. The sub color is spade' color in this canvas now."
  }

  $("#selectorMain").popover {
    title: "Change main shape"
    content: "You can change main shape. The main shape is 'Circle' in this canvas now.<br />&#9824; I recommend you use black for spade shape &#9824;"
    placement: 'left'
  }

  $("#selectorSub").popover {
    title: "Change sub shape"
    content: "You can change sub shape. The sub shape is 'Spade' in this canvas now.<br />&#9824; I recommend you use black for spade shape &#9824;"
    placement: 'left'
  }

  $("#btnSave").popover {
    title: "Save as Image"
    content: "Canvas will be convert to JPEG image and I'll open it in a new window."
    placement: 'left'
  }

  document.getElementById("dropBox").addEventListener 'dragover',(event) ->
    event.preventDefault()

  document.getElementById("dropBox").addEventListener 'drop',(event) ->
    event.preventDefault()
    files = event.dataTransfer.files
    f = null
    for file in files
      f = file
    reader = new FileReader
    reader.onload = () ->
      imageData = reader.result
      _drawer.bgImage = imageData
      _drawer.redraw()
    reader.readAsDataURL(f)

  $("#btnSave").on 'click', () ->
    img = _g.canvas.toDataURL("image/jpeg", 1.0)
    window.open(img, "_blank")

なんかこういう画像が作れます。
screenshot

cover sample 001

 
 
screenshot

cover sample 002

 
 
screenshot

cover sample 003

何かが悟れそうな画像ジェネレーター

Standard

http://bugcloud.com/worcloud/canvas/3/
 
 

class Block
  constructor:(row, col) ->
    @alive = true
    @row = row
    @col = col
  kill: () ->
    @alive = false

class Grid
  constructor: () ->
    @width = 22
    @height = 22
    winWidth = $(window).width()
    winHeight = $(window).height()
    @totalWidth = winWidth + (@width - (winWidth % @width))
    @totalHeight = winHeight + (@height - (winHeight % @height))
    @cols = Math.ceil(@totalWidth / @width) + 1
    @rows = Math.ceil(@totalHeight / @height) + 1
    @loopCount = @cols * @rows
    @totalWidth = @width * @cols
    @totalHeight = @height * @rows
    @blocks = []
    @blockCollection = []
    for i in [0..(@rows-1)]
      cols = []
      for j in [0..(@cols-1)]
        b = new Block(i, j)
        cols.push b
        @blockCollection.push b
      @blocks[i] = cols
  
  printBlocks: () ->
    str = ""
    for i in [0..(@rows-1)]
      for j in [0..(@cols-1)]
        b = @blocks[i][j]
        str += if b.alive then "□" else "■"
      str += "\n"
    console.log str
  pickupTryCount: 0
  pickup: (width, height) ->
    if @pickupTryCount > 60
      @pickupTryCount = 0
      return null
    else
      @pickupTryCount++
      result = null
      l = @blockCollection.length
      return null if l is 0
      b = @blockCollection[Math.floor(Math.random() * l)]
      if (b.col + width) <= @cols and (b.row + height) <= @rows
        for i in [b.row..(b.row+height-1)]
          for j in [b.col..(b.col+width-1)]
            block = @blocks[i][j]
            unless block.alive
              return this.pickup(width, height)
            else
              result = b
      else
        return this.pickup(width, height)
      @pickupTryCount = 0
      result

class Global
  constructor: () ->
    @canvas
    @context
  init: () ->
    me = this
    @canvas = document.getElementById 'canvas01'
    @context = @canvas.getContext '2d'

class Square
  constructor: (x, y, width, height) ->
    @x = x
    @y = y
    @width = width
    @height = height
    @radius = 3
    @radius2 = 14
    @r = Math.floor(Math.random() * 255)
  render: () ->
    _g.context.beginPath()
    _g.context.fillStyle = "hsla(#{@r}, 100%, 50%, 1)"
    _g.context.rect(@x, @y, @width, @height)
    console.log "x:#{@x}, y:#{@y}, w:#{@width}, h:#{@height}"
    _g.context.fill()
    _g.context.closePath()

_g = new Global()
_grid = new Grid()

$ ->
  $("#canvas01").attr("width", Math.floor($(document).width()))
  $("#canvas01").attr("height", Math.floor($(document).height()))
  _g.init()

  collection = []
  for i in [1.._grid.loopCount]
    collection.push {
      size: {
        col: Math.floor(1 + Math.random() * 4)
        row: Math.floor(1 + Math.random() * 4)
      }
    }
  for i in [1.._grid.loopCount]
    collection.push {
      size: {
        col: 1
        row: 1
      }
    }

  $.each collection, () ->
    block = _grid.pickup(this.size.col, this.size.row)
    unless block is null
      for i in [0..(this.size.row - 1)]
        for j in [0..(this.size.col - 1)]
          bb = _grid.blocks[block.row + i][block.col + j]
          bb.kill()
          newCollection = []
          for b in _grid.blockCollection
            newCollection.push b unless bb is b
          _grid.blockCollection = newCollection

      (new Square((_grid.width * block.col), (_grid.height * block.row), (_grid.width * this.size.col), (_grid.height * this.size.row))).render()
      _grid.printBlocks()

  img = _g.canvas.toDataURL("image/png")
  _g.context.clearRect(0, 0, _grid.totalWidth, _grid.totalHeight)
  $("body").append "<img src='#{img}' />"
  $("#canvas01").remove()

 
 
元ネタはこれです。
http://toyota.jp/86/