Home > Tags > japanese

japanese

Meetup.Tweener 000: 簡単なアニメーション

Hello world to Meetup.Tweener: Easy animation

まずは非常に簡単なアニメーションをやってみましょう。Wireframe の Cube をクリックしてみてください。ジャンプ先のページでも見られますが、このアニメーションは以下のコードで実現されています。

Meetup.Tweener.isUsing = 'jQuery'; // The Magic spell of using Tweener with jQuery
$(function(){ // jQuery way of DOM Ready
  var cube = document.getElementById('cube');
  $(cube).click(function(){
    Meetup.Tweener.addTween(
      cube,  // 1st arg: the target element
      {'left': '100%'} // 2nd arg: animation property
    );
  });
});

ご覧の通り、Meetup.Tweener は AS3 Tweener と全く同じ、Tweener.addTween というメソッドの呼び出しで始まります。詳しい内容は次回以降お楽しみに、ということで。

Flickr: Hello world to Meetup.Tweener: Easy animation

Hello World to Meetup.Tweener

今更、Hello World, という感じでもないんですが、Meetup.Tweener の解説記事を書いていこうと思います。

Meetup.Tweener は僕が Open Source として開発している JavaScript のライブラリで、HTML + JavaScript の環境で非常に簡単にアニメーションを作ることができます。もし Flash での開発経験があれば、Tweener という Library は絶対聞いたことがあると思うのですが、Original の Tweener と API 互換性を持たせつつ、JavaScript 用に最適化をしています。

今やどのメジャー JavaScript ライブラリもアニメーション機能があるというのになんでいまさらアニメーションライブラリ?と思われるかもしれません。Meetup.Tweener の利点は

  1. 依存性は低く、(理論上では)どのメジャーライブラリとも共存できる
  2. 長い間 Flash で培われた API
  3. Meetup での実用実績

(1) に関して、今のところ対応しているのは jQuery と MochiKit だけなんですが、Prototype.js, MooTools, YUI, Dojo には対応する準備があります。(2) に関して、HTML5 が台頭してくるにあたって、多くの Flash 製作者が JavaScript に流れてくることが予想されます(楽観的)。彼らにとってなれしたしんできた syntax が使えるのはとても大きな資産になることでしょう。また、アニメーションをメジャーライブラリに頼らないことで、突然のコードベース変更にも強いでしょう。

このライブラリは Google Adplanner によれば 6M の Unique Visitor をほこる Meetup.com で運用の実績があります。実地で使われているものですから、問題があれば対処は素早く行われます。

開発は Github 上の meetup.tweener レポジトリにて行われていて、ドキュメントも Github 上にあります。

開発にあたって、Yuichi Tateno (id:secondlife) さんの JSTweener を参考にさせていただきました。ありがとうございます。

090823: learn

diretory の比較 on Unix

Wordpress をアップデート。いつも忘れてしまう diretory の比較。普段は Changes.app などという Mac OS X の GUI アプリを使ってしまって、いっこうに覚えなかった…

How To Compare Directories in Unix

$ diff --recursive --brief /tmp/dir1 /tmp/dir2
Files /tmp/dir1/dir11/file12 and /tmp/dir2/dir11/file12 differ
Files /tmp/dir1/file1 and /tmp/dir2/file1 differ
Only in /tmp/dir1: file2
Only in /tmp/dir2: file3

これを応用すると、例えば dir1 にだけ存在するファイルは

$ diff --recursive --brief /tmp/dir1 /tmp/dir2 | grep '^Only \/tmp\/dir1'

とすればよいですね。

emacs で major mode を変える

例えば .html なファイルを emacs で開くとほぼおそらく HTML mode で開かれると思います。でも実は内部の JavaScript を編集したいし、js2-mode (JavaScript-IDE) で編集したい。凄い基本ですがしばらく emacs を触ってないで忘れてしまっていました。

M-x js2-mode

でした。


またこれから emacs 勉強記録をつけていきたいと思います。今日はどうやってコピーするのか忘れてましたが (M-w Copy / C-w Cut / C-y Paste) それさえわかれば、それなりに使えrて結構びっくりした。

これから

なんとなくここ数ヶ月スランプ気味でした。理由はいろいろあるんでしょうけれど、つい最近仕事で面白いことがあって、それをきっかけに考えることがあったので、このエントリをおこしてみました。

僕の勤める会社は変化することが信念というか、いろんなことがめまぐるしく変わります。いろんな意味でそれは楽しいのですが、ある意味ではとても緊張の多いことです。そして仕事のクオリティに対する要求はいつでも凄く高いです。だから内外の新しい変化についていかなければ行けないし、それが競争力を高める、ということなんだと思います。

もう数ヶ月前になりますが、社内の SCM を git に鞍替えしました。それを機に開発プロセスがとても快適になったんですね。Subversion で merge をやったことのある人ならわかると思うんですが conflict の余計な不調がなくなったし、細かいバグなどの修正がとても簡単になりました。イイコト尽くめのようなんですが、実際そうなってからリリースできた product の数、というのは実際よくわかりません。僕の主観的には大きな product のリリースは増えていなかったと思います。まぁこれは、teaming の問題なのかもしれませんが、各チームが big win を目指して気負いすぎていたのかな、と思います。

先週社内で hack-a-thon をやりました。僕が join してから、2回目の Hack-a-thon ですが、僕的にはほとんど初めての気分です。というのも前回の hack-a-thon では、僕はまだあまり環境に慣れていなくて、あまり誰とも話すことができていなかった。というか自分のポジション決めに精一杯で、自分でも何ができるのかよくわかっていないかった。結局自分の 10% プロジェクトの延長で、Meetup.Tweener のドキュメント充実など、あまり社内的にはおいしくないことをやっていましたが、まぁあまりそういうことには今まで気が配られていなかったので、ある程度好意的に受け止められました。

今回の hack-a-thon では、2つのプロジェクトを発表できて、自分的にはそれなりに満足でした。一つは新しい product に関わることなので内緒ですが、もう一つは JavaScript に関わることで、この blog で続きを出来たらと思っています。

正直今回の hack-a-thon はスケジュール的にとても急で、team 的には「なんで今?」という気もしていましたが、僕的にはとても実りの多いものでした。簡単に言ってしまえば気分転換はとても大事だ、ということなのかもしれませんが、すくなくともここ数週間感じていた仕事での不安は大部分拭われました。

それはなんでなんだろう、と考えてみると (1) 一つのことをに集中しすぎて袋小路に入っていた。それが打開されたということ、(2) アイデアの引き出しを増やすのはとても重要なこと、 (3) 技術的にチャレンジを常にする。ということなのかなぁと思いました。

というわけで、Twitter でつぶやくのではなく、またアウトプットを増やしていきたいと思います。

Visitor and Iterator pattern in JavaScript

最近また実験的なアプリを JavaScript で書いているんですが、node walker を書く必要にかられ、デザインパターン入門をまた開いてみました。以下のページを開いて、Firebug の console で、例えば window.d = new DOMNodeDest(document.body); d.accept(new Visitor()); などとすれば、各ノードを列挙してくれます。

Viistor Pattern

実際、頭を悩ましたのは、Visitor パターンというより、むしろ Iterator パターンでした。結構面白いと思うんですけど、どうでしょう?

Iterator = function (obj) {
  var i, chld, len, pub, mth,
      result  = {},
      BIND    = Iterator.bind;
  if (obj instanceof Array) {
    this.children = obj;
  }
  else if (typeof(obj) === 'object' && obj !== null) {
    this.children = [];
    chld = this.children;
    for (i in obj) {
      if (obj.hasOwnProperty(i)) {
        chld[chld.length] = obj[i];
      }
    }
  }

  pub = Iterator.publics;
  for (i = 0, len = pub.length; i < len; ++i) {
    mth = pub[i];
    result[mth] = BIND(this[mth], this);
  }
  return result;
};

Iterator.publics = ['next', 'hasNext', 'rewind'];
Iterator.prototype.index    = -1;
Iterator.prototype.children = null;

Iterator.prototype.next = function () {
  if (this.children === null) {
    return null;
  }
  var CHLD    = this.children,
      len     = CHLD.length,
      result  = null;
  ++this.index;
  if (len !== 0 && this.index < len) {
    result = CHLD[this.index];
  }
  return result;
};

Iterator.prototype.hasNext = function () {
  if (this.children === null) {
    return false;
  }
  var result  = false,
      len     = this.children.length;
  if (len !== 0 && this.index < (len - 1)) {
    result = true;
  }
  return result;
};

Iterator.prototype.rewind = function () {
  this.index = -1;
  var it,
      i     = 0,
      CHLD  = this.children,
      len   = CHLD.length;
  if (len) {
    for (;i < len; ++i) {
      it = CHLD[i].iterator;
      if (it) {
        it.rewind();
      }
    }
  }
};

Iterator.bind = function (func, context) {
  return function () {
    return func.apply(context, arguments);
  };
};

objectified 鑑賞

本日 IFC にて Objectified を観てきました。

objectified

Objectified: Naoto Fukasawa

Objectified

Objectified: David Kelley, IDEO

インタビューを受ける人の多くが英国英語を話すので、やや聞きづらいのですが、それでも Jonathan Ive の一言にはすごく頷きました。一通りアルミを削りだす新しい MacBook Pro の製作行程やデザインのプロセスを説明して後で『それって偏執狂だよねぇ?』と。でも“設計”(日本語でデザインというとファッションな感じがするので design の訳語として)に関わる人はみんな偏執にならざるを得ないと思います。

ソフトウェア開発と工業製品の開発は多くの違いがありますが、間違いなく一つ云えるのは、深い洞察のなされていない製品があふれている、という事実です。初心に戻って、それは肝に銘 じないといけません。

現在 NYC 近郊にお住まいの方は是非、お勧めです。

Meetup.Tweener (0.5.1)

まだ正式なアナウンスなどをしていないんですが、Github 上で Meetup.Tweener の開発を始めました。サンプルなどを充実させられたらと思っています。コメントは NaturalDocs でパース可能な状態になっていますので、ドキュメントに必要な方は NaturalDocs を使ってみてください。NaturalDocs のスタイル化が出来たらそれも package に含めようと思っています。

今日の英語: in layman’s terms.

僕は会社でサポートの人と IM すること(僕が作ったプログラムの使い方などを聞かれる)も最近増えてきたのだけれど、その中で出てきた単語。

E: Can you put in layman’s terms?
Me: I personally call it Dock.

文脈から何となく想像して適当に答えましたが、要するに“もっと簡単な言い方はない?”と聞かれたわけです。

Wikipedia: Layman (英語)
Wikitionary: in layman’s terms

僕はてっきりなんかテレビホストで Layman とか云う人がいるのかと思ったのですけれど、宗教用語から来てたんですね。宗教者 clergy に対する俗人 laity。その別の言い方としての layman の意味が時代と共に変化して、エキスパートではない人、という意味なったようです。でも元々 lay はラテン/ギリシア語源の 人の/世間一般のという接頭辞のようです。

Safari バグ: TD エレメントの間違った offsetTop 値

# 追記: このバグは最新の開発版では修正されています。WebKit Bugzilla を参照のこと→ WebKit Bugzilla 19094. Nightly でも既に修正されているみたいですね。もしこれに関してハックをしたなら(つまり僕のことですが)、以下のようなもう一つ、ハックが必要です。

var webkit = indow.navigator.userAgent.match(/WebKit\/([0-9]{3})/);
if (webkit && parseInt(webkit[1]) < 528) {
...
}

JavaScript ライブラリの多くは、HTML エレメントの(ページ上での)ピクセル位置(絶対座標)を返すメソッドを備えています。jQuery の jQuery.offset() しかり、MochiKit の MochiKit.Style.getElementPosition() しかり、MooTools の Element.getPosition() 等々… ほとんどの場合これらはうまく動くのですが、今日動かないケースを確認し、おそらく Safari のバグだと思うのでここに報告しておきます。

以下の条件が揃ったとき、ピクセル絶対座標を取得するメソッドは間違った値を返します。

  1. ブラウザは Safari
  2. 取得しようとしているエレメントは TD (あるいは display:table-cell)
  3. CSS で vertical-align を top 以外の値 (middle or bottom) が設定されている

次にこのケースの例を作りました。Safaribug: wrong offsetTop on TD. テーブルセルをクリックすると、アラートで、そのテーブルセルのピクセル座標を返します。Safari とその他のブラウザで開いてみてください。違いがあります。

ではコードで解説します。以下は Google doctype project で見つけた PageOffset: How to calculate the position of an element on the page (goog.style.getPageOffset) を下にしています。オリジナルの PageOffset のコードは非常に細かく説明してあるので、一度読んで見ることをお勧めします。長くないし。

function getPageOffset(el) {
    var pos = {
        x: 0,
        y: 0
    };
    var viewportElement = document;
    if (el == viewportElement) {
        return pos;
    }

    var parent = null;
    var box;

    pos.x = el.offsetLeft;
    pos.y = el.offsetTop;

    parent = el.offsetParent;
    if (parent != el) {
        while (parent) {
            pos.x += parent.offsetLeft;
            pos.y += parent.offsetTop;
            parent = parent.offsetParent;
        }
    }

    if (el.style.position == 'absolute') {
        pos.y -= doc.body.offsetTop;
    }

    parent = el.offsetParent;
    while (parent && parent != document.body) {
        pos.x -= parent.scrollLeft;
        parent = parent.offsetParent;
    }

    return pos;
};

Safari では、指定したエレメントから、その相対目標(これを指定しなければ、document.body を相対目標とします。つまりページの絶対座標ですね。)まで、エレメントを上り詰めて、その間の offset を累積加算していきます。問題は、一番最初の el.offsetTop (15行目) で起こります。これは table cell で、padding/margin/border が設定されていませんから、0 であるべきなのですが、Safari は、子孫要素への offset を返しているようなんですね。

どうにもいい方法が見つからなかったので、実際のアプリケーションではダーティハックを入れましたが、WebKit チームの早急な fix を望みます!!

Google Sync v. NuevaSync

Picture 1しばらく前から、Google Calendar を僕の iPhone で使いたくて、NuevaSync を使っていました。NuevaSync を通せば Google Calendar が Microsoft Exchange Server のように見える、という優れたサービスで、かつ無料です。

何も文句はなかったのですが、今日 Google Calendar を見てみたら Sync with iPhone なんてあったので、試してみました。英語ですが、次のリンクに説明があります: Sync: Set Up Your iPhone or iPod Touch

IMG_0001 4現状では NuevaSync の方がいいです。左の写真のように Google Sync ではメインのカレンダーにしかアクセスできません(何かほかに設定があるのでしょうか?)。NuevaSync ならすべてのカレンダーにアクセスできます。

これまでの Google からすると、きっと改善されるんでしょうがとりあえず現状はこうですよ、という覚え書きでした。

あ、そうだ。iPhone が Exchange Server のアカウントを1つしか設定できない、というのも酷いと思いました…

Home > Tags > japanese

Search
Feeds
Meta
Links
Ads!

Return to page top