日曜日, 9月 16, 2012

Designing Tumblr

Tumblr解説本、Designing Tumblrを献本していただきました。ありがとうございます。僕が関わったKAKATO梅川良満さんのTumblrも紹介してもらってます。あとthirozumiさんのページで投稿されてるのが僕のTEE PARTYの商品です。

で、KAKATOで使ったURLをランダマイズするスクリプトの掲載部分が中途半端だったので、補足しておきます。urls配列に入れたURLをダウンロードボタンとして使っているa要素(id="downloadURL")にセットするところ。

var urls = ["ダウンロードURL1","ダウンロードURL2","ダウンロードURL3"];
var a = document.getElementById("downloadURL");
a.href = urls[Math.floor(Math.random() * urls.length)];

アップロード先のサーバが混雑してたり落ちてたらURLだけ分散しても意味ないので、実際にこのような目的で使う場合はアップロード先も分散しておいた方がよいと思います。

本当は技術的なレビューとか面白いTumblrのセレクションで参加する予定だったのですが忙し過ぎで何一つできなかったので、代わりにと言うか何と言うか、せっかくなので書籍を参考にTumblrのテーマを作ろうかと思います。

今まではCustomizeのEdit HTMLで編集してた(もしくはローカルのHTMLからコピー&ペースト)んだけどストレス溜まるので、ローカルで開発環境を整えたい。

書籍にはfumblrが紹介されてたんだけど、環境の問題かすんなり動かなかったので深追いせずにThimbleを使うことにした。PHP製なのでXAMPPとかですぐ動かせる。どっちも微妙に古くて新しいタグに対応してなさそう。仕組みとしてはテンプレートタグをパースしてるだけっぽいので、自分で拡張すればよいかも。とりあえずforkしておいた。

日曜日, 8月 26, 2012

CSS3のbackground-sizeプロパティを試す

CSS3で追加されたbackground-sizeプロパティに、contentかcoverを指定すると画像をウィンドウいっぱいに表示してくれるので、写真をでかく見せたい場合に使えそう。

Perfect Full Page Background Image

JavaScriptで切り替えられるようにしてみた。Chrome推奨です。
動作サンプル
https://gist.github.com/3473035

addEventlistenerのとこ、以前だったら何も考えずimg要素それぞれにイベントリスナーを登録してしまっていたけど、バブリングを利用するようにした。
How JavaScript Event Delegation Works

ステートフルJavaScriptで出てきた。

現状だと画像をそのまま引き延ばすので元データの解像度が低いと荒れてしまう。最大表示する際に画像を差し替えるなど工夫が必要。シンプルに使えるようにライブラリ化しておきたいところ。

月曜日, 7月 16, 2012

stonewall開発日記10

リサイズイベントによって再度グリッドの引き直しをするためにコンストラクタから処理を分離した。で例によってTumblrから画像を引っ張ってくるサンプルをアップデートしたんだけど、これCSS3のMulti-Columnでよいのでは…と思って(このサンプルを思い出して)やってみたらやっぱそれでよかった(IEは10からじゃないと駄目だけど)。stonewallは左から右に要素を置いていくのに対し、Multi-Columnだと上から下なので全く同じという訳ではないが、タイル状に敷き詰めたいだけとか、上から下にレイアウトしていきたい場合にはCSSの方が良いだろうな。リサイズイベントを拾わなくても追従してくれるし。

前にも書いてたけど、やはりJavaScriptでしかできないレイアウトを実現するか、ベンダープレフィックスとかつけなきゃいけない現状のCSSよりは簡単で導入もしやすく古いブラウザの問題も解消する方向を検討したい。

グリッドデザインは単にグリッド状に並んでるだけじゃなくて垂直方向の間隔も揃ってないといけないんだけど、その辺までちゃんとやろうとするとすごく大変。
Preserving vertical rhythm with CSS and jQuery

レイアウトに関しては今回のMulti-ColumnやFlexible Boxとか色々遊べそうなので追っていきたい。

火曜日, 6月 19, 2012

TumblrのAPIから画像を取得して表示するサンプルをアップデート

stonewallのexampleとしてTumblrからJSONPで画像URLを取得して表示するコードをgithubにアップしたけど、実際に動いているものもアップした。投稿順ではなく高さをなるべく揃えるように低いところに足していくモード。
http://hysysk.org/work/tumblr

今回のAPI KEYは別に見られても構わないのだけど、複数人でコードを共有する場合などでは望ましいことではないので、バージョン管理下に置くファイルと、動作確認用のファイルを分けている。

こんな感じのpythonスクリプトでtemp.htmlを作ってgitignoreに追加しておくと、いちいちAPI KEYを手で置き換えなくて良いし、間違ってキーが入った状態でコミットしたりしない。通常業務でやると大変です。

import re
input = open('index.html', 'r')
output = open('temp.html', 'w')
for line in input:
    output.write(line.replace("YOUR API KEY","PURkZinJvrZVtis5m8TxmEcAbM4dcgjlfvecnWJyEAIf5BpZVe"))
input.close()
output.close()

一応UglifyJSでミニファイしてサーバに置いてあるんだけど、「API KEYを置き換える→JSをミニファイする→サーバにアップ」まで自動化したいしするべき。

あと、基本的なことだけどAPIを叩いてパースしたり表示を確認するのは、レスポンスデータを保存したデータかAPIドキュメントを元に作成したダミーのデータで試すのがよい(実はTumblrのAPIドキュメントにはフルサイズの画像を取得するoriginal_sizeというキーが抜けていたりする)。

それにしても実際に動いているものを触っていると色々と対応したいことがでてくる。ウィンドウサイズの変化に追従するとか、オートページングとか。クリックでオリジナル画像が表示されるとか。

ちなみに以前の画像が1枚しか読まれない問題は読み込み時のコードに不具合があったからでした。この話題についてはまた別の投稿で掘り下げたい。

火曜日, 5月 22, 2012

stonewall開発日記9

レイアウト方法を順番通りに並べるタイプと、高さが一番低いカラムに置くタイプの2種類にした。多少モデルとビューを意識してプロパティとして持った方がよいところは持たせるようにした。

exampleをオンラインで見せられるようにしたい。

そろそろ当初欲しかった機能は入ったのでクロスブラウザで確認してリリースタグを切りたい。

金曜日, 5月 18, 2012

stonewall開発日記8 振り返り

すごく緩くではあったけど、今回は業務でやっているようなアジャイルっぽい感じで開発をしてみた。ここ数日はデイリースクラムっぽい形で

  • やったこと
  • これからやること
  • 問題点
を挙げつつ進めてみたつもり。

今日は1週間に1度行っている「振り返り」を行ってみる。KPTと呼ばれるやつで、プロダクトの機能や開発スタイル(生活習慣含む)などのKeep = 良かったので続けていきたいこと、Problem = 改善したい問題点、Try = 挑戦したいことを挙げる。僕が所属しているチームではこれにZakkan = 雑感が加わって、新しく誰かが加わったとか、ゲームが面白いだとか、便利なツールとかについて話してる。

Keep

  • このスタイルの開発。週末にまとめるよりリズムが出て良い。
  • テストを書く。

Problem

  • もっと簡単に使いたい。DOMの構築は良いとして、要素の高さの取得はこちら側で吸収したい。
  • テストが重くなってきている。テストを面倒に感じると書いたり実行したりしなくなるのでよくない。

Try

  • テスト自動化したい。jsTestDriverやSeleniumなども試してみたい。
  • 現状だと単純にエントリ順に並べているだけ。順番が変わってもよいので高さが揃うように並べるとか、ちゃんとグリッドになってるとか、より見やすくて美しいレイアウトを目指す。
  • うまく結合できるAutoPager系のスクリプトなども作りたい。

雑感的なことをまとめると、zshのconfigurationをoh-my-zshにした。テーマが可愛いのと、gitでどのブランチにいるかが表示されるので便利。あとSublime Text 2をようやくちゃんと使い出した。vimも頑張って使っているけど、こういうのも触っておきたい。あんまりHaskell勉強できなかった。最近浅草に引っ越したんだけど、今週末は祭りで忙しい。

木曜日, 5月 17, 2012

stonewall開発日記7 Tumblr APIからJSONPを取得して画像を並べるサンプル

一通りできたので動作確認用にサンプルを作った。こういうグリッドで並べるようなレイアウトはtumblrやってる人ならだいたい好きだと思うからtumblrのAPIを使ってみた。動作確認していく上で細かなバグも見つかり、足りていないテストを追加したりした。JSONPのコールバック関数実行を待ってからレイアウト処理を実行しているからというのもあるけど、実際に使うと割とまだ面倒な感じで、今後どう改善するかを検討したい。

以下はTumblr APIをクライアント側のJavaScriptから利用する方法

Tumblrにアプリケーションを登録してOAuthキーを取得

ここでアプリケーションを登録。Application nameとApplication descriptionは何でもよい(後で変更もできます)。今回はローカルで試すのと、投稿を取得するだけなのでOAuthのConsumer Keyのみを使うのでApplication websiteもDefault callback URLも空でよいです。

TumblrのAPIからJSONPを取得

XMLHttpRequestを使いたいところだけど、異なるドメイン間での通信ができないので、JSONPを使う。JSONPを取得するには、

http://api.tumblr.com/v2/blog/{Tumblrアドレス}/posts[/投稿タイプ]?api_key={OAuth Comsumer Key}&jsonp=[コールバック関数名]
として、動的にスクリプトタグを生成してリクエストを飛ばす。今回は画像のみなので投稿タイプはphotoにする。

JSONPをパースして表示

コールバック関数の仮引数にJSONが入っているので、画像のURLを取り出しImageオブジェクトを生成してDOMに追加。要素の高さを取得するため全てがロードされるのを待ってbuildメソッドを実行している。読み込み部分が悪いのかも知れないけど、たまに全件表示されないのと、表示までに意識しなければならないことが多過ぎるのが課題。

通常のTumblrに組み込む方法はまた別の投稿で書こうと思う。

水曜日, 5月 16, 2012

stonewall開発日記6

縦方向の並びもテスト書いて通した。element.style.heightで要素の高さを取得しようとしていたのが間違いで、element.offsetHeightが欲しかったのだった。

コミットログ

ひとまずこれでNNNNYのサイトでやっているような並べ方の基本の部分はできた。exampleで実際に動きを確かめてみたいのだけど、いい方法を考えている。

月曜日, 5月 14, 2012

stonewall開発日記5

コンストラクタ関数を使ってStonewallオブジェクトとして利用できるように変更。設定をbuildに渡してるけどこれもコンストラクタの引数に移動するつもり。

#qunit-fixtureのスタイルはposition:absoluteでマイナス位置を指定している(display:noneにしていない)ので、子要素の幅や高さは指定できるはずなんだけど、どうも高さがうまく設定できない。試しに#qunit-fixtureのtopとleftを0にしてみたりして見た目を確認してみたのだけど、幅も変わっていない。しかしテストは通っているので、テストの正当性も含めて調査することにします。何となくCSSが怪しい気はしている。

ダミーのデータを作るのにFilleratiPlacehold.itを使った。

Viewのテストは難しい。

コミットログ

日曜日, 5月 13, 2012

stonewall開発日記4

buildという関数にレイアウト用のオブジェクトを渡すようにした。DOM操作が必要となるので、テストにダミーのHTMLが必要になるのだけど、QUnitではテストを実行するHTMLに#qunit-fixtureというdivが用意されているので、そこに書く

地味に関数名を変えたりしたのだけど、そういう時もテストがあると修正漏れとか見つけやすくてよい。

土曜日, 5月 05, 2012

Learning Haskell

関数型言語を何か覚えようと思いつつ全然手をつけられていなかったけど、ドキュメントが充実してきた感じがするのと、コンセプト的に新しいものがありそうなのでHaskellを勉強しようと思う。

何となくの先入観で、環境整えるのがめんどくさそうとか、Webアプリケーションとか作りにくそうと思っていたけど、インストールはThe Haskell Platformを使えば簡単だし、Webアプリケーションを作る場合はYesodのようなフレームワークもあり、それの導入もcabalというパッケージシステム(gemとかnpmみたいな)があるので簡単だった。

ターミナルでghciと入力すれば対話的に実行することもでき、想像よりかなり手軽だった。無料で読めるドキュメントも割とあるので、これらを読み進めながら何か作ろうと思う。

stonewall開発日記3

もたもたしているうちにVanilla MesonryというjQuery非依存のライブラリが出来てしまっていた。僕のは最終的なイメージがまだ固まっていないのだけど同じようなものにはしないつもり。

単純に要素がブロックになっていればよいという訳ではなく、行間や文字サイズが違っていてもベースラインを揃えたいだとか、そもそもグリッドは内容に合わせて引くものなので、テーマのように先にレイアウトがあってそこにコンテンツが流し込まれるのではなく、コンテンツに応じてレイアウトの方が決まっていくようなものにできればと思う。できるのかどうかはわからないけど。

グリッドレイアウトしたい要素の幅とコラムの幅からその隙間のマージンを計算する関数を追加。ここが割り切れない値になる可能性もあるのだけど、ひとまずは切り捨てる方向で考える。

コミットログはこちら

Responsiveな流れからすると単位を%にするのが良いのかもしれない。

Rolling Your Own Grid Layouts on the Fly Without a Framework | Design Shack

水曜日, 2月 22, 2012

Paper.js study 0 Setup

Paper.jsの勉強を始める。まずはセットアップ。
<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="paper.js"></script>
    <script type="text/paperscript" canvas="myCanvas">
        // ここにコードを書く
    </script>
</head>
<body>
    <canvas id="myCanvas" resize></canvas>
</body>
</html>

paper.jsを読み込み、canvasアトリビュートで描画先となるCanvas要素のidを指定し、typeをpaperscriptとしたscriptタグ内にコードを書く。
このコードはPaperScriptと呼ばれている。PaperScriptではなく通常のJavaScriptで書く方法もあるが、ひとまずはこの方法で進めていく。

木曜日, 2月 09, 2012

stonewall.js開発日記2

まず、どういう風に使いたいかというのを考えたのだけど、jQuery Masonryを参考にしてみる。
$('#container').masonry({
    itemSelector: '.box'
});
という感じで、グリッド表示したい要素に対して、Optionを設定したオブジェクトをmasonryメソッドで渡している。 columnWidthを指定しない場合は最初の要素の幅が適用される。 目標としてはひとまず、
  • jQueryへの依存をなくす
  • アニメーションなどのコードをなくしてレイアウトに焦点を当てる
  • jQuery Masonryでできないことをする
といったところ。 まずContainerとなる要素の幅をColumnの幅で割るgetColumnsという関数を書いてみる。 コンテナの幅が960で、コラムの幅が300だとしたら、3が返ってくればよい。 testsディレクトリ以下にstonewall_test.jsというファイルを作成。
test("calculate number of columns", function() {
    var containerWidth = 960
        , columnWidth = 300
        , columnLength;
        columnLength = getColumns(containerWidth, columnWidth);
        equals(columnLength, 3);
});

レッド

これでtest以下のindex.htmlにstonewall.jsとstonewall_test.jsを追加しブラウザで開くとテストが実行されるはず。 結果は
    Died on test #1: getColumns is not defined - {}
というメッセージが出てテストが失敗する。 stonewall.jsにはまだ何も書いておらず、getColumns関数も無いのでこれは当然。 落ちるテストを書くことで、テスト自体が間違っていないことを確かめる。 いったんコミット。

グリーン

次にstonewall.jsの方にテストが通るように実装を書く。 3が返ってくる最も簡単な実装は、
var getColumns = function(containerWidth, columnWidth) {
    return 3;
};
となる。テストを実行すると無事通る。 コミットする。

リファクタリング

さすがにどんな値を渡しても常に3が返るようでは使い物にならないので、
     return Math.floor(containerWidth/columnWidth);
として、テストを実行し通ることを確認してコミット。 この「レッド、グリーン、リファクタリング」の繰り返しで、開発を進める。 例えばcolumnWidthが0だったら…とか文字列が渡されたら…というテストケースを追加し、 それらをパスするようにして品質を高めていく。 原則として「テストコードを書いている時はテスト対象のコードを変えない。テスト対象のコードを書いている時はテストコードを変えない」。 テスト書いておくと助かるのは後で設計を変えた時とかにどこを直せばよいかがわかりやすいところですね。とにかく赤になって落ちているところを直してグリーンにしていけばよい。

木曜日, 2月 02, 2012

GIF STREAM

kkosugeさんのサイトがすごく面白かったので、node.jsがちょっと追っていない間にバージョンが上がりまくってたのと、WebSocketに対する興味からこんなの作ってみた。

GIF STREAM

サーバから4秒おきにGIFアニメのURLがimg要素のsrcにセットされるというだけ。なんだけど同期が取られているので複数タブや複数ウィンドウでも同じ画像が表示されるはず。

やってみて思ったのは、多分GIFアニメじゃなくても同期のタイミングさえ合っていればそれなりに楽しめそうということと、特定のコネクションから操作を受け付けるようにすればVJ的に画面の制御もできそうということ。