2012年8月20日月曜日

Javascript の オブジェクトの操作。

なんか別な事しようと思ってハマッたっつか、面白いから調べてみたよ。

var obj = {foo:"moge"};
var dat = obj;
obj.foo = "bar";

obj = "";
alert(dat.foo); // <- undefined とかを期待したのに、bar って出る。
alert(obj.foo); // <- こっちはundefined と出る。おいおい。


というわけで、こうしなきゃだめ。

var obj = {foo:"moge"};
var dat = obj;
obj.foo = "bar";

obj.foo = undefined;
alert(dat.foo); // <- undefined
alert(obj.foo); // <- undefined

なんか、当たり前のコードになった。
なんか、これ、腑に落ちないよねー。
それが出来るんなら、なんで最初のは undefined にならねーんだっつー話ですよ。
まぁいいか。つか、おかげでなんか今まで書いたコードでメモリ食う理由がわかった気もする。

あと、調べてわかったことは、 var obj ってしたら、 delete(obj) って出来ないということ。
グローバル変数じゃないと、delete 演算子は仕事をしないっつーことのようです。
基本らしいのだけど、基本を知りません。ワタクシ。Oh! No.
 http://nanto.asablo.jp/blog/2008/01/09/2552470#jsdel-target

ここを読むと良くわかりました。

【削除されない見本】
 var obj = {foo:"moge"};
 var dat = obj;
 obj.foo = "bar";

 delete(obj); // <- 削除されない
 alert(dat.foo); // <- bar
 alert(obj.foo); // <- bar

かーらーの、

【削除される見本】
 obj = {foo:"moge"};
 var dat = obj;
 obj.foo = "bar";

 delete(obj); // <- 削除される
 alert(dat.foo); // <- こっちは bar が出る。
 alert(obj.foo); // <-エラーになって alert が出ない。

Javascript の オブジェクトとかは参照渡し!とはいえ、
参照元のオブジェクト自体を削除しても、参照先のプロパティも削除されるわけではなく、
どっちかというと、ギリギリ前に参照していた内容がコピーされる、ということかなぁ?


2012年8月15日水曜日

BPMSync.js にレベルコントローラもつけましたの件。

これもつけないと不便だよなーと思ったので、
最小値、最高値、小節と音符範囲、コールバック関数を指定して、
レベルが変化していくような機能をBPMSync,jsにつけました。
なんか、メンバ変数があとで使いたくなるようなものにしてしまったので、
さらに機能を追加した時に困りそうでたまらないですねー。センスないわ。



デモではさっきのかえるの歌の文字をデカくしていってますが、
このレベルコントローラ単独でも使えますよ。

var hoge = BPMSync(150,16,[]);
   hoge.levelControl(0,127,[0,8],[1,15],function(val){/*do something*/});

みたいにすれば動くはずー。

最初は jQuery の animate と連動したら楽かなーとか、
animate をいじくりまわせばいいかなーとか思ったけど、
めんどくせーから書きました。
30分くらい?のお気楽コーディング。
でも、今回は怠けて、変な文字とか投げられたときの処理してなかったり、
数が減っていくような動きを要求された時にちゃんと動くか確かめなかったり、
まぁ、手抜きですけど、いいんですよ。そんなものは。
加算しか出来ないんだったら、コールバック関数の中でうまいことしてくださいよですよ。ええ。

あとなんかもう一個くらいないとこれ使い物にならねーなっつー機能があったので、
思い出したら追加します。
ここまで出掛かっているのに思い出せない感じ。

思いつきは、ちゃんとメモを取りましょう!

2012年8月14日火曜日

BPMと音符単位で同期させてなんかさせたい時にいい感じの BPMSync.js 作った。

というわけで、さっきの Movietime.js よりかは、
こっちのほうが使い道ありそうな感じがします。
似たようなのを前にどっかで見たんだけど、
失念してしまったので、さっきの勢いでバリバリと書いてみた。



なかなか表現が難しい?のだけど、
1フレームを8分音符と同じにするとか、16分音符と同じにするとかできると、
結構楽チンにかっこいいPV的なものが出来ますよ。

てか、書いたのは良いんだけど、
なんかこれ、 new BPMSync() で最後に渡す配列がイマイチだよね。
まぁ、これ、自分で改造してもらって、配列の中に Object 入れて、
そのオブジェクトによって内部的にさらに何かしらのメソッドゥーとか動かしていけば、
うまい事いくんじゃないかしら?

小節と音符を管理する都合上、配列で表現するとなると、二次元配列ぽくなるのは仕方ないかなぁ。
他になんかうまい方法ねーべかな。

これ、for文とかでぶん回したくなるんだけど、
なんかうまく動かない気がするので、for文じゃなくした。
なんか、this.measure とかせんでも、引数使いまわしてもよかったんだけど、
まぁ、そこら辺は、趣味?管理のしやすさ?クラスなのにメソッドに引数とか入れないのがベターなのかなー?とか、
なんか世間体とかいろいろ考えた結果こうしましたけど、
もっと綺麗にエレガントに素晴らしく出来る人は、Forkしてゴリゴリ修正してください。
むしろ全部作り直してくれてもOKです。

オホホホホ。

FPSとフレームを指定して、なんか動かす Movietime.js を作りました。

Timeline.js って名前にしようとしたら、同じような内容で、同じようなのがあったので笑った。

http://kjirou.net/main/public/js/lib/timeline/test/index.html

で、上記と何が違うかというと、
FPS(Frame Par Seconds) を指定して、
Flashみたいに、特定のフレームになったらなんかを表示するような事ができます。
ちなみに、ちゃんとFPSとか計ってないから、ずれたりしたらごめんね。

jsdoit にコードをアップしました。
なんか、前に作ったアカウントがどのOpenIDプロバイダで登録したかわからなくなったので、
仕方がないからpsychedesire1というアカウントを作ってやりました。

デモでは、指定したフレームが経過したら、
文字が太くなります。



test2 が二番目に来てるけど、500フレーム経過したら動いてねって指示をしているので、
一番最後に動きます。
そこら辺は、機能として、前回の経過フレームに加算する方法で動かすか、
それともそのままの経過フレームで動かすかを選べるようにしたほうが良いかなー。

そのままの経過フレームで動かすほうがよいメリットは、
コードを書き換えなくても、メソッドチェーンのケツにくっつければよいという点。

 hoge.next(0,func1).next(150,func2).next(200,func3);
 0フレーム目→150フレーム目→200フレーム目

となんか作ってて、100フレーム目にもアクション追加したいよ!
ってなった時に、普通にメソッドチェーンのケツに新しいアクションを追加すればよいだけ。

 hoge.next(0,func1).next(150,func2).next(200,func3).next(100,func4);
 0フレーム目→150フレーム目→200フレーム目→100フレーム目




前回の経過フレームに加算する方法だと、

 hoge.next(0,func1).next(150,func2).next(50,func3);
 0フレーム目→150フレーム目(150を指定)→200フレーム目(50を指定 200-150 = 50だから)

と作ってて、100フレーム目にもアクションを追加したいよ!
ってなった時に、

 hoge.next(0,func1).next(100,func4).next(50,func2).next(50,func3);
 0フレーム目→100フレーム目(100を指定)→150フレーム目(50を指定)→200フレーム目(50を指定)

って感じで、書き換えが頻繁になる気がする。
結構、動画を作る立場で考えるに、こういう計算作業は極力やりたくないものでござるので、
あまり経過フレーム加算のパターンを使うことは少ないかなーとか重いつつ。


でもまぁ、メインでフレーム数を管理する変数を用意すれば良いだけなので、
機能を追加するのは、たいした問題ではないのだけれども。
というわけで、早速直した。
Forkしたぜっ!イエイイエイ!



全部作っても一時間もかからなかったぜーい。
動画メインのFlasherもHTML5とかでなんかやる時に、使いやすいと思いますよ。
参考にしたブログ。

メソッドチェーンの作り方 - あと味
http://taiju.hatenablog.com/entry/20100307/1267962826

2012年8月8日水曜日

FizzBuzzってなんだよ。

FizzBuzzってなんぞやと思ったら、世界のナベアツみたいなやつだった。

http://ja.wikipedia.org/wiki/Fizz_Buzz

3で割り切れたら Fizz で、5で割り切れたら Buzz で、どっちでも割れたら FizzBuzz なんだとさ。
出来るだけ短くプログラムを書くのが楽しいらしい。

業務プログラマがFizzBuzz書いたらどうなるか
https://gist.github.com/3292173 

が面白かった。ガッチガチやぞっ!って感じ。

で、なんかとりあえず考えてみた。 Javascriptですけども。

var fizzbuzz = function(num){
    if(typeof(num) !== "number"){return "not a number";}
    if(num < 1){return "input 0 upper";}
    return (!(num % 15) ? "fizzbuzz" : (!(num % 3) ? "fizz" : (!(num % 5) ? "buzz" : num)));
};
 

for(var i = 0;i < 31;++ i){
    alert(fizzbuzz(i));
}


長ぇな。
最初の方の例外処理みたいなの無ければ

var fizzbuzz = function(num){
    return (!(num % 15) ? "fizzbuzz" : (!(num % 3) ? "fizz" : (!(num % 5) ? "buzz" : num)));
};

 
だけでおっけーだけど、 なんか、メンテナンスし辛いよなこれでは。

var fizzbuzz = function(num){
    if(typeof(num) !== "number"){return "not a number";}
    if(num < 1){return "input 0 upper";}
    var fizz = 3,buzz = 5;
    return (!(num % (fizz * buzz)) ? "fizzbuzz" : (!(num % fizz) ? "fizz" : (!(num % buzz) ? "buzz" : num)));
};


これで fizz と buzz の条件が変わってもOKだよねっ!
いやいや、それだったら、

var fizzbuzz = function(num,fizz,buzz){
    if(typeof(num) !== "number"){return "not a number";}
    if(num < 1){return "input 0 upper";}
    return (!(num % (fizz * buzz)) ? "fizzbuzz" : (!(num % fizz) ? "fizz" : (!(num % buzz) ? "buzz" : num)));
};

var fizz = 3,buzz = 5;
for(var i = 0;i < 31;++ i){
    alert(fizzbuzz(i,fizz,buzz));
}


こっちのほうがいいよなぁ。うん。
FizzBuzzっていうゲームなんだから、ルールは関数の外で変わるんだから、こっちのほうが正しい。

グローバルが汚くても良いんなら、

i=0;while(i<31){alert(!(i%15)?"fizzbuzz":!(i%3)?"fizz":!(i%5)?"buzz":i);++i;}

こんな感じじゃね?使いまわせねーし読み辛いけど。78文字くらい。
もっと短くなるんだろうなぁ。凡人はこんなレベルです。

phpでFizzBuzz最短56Byte
http://d.hatena.ne.jp/milieu/20100204/1265305089

PHPだけど、こっちのが短い。
なるほど、割り切れたらベースじゃないほうが結果として短くなるのか。

i=0;while(i<31){alert(i%15?i%5?i%3?i:"fizz":"buzz":"fizzbuzz");++i;}

これで 69文字か。