tech memorandom

Webに関して調査したことや、メディアアート系(Max,Processing)で調査したことなどを書いていきます。

emacs js2-modeのUndeclared variableについて

javascript-modeからjs2-modeに変えてみた。fly-makeなどを使わなくてもエラーチェックを行なってくれるしすごく良い感じ。
しかし1つ困った点があってUndeclared variableがechoされつづけてしまう。そういった変数が存在すること自体は確かに問題であるけど、別ですでに定義済みだったりすると常に出続けてしまうと思われる。

検索などができない状態なので表示をとめることにした。
正しい処置とは思わないし、他に設定がありそうも気にするけど暫定処置としてコメントアウト。
これでいちおUndeclared variableのワーニングがて続ける、という状態から開放されます。

メモがてら残しておきます。

js2.elの7000行あたりです。

(defun js2-highlight-undeclared-vars ()
"After entire parse is finished, look for undeclared variable assignments.
We have to wait until entire buffer is parsed, since JavaScript permits var
decls to occur after they're used.

If any undeclared var name is in `js2-externs' or `js2-additional-externs',
it is considered declared."
(let (name)
(dolist (entry js2-recorded-assignments)
(destructuring-bind (name-node scope pos end) entry
(setq name (js2-name-node-name name-node))
(unless (or (member name js2-global-externs)
(member name js2-default-externs)
(member name js2-additional-externs)
(js2-get-defining-scope scope name))
(js2-set-face pos end 'js2-external-variable-face 'record)
;; (js2-record-text-property pos end 'help-echo "Undeclared variable")
(js2-record-text-property pos end 'point-entered #'js2-echo-help))))
(setq js2-recorded-assignments nil)))

参考まで。

補足)
warningがでるのはコードが悪いんだろうと思っていたのですがどこかみつからず悩んでいたのですがコンストラクタ定義の際の型がぬけていました。そしてそういった変数はオレンジ色で表示してくれます。問題なく動作していたのでついつい見逃していました。

修正前

Hoge = function (){
   hoge;
}

修正後

var Hoge = function (){
   hoge;
}

FreeのCDN cloudflareを使ってみた。

前回、herokuを使って無料でサイトをつくる記事をかきました。実際運用して気づいたのですが、サーバがアメリカにあるため、画像の読み込みが激遅です。当初、画像だけdropboxとかpicsaにおこうかと思ったのですが、無料で使えるCDNがあったりするんじゃないかと思ってみてさがしみたらcloudflareというサービスがありました。このサービスの利用は超簡単で、DNSの設定をcloudflareが提供するDNSに変更するだけです。サイトのアカウントをつくるとばーっと説明するムービが2分ほど流れます。このへんに実際やってみた記事とかがのっています。

結果は実際にかってはいないのですが、体感でわかるレベルぐらい違います。

 

こっちがdirectでアクセスした場合のサイトです。

CDN経由でアクセスした場合はこっちです。

 

このサイトは画像を70枚ぐらい読み込んでcss3でアニメーションさせているのですが、画像のロードがかなり重かったのが悩みでしたがこれで解消できました。

転送量などに特に制限はないようですが、SSLなどを使う場合は月額2000円ほど払う必要があるようです。それでもだいぶやすいですね。

よかったらためしてみてはいかがでしょうか。

Perfume-Dev Hack

最初はモーションキャプチャーしたデータをサイトで動かすだけかと思いきや、どんどん進化して楽しい感じなっています。perfume-global。そしてそのコードはgithubで公開されています。

現在はVol.4までで登場していてます。Vol.1はモーションをパーティクルで表示しただけだったものが、いくつかのシリーズを得てVol.4はPerfume本人たちのダンスを3次元加工しています。最終的にはやくしまるえつこのサイトでやったように360度まわせるコントローラーでもつけたりするんじゃないかとか期待してしまいます。

PerfumeがGlobal進出するにあたり、世界共通言語であるコードを使って世界を表現し、それを公開することで、言語や文化の障壁を超え話題にしたくなるものをつくりだしたそうとした、そんな意図感じずにはいられません。

Perfume-GlobalのサイトにはPerfumeの声入りの音声は一切流れていませんし、彼女たちの顔すらだしていません。

最初は肖像権や版権の問題かとも思ったのですが、コードつかったプロモーション戦略にそういったものは、むしろないほうがメッセージがストレートに伝わるから、あえてだしてないのかもしれません。いつかはだすでしょうが、それは十分に興味をひきつけたあとになるんじゃないかと想像しています。

その時、どんな音や映像を流すのかちょっと想像できないですが、一流のクリエイター、プロモーターが市場をみて導き出した答えであることは間違いないので、その時にでてくるものと世界の反応を楽しみにしています。

で、大げさなタイトルのHackについてでですが、やったことはパーティクル人間をロボットにしただけです(´・ω・`)
あんまり時間がなかったので手軽なProcessing版でやってました。

p5f_sample.pdeはカメラのアングルとか背景の動きが書かれています。このへんは面倒くさかったので全くさわっていません。音にあわせてカメラとか動かせば楽し感じになったと思いますが、これに時間かけていると怒られるのでやめました。

パーティクルの描画を別のオブジェクトに置き換えるには、PBvh.pdeに手を入れる必要があります。

BvhParserがBVデータを読み込んでくれ、かつデータにアクセスするためのAPIを用意してくれています。
getName()というAPIがあり、これをたたくと、どの部分のBVデータかを取得することができます。
今回は頭をかえてましました。getName()がHEADだったらHeadイメージを描画しています。
BvhParserのJavaDocも公開されており、これをよむと色々できます。

できた動画はこんな感じです。

public class PBvh
{
  public BvhParser parser;
  public PImage img;
  public PImage imgHead;
  
  public PBvh(String[] data)
  {
    parser = new BvhParser();
    parser.init();
    parser.parse( data );
    img = loadImage("robo_head.png");
    imgHead = loadImage("head.png");
    
  }
  
  public void update( int ms )
  {
    parser.moveMsTo( ms );//30-sec loop 
    parser.update();
  }
  
  public void draw()
  {
    fill(color(255));
    
    for( BvhBone b : parser.getBones())
    {
      String head = "Head";
      String name = trim(b.getName());      
      pushMatrix();
      translate(b.absPos.x, b.absPos.y, b.absPos.z);
      image(img, 0, 0);
      popMatrix();
      if (head.equals(trim(b.getName())))
      {
        pushMatrix();
        translate( b.absEndPos.x, b.absEndPos.y, b.absEndPos.z);
        image(imgHead, 0, 0);
        popMatrix();
      }
        
    }
  }
}

coffeescriptでflymake

coffee書いているとたまにインデントをミスってあとで苦い思いしながら修正ってことが多かったのでflymakeで
事前にSyntaxエラーをわかるようにしてみました。わりと快適になったのでなんとなく共有。

(when (require (quote flymake) nil t)

(defadvice flymake-post-syntax-check (before flymake-force-check-was-interrupted)
(setq flymake-check-was-interrupted t))
(ad-activate 'flymake-post-syntax-check)
  (when (not (fboundp 'flymake-php-init))
    ;; flymake-php-initが未定義のバージョンだったら、自分で定義する
  (defun flymake-coffee-init ()
    (let* ((temp-file   (flymake-init-create-temp-buffer-copy
                         'flymake-create-temp-inplace))
           (local-file  (file-relative-name
            temp-file
                         (file-name-directory buffer-file-name))))
      (list "coffee" (list "-bc" local-file))))
      (push '(".+\\.coffee$" flymake-coffee-init) flymake-allowed-file-name-masks)
      (push '("\\(Error: In \\([^,]+\\), .+ on line \\([0-9]+\\).*\\)" 2 3 nil 1) flymake-err-line-patterns)
(add-hook 'coffee-mode-hook
          '(lambda () (flymake-mode t)))

    ;;エラー行をmini bufferに表示
      (global-set-key "\M-e" 'flymake-goto-next-error)
      (global-set-key "\M-E" 'flymake-goto-prev-error)
    ;; gotoした際にエラーメッセージをminibufferに表示する
    (defun display-error-message ()
      (message (get-char-property (point) 'help-echo)))
    (defadvice flymake-goto-prev-error (after flymake-goto-prev-error-display-message)
      (display-error-message))
    (defadvice flymake-goto-next-error (after flymake-goto-next-error-display-message)
      (display-error-message))
    (ad-activate 'flymake-goto-prev-error 'flymake-goto-prev-error-display-message)
    (ad-activate 'flymake-goto-next-error 'flymake-goto-next-error-display-message)

他おすすめなlispは、HighlightIndentationとかもいいです。
indentの可視化ができます。ただインデントが深いコードをひらくとかなり重たくなるので常時使用はちょっと厳しいです。

追記)
すでにこんなのがあるよ!とFacebookに同僚に教えてもらいました。こっちつかったほうがいいかもしれません。
https://github.com/purcell/flymake-coffee


(CoffeeScrpitについて余談)
Coffeescriptって、javascriptを短く書くためのものみたいな感じでサイトでふれまわったせいか、
短く書くためにcoffeescriptを使うみたいなイメージが強かったりするんじゃないかと思う。

実際使ってみて思うのは短く書くためのツールというより、
Javascriptをオブジェクト思考らしく書けるようにしたもの、という印象が強い。
生成されるJSのコードがとてもメンテできないものか、というとそうでもない。

JSのプロトタイプ型オブジェクト思考をちゃんと理解している人が書きそうなコードが生成される。
extendsとか使うとちょっとごちゃごちゃするけど、それもJSで継承をちゃんと書ける人なら読めるコードだと思う。
むしろ、Coffeeeが生成したコードを読んで逆に理解を深めたぐらい。

CoffeeScriptのいいところ、逆にいうとJavaScriptの危ないところを丁寧解説していて、
それらを保管するためにCoffeeScriptでとったアプローチがちゃんと書かれているのでCoffescriptに興味を持たれた方は一読されてみてるといいかもしれません。

The Little Book on CoffeeSript

これの1.〜3.まで読むとCoffeeScriptがなぜ生まれたのか、なぜ有意義なのか、ちょっとわかると思います。

JavaScriptについて骨の髄まで理解したエンジニアではないので、CoffeeScriptってこうゆう見方もあるよ、
ぐらいにうけてとめてもらえると幸いです。

herokuをつかってドメイン代だけサイトを公開する方法

6月にパーティをやるのですが、そのwebサイトをheroku上に置くことにしました。

選んだポイントは以下の点が無料でできるからです。

  1. 高速
  2. カスタムドメインの割り当て
  3. gitによるバージョン管理
  4. コラボレーション(他の開発者との共同作業)などを簡単に実現できる
  5. AWS上にあるのでAWSインスタントと通信してもトラフィック請求が発生しない。
 
これらのことがドメイン代費用だけ(年間800円)できるのは活気的です。
ロリポップなんて借りてる場合ではないです。
 

herokuの利用するにはまずherokuにアカウント登録をする必要があります。

そのあとアプリを作成します。そのあたりは以下のリンクをみると詳しく書かれています。

https://devcenter.heroku.com/articles/quickstart

 
作成したアプリのドメイン登録はかなり簡単です。
ドメイン管理サイトでドメインを取得します。
今回は以下のサイトから取得しました。
 
 
 
続いて、herokuのproxyのDNSの設定を行います。
herokuアプリを作成するとheroku用のURLがわりあてられるので、CNAMEとしてそのURLを登録するのもありだと思いますが、
DNSの変更を行うと反映時間がかかるのでproxyのAレコードを追加ほうがおすすめです。
 
以下のAレコードを追加します。このアドレスはheroku共通のproxyサーバのアドレスなのですが、
これを設定しておけば、あとはheroku側でサブドメインの設定などもできます。
 
ちなみにfc2の場合、Aレコード追加UIがなぜかホストが必須項目でした。
@マークをいれておけばいいみたいです。
 
 
75.101.163.44
75.101.145.87
174.129.212.2
 ドメインの登録は超簡単で以下のコマンド打つだけです。Web GUIからも登録できます。
$ heroku domains:add www.example.com Added www.example.com as a custom domain name to myapp.heroku.com

 ドメインの反映ができたタイミングでwww.example.comにアクセスするとherokuで作成したアプリが表示されます。

$ heroku domains:add *.example.com Added *.example.com as a custom domain name to myapp.heroku.com

Webサイトを共同開発したい場合ですが、以下のコマンドをうつことで他のメンバーもheroku上のgitにアクセスできるようになります。

$ heroku sharing:add joe@example.com 

 他のメンバーがherokuユーザでなければ、herokuの登録をしてもらいます。このあたりもinvite mailを自動で送ってくれるので説明の手間がはぶけます。

他のユーザは、作成済みのherokuアプリをcloneしてもらいます。

 

$ git clone -o heroku git@heroku.com:theirapp.git

 

 あとは通常のgitの運用と同じなのですが、一点違う点は、masterにpushすると自動でdeployされる点です。

わりと手の込んだサイトをつくる場合、いきなり本番にでてしまうとまずい場合もあると思います。

その場合はもうひとつ開発用のherokuアプリをつくることで解決できます。

 

開発である程度動作確認したものを本番ドメインを割り当てたheroku appにpushといった流れになるかと思います。

Webサイトを公開する場合ですが、今回つくりたいような場合はpublicディレクトリさえあればよかったりします。

lokkaのデザイナーのmachidaさんがそんな要望みたしてくれるひな形を公開してくれています。

 

  1. 記事 http://kuroigamen.com/22
  2. ひな形 https://github.com/machida/kuroigamen-sandbox

 

このひな形ですが、sinatraを使っています。

http://www.sinatrarb.com/

 

sinatrarubyで書かれたフレームワークなのですが、シンプルかつ拡張しやすいので、

とっかかりには最適だと思います。 

このひな形をcloneしてきて、あとはpubicディレクトリにhtmlやcssをいれてherokuにpushすると公開されます。

 

記事をたくさんいれたいからCMSをおきたい、という場合は、lokkaがおすすめです。

lokkaは、sinatraをベースつくられたwordpressのようなCMSです。

完成度はwordpressには落ちますが、herokuに簡単にdeployできる点がポイント高いです。

 

http://lokka.org/

 

lokkaをいれたい場合は、上述のインストール方法に従いアプリを作成します。

 

blog.hoge.comみたいな感じで上述のような手順でアプリを追加することができます。

ここで書いた手順は、流れの大枠しか書いていないので参考程度に。

まよったらherokuのドキュメントを直接みてください。  

 

Virtual boxのNAT経由の外部接続について

かなり久しぶりの更新です。


私物のMacでWebアプリケーションの開発を行うことが多いのですが、MacにLAMP環境をいれたりすることに抵抗があるので、なるべくVirtual Boxを上で開発を行うようにしています。

Virtual Boxは無料のVMなのですが、制限なく使えるし、Windowsも動作します。動作もわりと軽いのでかなり重宝しています。

 

Virtual Boxを使う際ですが、ネットワーク環境がかわっても接続できるように以下のような設定をしています。


 外部接続用  NATアダプタ

   内部接続用  host-onlyアダプタ


他にBridge接続というゲストOSにIPアドレスを割り当てる方法があるのですが、これを使う2つのIPアドレスを取得することになり、モバイルルーターなどで外で使う場合かなり不便します。特に一旦ブラウザで認証するような公衆無線Lan環境下ではゲストOS内でブラウザをたちあげる必要があり、x windowなどいれていないsever版などではかなり難儀したので使用を封印し、外部アクセスはNAT経由のみにしています。


NAT経由でもポートフォワードの設定をいれることで、ssh接続は設定すれば可能なのですがその設定が面倒なのとmysqlなどの接続時にわざわざポートフォワードするはめになり不便なので、ホストOSとゲストOSの通信はhost-onlyアダプタを利用しています。


NAT使って接続する 場合、本来であれば、家からオフィスに移動してもホストOSをルータに接続しにいくので、外部接続はゲストOSのネットワーク設定さえ切り替わっていればそのままつながるはずですが、時々つながらないことがありました。ネットワークを再起動すると名前解決できるようになるのですが、これではNATを使っている意味がありません。

 

まあ、networkの再起動すると修正されるのですが面倒です。我慢していたのですが、いい加減いらいらいして調べてみることしました。動作させてみてわかったのは、外にはIP直指定であれあば外にでるが、名前解決ができない、という状態になっていました。

 

/etc/resolvedをみたところ、ルータのアドレスを参照するようになっていました。


ホストOSが参照しているネームサーバーになっていたので、linuxのネームサーバをgoogle public DNSに変えたところ、名前解決できるようになりました。

 

わーい!

 

念のためテストするかと再起動したらまた/etc/resolvedの記述が再びルータのアドレスになっていました。

どうやら起動時にVMがホストOSが参照しているネームサーバに勝手に書き換えてしまうようです。

 

Virutal Boxのドキュメントなんて全く読む気になりませんが読んだらきっと書いてあるのでしょうが、驚くべき動きです。


ホストOSのネットワーク設定も、ネームサーバをネットワークに依存しないものにしておく必要があるようです。

 

プロバイダからもらったネームサーバをちゃんと登録している方は、こんなことにはまらなかったのかもしれません。

その設定が無意味だと勝手に思っていたので私はルータのみnameseverにしていたのでこんな惨劇がおきました。

 

というわけで、ホストOSのネームサーバをgoogle dnsに変更することにしました。(追加でもいいと思います)


これで、VM再起動後も無事ネットワークが変わっても外にでれるようになりました。


同様の現象がおきている人は、ホストOSのネームサーバーにGoogle Public DNSを足すと幸せになります。

 

https://developers.google.com/speed/public-dns/

 

ちなみにVM使わない派の人でもGoogle Public DNSをnamseverに指定すると名前解決がだいぶ早くなります。

ネットの体感速度があがるので是非追加されることをおすすしておきます。

 

Processing サブディスプレイでフルスクリーンする方法

別blogからの移転記事です。

 

ProcessingはJavaを描画に特化したような言語でちょっとプログラムかける人にとってはとても使いやすいメディアアートのツールです。MaxやJitterもオブジェクトをパッチすることで表現することができる素晴らしいツールなのですが、演算処理やデータ処理を書こうと思うと途端にややこしくなります。オブジェクトをJSやJavaで書くこともできるのですが、inlet,outlet,bang周りがどうも扱いづらくてあまり使う気になれませんでした。

 

ただProcessingでVJのような映像やろうとした場合、サブディスプレイでフルスクリーンをすることができない、という他の映像ソフトではちょっと考えられない欠点があります。


Processingでサブディスプレイにフルスクリーンで表示する方法を調査してみした。

ProcessingはJavaをラッパーしたようなものなので、Javaのawtパッケージを使うことでなんとかなりました。

(本当はこういった仕組みをprocessingにいれてほしいのですが・・・)

 

ひとまず動いたので共有します。

だいぶ前の記事なので動かなかった本当ごめんなさい。

 

import java.awt.*;

Rectangle monitor = new Rectangle();
boolean bSubdisplay = true;

void setup() { 
  GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
  GraphicsDevice gs = ge.getScreenDevices();  
  GraphicsDevice gd = gs[0];
  
  //サブディスプレイがある場合は上書き
  if (gs.length == 2 && bSubdisplay)
  {
    gd = gs[1];
  }
  
  GraphicsConfiguration gc = gd.getConfigurations();
  monitor = gc[0].getBounds();

  println(monitor.x + " " + monitor.y + " " + monitor.width + " " + monitor.height);
  size(monitor.width, monitor.height);
  background(0);
}

void draw() {
  frame.setLocation(monitor.x, monitor.y);
  frame.setAlwaysOnTop(true); 
  stroke(255);
  line(0,0,width,height);
}  

public void init() {
  frame.removeNotify();
  frame.setUndecorated(true);
  super.init();
}