Google Street Viewで道案内する

Standard

なんか去年ぐらいに駅から会社までのビデオ撮って道案内コンテンツを作るみたいなのを職場の人がやってて、会社案内とかのページに地図だけあるよりおもしろいけど、ビデオ撮るの大変だなっていうのを大好きなトイレでふと思ったのでストリートビューでやってみました。横浜駅から逗子海岸まで。
 
http://bugcloud.github.com/google-street-view-navi/
https://github.com/bugcloud/google-street-view-navi
 
車酔いした。

jQuery Mobileと一緒に使えるPage Scroller

Standard

デザイナーの人とかけっこう好きな
http://coliss.com/articles/build-websites/operation/javascript/296.html
をjQuery Mobileと一緒に使うと苦しいみたいだったので書きました。
 
 
https://github.com/bugcloud/page-scroll-z
http://bugcloud.github.com/page-scroll-z/
 
全部のaタグを対象にしないで指定できるようにしただけです。ももクロのことはよくわかりません。

Meteor触った

Standard

みんながよってたかってMeteorの釣り記事書くし、よってたかって釣られるので触ってみました。

 
 
インストールの前に
Meteorをインストールする前に簡単な準備が必要です。手元にWindowsマシンしかない場合だけなんですが、その場合はそれをソフマップハードオフに持って行って買い取ってもらいます。たぶん数千円から数万円になるので、それを元手にギャンブルでもして10万円ぐらいになったらMacBook Airを買ってください。なぜならWindowsだと環境を作るだけで時間単価数万円と言われるみなさんの時間がドブに捨てるよりムダになってしまうからです。
 
 
インストール
node.js, npm, mongodbなど、Meteorを動かすために必要な環境がない場合、用意されているインストールスクリプトを走らせるだけですべてのセットアップが完了します。

curl install.meteor.com | /bin/sh
meteor --help

幸せですね。
ボクの環境では、必要そうなものはすでにインストール済みだったのでMeteoraを直接起動するだけで大丈夫でした。

cd ~/src
git clone https://github.com/meteor/meteor.git
alias meteor='/home/nagino/src/meteor/meteor'
meteor --help

 
 
プロジェクトの作成

meteor create i-meet-meteor

このコマンドでひな形が作られます。この状態ですでにハローワールドになっているのでサーバを起動してみます。

meteor
#もしくは
meteor run

http://localhost:3000/ にアクセスすると、Hello Meteor! が表示されています。
 
 
なんか作ってみる

if (Meteor.is_client) {
  //ブラウザ側の処理....
}
if (Meteor.is_server) {
  //サーバサイドの処理...
}
//両サイドの処理...

みたいな感じで書いていくみたいです。CoffeeScriptとかunderscore.jsとかデフォルトで使えます。
つまずいたところは、

  • server
  • public

という名前のディレクトリ以外に配置したファイルは自動的にロードされるところでしょうか。ロード順とか。あと、jQueryプラグインとかを読み込みたいときにサーバサイドでも走ろうとして落ちることがあって、どう回避するのかわかりませんでした。結局プラグインに手を入れて

if (Meteor.is_client) {}

で囲んだりしました。
 
 
デプロイ
https://github.com/bugcloud/i-meet-meteor
Tumblrから画像をとってきて並べるだけのいつものやつを作ったので公開してみます。
MeteorはなんとPaaSをやっていて、herokuとかと同じ感じでコマンドひとつで公開ができてしまいます。

#meteor deploy アプリ名
meteor deploy i-meet-meteor

これで
http://i-meet-meteor.meteor.com/
にアクセスすると、
 
screenshot

screenshot

 
 
公開されています。富豪ですね。

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