0

glitchtweet.com作った

2ヶ月ぐらい前に作った。blog書くのめんどくさくて放置してた。

http://glitchtweet.com


俺がやっているような素敵な装飾がついたツイートがだれでもできるwebサービスです。しかも気に入ったのがでるまで何度でもやりなおせる。
iPhoneやAndroidから使うことを想定している。



ライブラリ以外のコードを数えたら、286行しかなかった。
その他は以前作ったテキストに文字装飾を行うglitchtext.jsが500行ぐらい。sinatra、haml、jqueryのおかげでシンプルに書けた。

ソースはここにある
shokai/glitchtweet-web-app – GitHub



以下細かいことなどを書く

■ファイルサイズ
でかい。glitchtext.jsが辞書が巨大すぎて300kb以上ある。けどしょうがないし、まあキャッシュ効くからいいか


■サーバー
さくらVPSのdev.shokai.orgに、virtualhostでglitchtweet.com割り当てて使ってる。


■開発環境
まずglitchtext.jsはv8とRakeで単体でテストをしている。前に書いた
glitchtweet.comのwebアプリ自体はローカルでwebrickで起動して、chromeの開発パネルでjsなどのデバッグをした。あとはiPhoneとAndroidのsafariのブラウザで開いて、見た目を調整した。


■なるべく画面遷移しない
jquery mobileやjQTouchを使うとネイティブアプリ風に外見で、横にスライドして表示を切り替えるwebアプリを作れるけど
面倒だったので使わなかった。visibleをon/offしてtweetボタンを表示したりしなかったり等している。
なのでviewのテンプレートは1つしかない。


■twitterログイン
生成したglitchテキストはoAuthでログインしてtweetされるが、ユーザ情報管理にDBは使っていない。
cookieにtwitterのoauth tokenとsecretを保存している。
最初の画面でログイン済みかどうかは、haml template上でtokenとsecretがあるかどうかだけで表示を分岐しているので、実際glitchtweet.com側では誰がどんなtweetをしているかは把握していない(しようと思えばできる)


■cookieでsession
sinatraでcookieベースのsessionを使うようにしている。
Rack::Session::Cookieを使う – 橋本詳解に書いた。
glitchtweet.comでは2週間cookieで保存するようにしている。
use Rack::Sessioin::Cookieしたらsinatraのsession関数がcookieを使うようになってくれた。
(これで大丈夫ですよね?)


■ホーム画面アイコン

<link href='http://glitchtweet.com/img/icon.png' rel='apple-touch-icon' />
これをheadに書いておくと、iPhoneのホーム画面にブックマーク保存するとアイコンが付く。
Android2.3でもホーム画面にブックマークショートカットを作ったらアイコンが出るようになった。しかも角丸化される。apple-touch-iconって名前なのに処理してくれるAndroidえらい。


■テスト環境にwebrick使うようにした
開発中にSinatra1.2.1が出たのでupdateしたら、thinを使うとhttpリクエスト送った瞬間に問答無用で強制終了するようになった。
webrick使うようにした。
Sinatra1.2.1とthin1.2.10を同時に使うと死ぬ – 橋本詳解


■viewport
@hitoriblogさんに教えてもらった。
適当なhtml/cssを書いていてもiPhoneではそれなりに正しいサイズで表示されるんだけど、Androidではテキストエリアをクリックした瞬間にものすごいズームをされてしまう。
これはviewportをheadに指定しておくとなんとかなる。Androidはデバイスがたくさんあるので、画面サイズが微妙に違うのでwebサービス作ってる人は大変そう。
<meta content='width=device-width, user-scalable=no' name='viewport' /> 
このへんも参考になる。


■shakeイベント
ネイティブアプリではshakeのイベント、つまりiPhone本体を振ったイベントを取得して、undoに使われている。
全く、操作と実行内容の関連付けが最も意味不明な機能だと思う。

でもiOS4.2からsafariでも加速度センサーが使えるようになったので、せっかくだからshakeイベントを取れるjsライブラリを作った。
shokai/js-iphone-shake-event – GitHub

glitchtweet.comでも使っている。tweet後に、もう一度同じソースからglitchしたい時にshakeすると消えた文字が復元される。

これについてはあとで書く。


■iphone-js-console
shokai/iphone-js-console – GitHub
iphone-shake-event.jsを作っている時に、iPhone実機でのデバッグをする為に作った。
パソコンのterminal上でjsを書くと、iPhone上で実行されたり、パソコン上でiPhoneのブラウザ上のjsの値を読み出したりできて便利。

これについてもあとで書く。

0

glitchtext.js作った

作った。https://github.com/shokai/js-glitchtext

ここで試せる → glitchtext.js sample
jsのサイズが圧縮しても385Kbもあるんだけど、9割以上がインターネットをクロールして取得した装飾用顔文字になってしまった。必要ない人は後述するビルド方法に基づいてsrc/plugins/face.jsを除外してビルドするともっと小さくなるはず。


元々は、去年の夏にRubyで作ったglitchtweetというtwitterクライアントがあって、それの機能をJavaScriptに移植したもの。

glitchtweetについてはずっと使ってるんだけどblogに書くの忘れてた。ふつうの発言を入れると適当に装飾・変形させてtweetするもので、20個ぐらいのプラグインがランダムに作用して壊れた文字列を作るというもの。
後輩のぽわわがTogetter – 「奇跡のglitchtweet開幕だ」にまとめてた。


■glitchtext.jsの使い方
まずTinySegmenterとglitchtext.jsを読み込んで

<script src="tiny_segmenter-0.1.js" type="text/javascript" />
<script src="glitchtext.js" type="text/javascript" />


javascriptでGlitchTextオブジェクトを作って、randomすると適当にランダムに変形される。
2〜3回randomを繰り返すとより強力に変形する。
var g = new GlitchText();
var source = '今日はかずすけ楽しかったねー また遊ぼうねー 今度はお弁当持って行こう';
var result = g.random(source);
もしくはglitch_を先頭に持った関数で任意の変形ができる。関数の一覧はmethods()関数で取得できる。

TinySegmenterが無くても動くが、いくつかのプラグインが有効化されない。



工夫したことについて書いておく

■プラグイン
今のところ、22のプラグインが入っている。
こんな感じ
glitch_addspace : こ こ に ソ ー ス 置 い た   h t t p s : / / g i t h u b . c o m / s h o k a i / j s - g l i t c h t e x t
glitch_atai : \ここにソース置いた https://github.com/shokai/js-glitchtext/
glitch_cmabridge : ここにーソスい置た htpts://github.com/shokai/js-giltchtext
glitch_double : ここにソース置いた https://github.com/shokai/js-glitchtext ここにソース置いた https://github.com/shokai/js-glitchtext
glitch_doubleChar : ここここににソソーースス置置いいたた hhttttppss::////ggiitthhuubb..ccoomm//sshhookkaaii//jjss--gglliittcchhtteexxtt
glitch_dullness : ごごにゾーズ置いだ https://github.com/shokai/js-glitchtext
glitch_face : ここにソース置いた https://github.com/shokai/js-glitchtext ォヵェリ☆彡..._〆(`・∀・´o)
glitch_fill140 : ここにソース置いた https://github.com/shokai/js-glitchtextここにソース置いた https://github.com/shokai/js-glitchtextここにソース置いた https://github.com/shokai/js-glitchtext
glitch_hiragana : ここにそーす置いた https://github.com/shokai/js-glitchtext
glitch_hirakata : ココニそーす置イタ https://github.com/shokai/js-glitchtext
glitch_ignoreSearch : こ/こ/に/ソ/ー/ス/置/い/た/ /h/t/t/p/s/://///g/i/t/h/u/b/./c/o/m///s/h/o/k/a/i///j/s/-/g/l/i/t/c/h/t/e/x/t
glitch_insertWave : こ〜こに〜ソー〜ス置〜いた h〜ttp〜s://g〜ithu〜b〜.com/shok〜a〜i/j〜s-g〜litch〜text
glitch_kaibu : ここにソース置いた https://github.com/shokai/js-glitchtextxethctilg-sj/iakohs/moc.buhtig//:sptth たい置スーソにここ
glitch_katakana : ココニソース置イタ https://github.com/shokai/js-glitchtext
glitch_kirakira : .'。:。'★。.:゜。*:*゜*'ここにソース置いた https://github.com/shokai/js-glitchtext'*゜*:*。゜:.。★'。:。'.
glitch_linePrefix : ────ここにソース置いた https://github.com/shokai/js-glitchtext
glitch_reverse : txethctilg-sj/iakohs/moc.buhtig//:sptth たい置スーソにここ
glitch_sekine : ここにショーシュ置いた https://github.com/shokai/js-glitchtext
glitch_speak : (ここにソース置いた https://github.com/shokai/js-glitchtext)
glitch_updown : ここにソー↓ス↑置いた ↓h↑t↓tps://g↑i↓t↑hub.com/shoka↓i↑/↓j↑s-gli↓tch↑t↓e↑xt
glitch_vertical_reverse : ここにソース置いた ɥʇʇds://bıʇɥnb.ɔoɯ/sɥoʞɐı/ظs-b1ıʇɔɥʇǝxʇ



■Rakeでビルドする
RakeはRubyで書けるMakefile。

今回は文字列を操作する関数をたくさん作りたかったが、1つのjsファイルに追記していくとメンテナンスがしづらい。
動作テストまでは関数群はpluginsディレクトリに置いてあって、リリース時にRakeで一つのglitchtext.jsに合体させる様にした。

今までJSのオブジェクト指向的な機能はあまり使ったことがなかった。
忘れないうちにメモしておく
  • 先にクラスを定義しておけば後からprototypeで関数を追加できる
  • for(i in object)でオブジェクトのメソッドの名前のリストを取れる
  • メソッド名がわかれば、object[メソッド名]()で関数を実行できる
  • メソッドとプロパティの区別があまり無いので高階関数が簡単に作れる
  • if(typeof hoge == ‘function’)でプロパティかメソッドか判別できる
このへん今回重要だった。



■TinySegmenterでcmabridge
cmabridgeというプラグインにTinySegmenterを使った。TinySegmenterはJavaScriptで実装されたわかち書きエンジンで、つまり日本語を単語レベルに分割してくれる。

cmabridgeはcambridge大学で発見されたという人間の認知の穴を突いた手法。単語中の隣接する1文字が入れ替わっていてもなぜか文章として読めてしまうというもの。
こんなの↓
日今はかずけすし楽かったーね たま遊ぼうーね 度今はお弁持当ってこ行う
tinysegmenterでは品詞は分類できないが、この用途には十分だった。
あとArray.prototype.mapにRubyのArray.mapを追加したので、メソッドチェーンでどんどん文字列操作できて書いてて楽しい。



■デバッグ
chromeのjsエンジンのv8を使った。Macでは
brew install v8
でインストールできる。v8はchromeの開発パネルみたいにどのファイルの何行目でエラーが起こったかを確かめられるので良い。

glitchtext.jsは、文字列を入れたら文字列を返す関数をたくさん作る必要があったので、ブラウザでデバッグするよりもterminalからたくさん文字を入れてまとめてテストできるようにした方が効率的だったので使ってみた。
rake test
すると、プラグインディレクトリとテストコードのディレクトリを総ざらいしてこんな風に実行する
v8 /Users/sho/src/js/glitchtext/libs/tiny_segmenter-0.1.js /Users/sho/src/js/glitchtext/src/glitchtext.js /Users/sho/src/js/glitchtext/src/plugins/addspace.js /Users/sho/src/js/glitchtext/src/plugins/atai.js /Users/sho/src/js/glitchtext/src/plugins/cmabridge.js /Users/sho/src/js/glitchtext/src/plugins/double.js /Users/sho/src/js/glitchtext/src/plugins/double_char.js /Users/sho/src/js/glitchtext/src/plugins/dullness.js /Users/sho/src/js/glitchtext/src/plugins/face.js /Users/sho/src/js/glitchtext/src/plugins/fill140.js /Users/sho/src/js/glitchtext/src/plugins/hiragana.js /Users/sho/src/js/glitchtext/src/plugins/hirakata.js /Users/sho/src/js/glitchtext/src/plugins/ignore_search.js /Users/sho/src/js/glitchtext/src/plugins/insert_wave.js /Users/sho/src/js/glitchtext/src/plugins/kaibun.js /Users/sho/src/js/glitchtext/src/plugins/katakana.js /Users/sho/src/js/glitchtext/src/plugins/kirakira.js /Users/sho/src/js/glitchtext/src/plugins/line_prefix.js /Users/sho/src/js/glitchtext/src/plugins/reverse.js /Users/sho/src/js/glitchtext/src/plugins/sekine.js /Users/sho/src/js/glitchtext/src/plugins/speak.js /Users/sho/src/js/glitchtext/src/plugins/updown.js /Users/sho/src/js/glitchtext/src/plugins/util.js /Users/sho/src/js/glitchtext/src/plugins/vertical_reverse.js /Users/sho/src/js/glitchtext/test/test.js

v8は、引数に複数のjsファイルを指定できて、先に指定した物から読み込まれる。先にGlitchTextクラスの定義を読み込んで、続けてプラグインを読み込んでGlitchTextクラスをprototype拡張し、最後にテストコードを実行している。

こうすると、どのプラグインの何行目でエラーが起きたかがちゃんとv8が教えてくれる。複数のプラグインを試行錯誤しながら作っている場合でも、できた物からgitにcommitできるし、別のパソコンで他のプラグインが欠けている状態からでもテストを実行できる。


■ビルド
v8に渡したのと同じく、glitchtext本体→プラグインの順にjsファイルを連結させれば単体の.jsファイルにできる。
jsminを使うとjsファイルを圧縮できた。
Macではhomebrewでインストールできる。
brew install jsmin
jsmin < input.js > output.js