<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>かえラボBlog</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://kaelab.ranadesign.com/blog/atom.xml" />
    <id>tag:kaelab.ranadesign.com,2009-01-20:/blog//1</id>
    <updated>2011-12-28T12:17:15Z</updated>
    <subtitle>かえラボBlogはラナデザインアソシエイツのテクニカルチームが運営する技術系ラボプロジェクトです</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 5.04</generator>

<entry>
    <title>Ajax遷移するページのページビューをGoogle Analyticsで計測する</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/12/ga-ajax.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.411</id>

    <published>2011-12-28T11:59:21Z</published>
    <updated>2011-12-28T12:17:15Z</updated>

    <summary>Ajaxで他のページを取ってきてコンテンツを書き換えてしまうようなサイトでは、Google Analytics従来の手法では遷移先のページビューを取得できませんが、_trackPageviewを使うことで解決できます。</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ajax" label="Ajax" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>Ajaxで他のページを取ってきて、コンテンツをガリガリ書き換えてしまうようなサイトを先日案件で作ったのですが、従来の方法ではGoogle Analyticsで遷移先のページビューを取得できないことに気づいて、実験を行ってみました。</p>

<figure><img alt="20111228_googleanalytics.png" src="http://kaelab.ranadesign.com/blog/entry_assets/20111228_googleanalytics.png" width="450" height="300" class="mt-image-none" style="" /></figure>

<p>実験のために作成したデモがこちらです。</p>
<p><a href="http://kaelab.ranadesign.com/blog/demo/gatest/">Google Analytics Demo</a></p>
<p>何をやっているかを解説していきます。</p>

<p>以下のような部分がAjaxでページを書き換える処理の例です。<br />
今回はjQuery 1.7.1を使うことを前提にしてコードを書いています。&quot;ul a&quot;セレクタ（いかにもやっつけですが。。）で選択されたa要素をクリックすると、href属性値で指定されたURLをAjaxリクエストし、その内容で <code>&lt;div id="contents"/&gt;</code> の中身を書き換えちゃうよ、というものです。</p>

<pre><code>$(function() {
    $(document).on('click', 'ul a', function (e) {
        if (this.href) {
            $.ajax(this.href, {
                dataType: 'html',
                success: function(data) {
                    $('#contents').empty().html(data);
                }
            });
        }
        e.preventDefault();
    });
}); </code></pre>

<p>Google Analyticsの設定を行っていきましょう。<br />
まずはhead要素内で普通にトラッキングコードを埋め込みます。</p>

<pre><code>&lt;script&gt;
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-TRACKINGID']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
&lt;/script&gt;</code></pre>

<p><code>UA-TRACKINGID</code>の部分は適切なトラッキングIDに置き換えてください。</p>

<p>さて、本題です。<br />
Ajaxで読むページのページビューを取るには、<a href="http://code.google.com/intl/ja/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._trackPageview"><code>_trackPageview()</code>という機能</a>を使います。リンクをクリックしたイベントをトリガーに、このコードを呼び出してやればOK。<br />
それが以下のコードです。</p>

<pre><code>$(function() {
  $(document).on('click', 'a', function () {
    if (_gaq &amp;&amp; this.href) {
      _gaq.push(['_trackPageview', this.href]);
    }
    return true;
  });
});</code></pre>

<p>.on()というメソッドはjQuery 1.7の新機能なので、古いバージョンのjQueryを使わなければいけない場合、.live()とか使えばいいと思います。</p>

<pre><code>$('a').live('click', function() { ...</code></pre>

<p>という感じに。<br />
なお、今回はhref属性値に目的のURLがセットされているのが前提のコードになっています。もし特定のページを計測したい場合、<code>this.href</code>の部分は特定の文字列に置き換えても問題ないです。</p>

<pre><code>_gaq.push(['_trackPageview', '/contact/email.html']);</code></pre>

<p>というようになりますね。</p>


<h3>リアルタイムレポートでページビューを確認する</h3>

<p>Google Analyticsは<a href="http://www.google.co.jp/search?q=analytics%20%83%8A%83A%83%8B%83%5E%83C%83%80">リアルタイムなレポート機能</a>を実装してきました。ログインして、リニューアルされたUIになっていたら、その機能が使えます。（まだ使えない人は<a href="https://services.google.com/fb/forms/realtimeanalytics/">ここから申し込める</a>みたいですね）</p>

<p><a href="http://kaelab.ranadesign.com/blog/entry_assets/20111228_googleanalytics2.jpg"><img alt="20111228_googleanalytics2.jpg" src="http://kaelab.ranadesign.com/blog/assets_c/2011/12/20111228_googleanalytics2-thumb-400x320-92.jpg" width="400" height="320" class="mt-image-none" style="" /></a></p>

<p>メニューの「リアルタイム」→「コンテンツ」を選択し、ページ中央の「ページビュー数（直前の30分間）」をクリックします。これで、直近30分間のページビュー数をリアルタイムにウォッチしている状態になるので、先ほどのデモなどをいじくってこちらで確認する、ということができます。Ajaxで読むページのURLが、ページビュー数としてカウントされているかどうかを確認しましょう。</p>

<p style="margin-top:2em;">弊社は本日が仕事納めです。<br />
今年は震災などがあり大変な年になりましたが、来年はよりよい年となるよう、この場を借りてお祈り申し上げます。<br />
来年もどうぞよろしくお願いいたします。</p>
]]>
        
    </content>
</entry>

<entry>
    <title>『WebデザイナーのためのjQuery入門』を献本いただきました</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/12/webdesignjquery.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.409</id>

    <published>2011-12-09T11:12:54Z</published>
    <updated>2011-12-09T11:29:32Z</updated>

    <summary>出版されたばかりのjQuery本を著者の高津戸さん(@Takazudo）より献本いただきました。</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="雑記" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="book" label="Book" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<figure>
<img alt="WebデザイナーのためのjQuery入門" src="http://kaelab.ranadesign.com/blog/entry_assets/jquerybook.jpg" width="240" height="240" class="mt-image-none" style="" />
</figure>

<p>出版されたばかりのjQuery本を著者の高津戸さん(<a href="https://twitter.com/takazudo">@Takazudo</a>）より献本いただきました。ありがとうございます！
タイトルの通り、本書はWebデザイナーなどのプログラミング初心者のための本であり、著者曰く</p>

<blockquote title="書籍冒頭の「はじめに」より">
<p>本書は、「自分でコードを書けるようになる人」がひとりでも増えるように配慮して書いたつもりです。</p>
</blockquote>

<p>というわけで、非プログラマのjQuery/JavaScript入門書としては強力な一冊となっています。</p>

<p>手にとって思ったのは、とにかく親しみやすい文体と図解でわかりやすく書かれている、ということ。<br />
書籍なので丁寧な文体で書かれてはいますが、文章のもって行き方や言い回し、作例などはユニークで「プログラミングを理解する」という複雑なテーマに挑む読者に対して、著者がとてもフレンドリーに向き合っている印象を受けました。</p>

<aside class="note">
<p>なお著者のブログや、イベントでのプレゼンスライドなどを見ると、その雰囲気を知ることができます。</p>
<ul>
<li><a href="http://hamalog.tumblr.com/">Takazudo hamalog</a></li>
<li><a href="http://cssnite.jp/archives/post_2096.html">CSS Nite LP, Disk 13フォローアップ（4）高津戸 壮さん｜CSS Nite公式サイト</a></li>
<li><a href="http://cssnite.jp/archives/post_1881.html">CSS Nite LP, Disk 9「Coder's Higher」フォローアップ（5）｜CSS Nite公式サイト</a></li>
</ul>
</aside>

<p>私はJavaScriptをちゃんと学び始めて4年くらいが経ちますが、私にとっての入門書は「<a href="http://www.amazon.co.jp/Web%E3%82%AF%E3%83%AA%E3%82%A8%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEDOM-Scripting-%EF%BC%88Web-Designing-Books%EF%BC%89/dp/4839922268/ref=sr_1_6?ie=UTF8&amp;qid=1323428006&amp;sr=8-6">WebクリエイティブのためのDOM Scripting</a>」でした。<br />
当時は今ほどブラウザが優秀ではありませんでしたし、JavaScriptライブラリなどもそれほど強力ではありませんでしたから、本書のようにフレームワークに特化した日本語書籍は当時なかったと記憶しています。しかしもし自分が今JavaScript入門者であったら、まさに本書は読みたい内容であるなあと感じました。</p>]]>
        
    </content>
</entry>

<entry>
    <title>画像を読み込みを制御するプラグイン imgloader.js</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/06/imgloader.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.408</id>

    <published>2011-06-21T06:44:31Z</published>
    <updated>2011-09-16T07:47:32Z</updated>

    <summary>画像の読み込みと生成を行い、ローディング完了またはタイムアウトを確認してからコー...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[画像の読み込みと生成を行い、ローディング完了またはタイムアウトを確認してからコールバックに設定した処理を行う。

【 実行方法 】
<pre><code>
$("element").imgloader(options);
</code></pre>

【 オプション 】
imglist: (Array) 画像のsrcに指定するパスを配列形式で指定。
callback: (function) コールバック処理を関数形式で指定。
timeout: (Number) タイムアウトをミリ秒で指定。省略時はタイムアウトしない。

【 例 】
<pre><code>
	var options = {
		imglist: [
			"photo/0.jpg",
			"photo/1.jpg",
			"photo/2.jpg",
			"photo/3.jpg"
		],
		width: 1200,
		height: 896,
		callback: function() {
			// コールバック処理
		}
	}
	
	// loader
	$("#imgContainer").imgloader(options);


// HTML
	<div id="imgContainer"></div>

</code></pre>

<p class="link"><a href="/blog/demo/fitter" target="_blank">デモはこちらから</a>
<p class="link"><a href="/blog/demo/fitter/js/imgloader.js" target="_blank">ダウンロードはこちらから</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>画像をウィンドウにフィッティングさせるプラグイン fitter.js</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/06/fitterjs.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.407</id>

    <published>2011-06-17T06:36:59Z</published>
    <updated>2011-09-16T07:49:23Z</updated>

    <summary>リサイズイベント発生時に要素内の画像サイズをウィンドウサイズに合わせて変更する。...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>リサイズイベント発生時に要素内の画像サイズをウィンドウサイズに合わせて変更する。<br />
最小サイズを指定しておけば、それより小さくはならない。</p>

<p>【 実行方法 】<br />
<pre><code><br />
$("element").fitter(options);<br />
</code></pre></p>

<p>【 オプション 】<br />
width: 画像の初期横幅<br />
height: 画像の初期縦幅<br />
minWidth: 最小横幅<br />
minHeight: 最小縦幅<br />
selector: フィッティングさせる要素を指定する。初期値は"img"。</p>

<p><br />
<p class="link"><a href="/blog/demo/fitter" target="_blank">デモはこちらから</a><br />
<p class="link"><a href="/blog/demo/fitter/js/fitter.js" target="_blank">ダウンロードはこちらから</a></p></p>]]>
        
    </content>
</entry>

<entry>
    <title>要素をスクロールに追従させるfloater.jsに、IE6でもfixedできる機能を追加</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/06/floaterjsie6fixed.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.405</id>

    <published>2011-06-14T12:24:47Z</published>
    <updated>2011-06-14T13:02:30Z</updated>

    <summary>フローティングなナビゲーションを作るjQueryプラグイン ↑に位置固定(pos...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="plugin" label="plug-in" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p><a href="/blog/2011/06/jquery-2.html">フローティングなナビゲーションを作るjQueryプラグイン</a></p>

<p>↑に位置固定(position: fixed)の機能を追加した。</p>

<p>もちろん、IE6にも対応。</p>

<p><a href="http://kaelab.ranadesign.com/blog/demo/floater/js/floater.js">floater.js</a></p>

<p><a href="/blog/demo/floater/">サンプル デモ</a></p>

<p>オプションや使い方などは前記事を参照ください。<br />
</p>]]>
        
    </content>
</entry>

<entry>
    <title>フローティングなナビゲーションを作るjQueryプラグイン</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/06/jquery-2.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.404</id>

    <published>2011-06-14T09:38:05Z</published>
    <updated>2011-06-14T14:23:04Z</updated>

    <summary>fixedオプションを追加。 ナビゲーションなどのコンテンツをスクロールに追従さ...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="plugin" label="plug-in" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p class="note">fixedオプションを追加。</p>

<p>ナビゲーションなどのコンテンツをスクロールに追従させ、画面の上下に接着させるjQueryプラグイン。</p>

<p>どこかで見たような気がするのだが、どこで見たか思い出せない＆探してもすぐ出てこないので、作ってみた。</p>

<p><a href="http://kaelab.ranadesign.com/blog/demo/floater/js/floater.js">floater.js</a></p>

<p><a href="/blog/demo/floater/">サンプル デモ</a></p>

<p>使い方は簡単。<br />
よくある感じで、動かしたい要素でfloaterメソッドを実行する。</p>

<pre><code>
	$(element).floater();
</code></pre>

<p>オプションは以下の通り。</p>

<ul>
	<li>marginTop: 上の余白</li>
	<li>marginBottom: 下の余白</li>
	<li>agility: 0～1。0はナビが通り過ぎるまで待つ。1はナビの末端が出るとすぐ動きだす。</li>
	<li>speed: アニメーションにかける時間</li>
	<li>easing: イージング</li>
	<li>fixed: trueでposition: fixedに切り替え。初期値はfalse。</li>
</ul>

<p>オプションを適用すると、こんな感じ。</p>

<pre><code>
	$("nav").floater({
		marginTop: 60,
		marginBottom: 80,
		wait: 0.75,
		speed: 800,
		easing: "easeInQuad"
	});
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>要素をフェードで切り替えていくプラグイン fadechanger.js</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/06/fadechangerjs.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.406</id>

    <published>2011-06-11T06:25:38Z</published>
    <updated>2012-04-04T12:26:38Z</updated>

    <summary>追記： 2012/04/04 オプションを追加しました。 最前面(末尾)の要素を...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p><strong>追記： 2012/04/04 オプションを追加しました。</strong></p>

<p>最前面(末尾)の要素をfadeOutさせたのち、最背面(先頭)へ移動させ、show()している。その繰り返し。<br />
CSSは特に指定していないので、同じ場所で切り替える場合は、position: absoluteなどで重ねておく必要あり。</p>

<p>【 実行方法 】<br />
<pre><code><br />
$(parent-element).fadechanger({ selector: child-element });<br />
</code></pre></p>

<p>【 オプション 】<br />
speed: 切り替えにかける時間をミリ秒で指定。初期値は2000。<br />
wait: 次の切替までの待ち時間をミリ秒で指定。初期値は2000。<br />
selector: 要素内のどの子要素を切り替えるかを指定する。省略した場合は、すべての子要素が対象となる。<br />
(例) { selector: ".opened" }とした場合は、openedというクラス名を持った子要素のみが対象となる。<br />
loop: 切替のループ回数を数値で指定。初期値は"infinite"（無限）。</p>

<p><br />
<p class="link"><a href="/blog/demo/fitter" target="_blank">デモ（無限繰り返し）</a><br />
<p class="link"><a href="/blog/demo/fitter/one.html" target="_blank">デモ（ループしない）</a></p>

<p class="link"><a href="/blog/demo/fitter/js/fadechanger.js" target="_blank">ダウンロードはこちらから</a></p>
]]>
        
    </content>
</entry>

<entry>
    <title>RaNa design WEBSITE RENEWAL PROJECTのネタばらし その3</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/04/rana2011neta3.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.403</id>

    <published>2011-04-20T04:50:19Z</published>
    <updated>2011-04-20T08:38:21Z</updated>

    <summary>昨年末に公開したRaNa design WEBSITE RENEWAL PROJECTの舞台裏エントリーその3です</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rana" label="RaNa" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p><a href="http://kaelab.ranadesign.com/blog/2011/04/rana2011neta2.html">その2</a>から随分時間が経ってしまいましたが、続きを書いていきます。</p>
<p>今回はカエルのキャラクターがシャベルやドリルを使って「働く」アクションを追加する内容です。</p>
]]>
        <![CDATA[<section>
<h3>設計と実装編 その4 - 「働く」アクションを追加する</h3>

<p>案の定というか当たり前というか、画面上をカエルが歩いているだけだとコンテンツとしては退屈ですので、キャラクターが働いているアクションを追加します。</p>
<p>働いているキャラクターはアニメGIFなので、「働いている」状態の実装は画像切り替えだけでOKです。</p>

<figure>
<img alt="「地面ガガガなう」の画像" src="http://kaelab.ranadesign.com/blog/entry_assets/kaeru9-work.gif" width="90" height="50" class="mt-image-none" style="" />
<figcaption>キャラクターが「働く」アニメGIFの例</figcaption>
</figure>

<p>ここでのポイントはキャラクターが立ち止まるところにあります。</p>

<ul>
<li>キャラクター初期化時に「働く」エリアをランダムに決定</li>
<li>働くエリアの特定の座標に到達したら立ち止まり、働くキャラクター画像に切り替える</li>
<li>働き終わったら通常のキャラクター画像に切り替え、通常の移動を再開</li>
</ul>

<p>というわけでこれをKaeruクラスの機能に落とし込んで、<code>_selectWorkingArea()</code>メソッド、<code>_checkWorking()</code>メソッド、<code>_work()</code>メソッドを追加することにしました。</p>

<pre><code>Kaeru.prototype = {
...中略
  _selectWorkingArea: function (arr, count) {
  // 「働く」エリアを選択して返す
  // @param {Array} arr behavior配列
  // @param {Number} count 働く回数
    var arr2 = arr.concat(),
      newArr = [],
      newArr2 = [],
      noWorkingAreaMap = [0,1,8,9,16,17,24,25]; // 縦移動エリア
    $.each(arr2, function (i) {
      // check area to work
      for (var j = 0, l = noWorkingAreaMap.length; j &lt; l; j++) {
        if (arr2[i] === noWorkingAreaMap[j]) {
          return true;
        }
      };
      newArr.push(arr2[i]);
    });
    arr2 = shuffle(newArr);
    for (var i = 0; i &lt; count; i++) {
      newArr2[i] = arr2[i];
    };

    function shuffle(array) {
      var array2 = array.concat();
      $.each(array, function(i) {
        var index = Math.floor(Math.random() * array2.length);
        var element = array2[index];
        array2.splice(index, 1);
        array[i] = element;
      });
      return array;
    }

    return newArr2;
  },
  _checkWorking: function (workingArea, currentArea) {
  // 現在いるエリアが「働く」エリアかチェック
  // @param {Array} workingArea 「働く」エリア
  // @param {Number} currentArea 現在いるエリア
    var self = this,
      flag = 0;
    $.each(workingArea, function () {
      if (currentArea === parseInt(this)) {
        flag = 1;
        return false;
      }
    });
    return flag;
  },
  _work: function (map, imgSrc) {
  // 「働く」処理
  // @param {Object} map エリアIDに対応したmap
  //     例： { fromX: 0, fromY: 80, toX: 392, toY: 80 }
  // @param {String} imgSrc 働いているカエル画像のパス
    var self = this,
      randomN = Math.ceil(Math.random() * 5) + 1,
      newMap = {
        fromX: map.fromX,
        fromY: map.fromY,
        toX: Math.floor((map.toX - map.fromX) / randomN + map.fromX),
        toY: map.toY
      };
    this.$characterBox.animate({
        'left': newMap.toX
      },
      this._computeDuration(newMap),
      'linear',
      function () {
        // work!
        self.$character.attr('src', imgSrc);
        setTimeout(function () {
          // 移動再開
          self.resetMove();
        }, 7500);
      }
    );
  },
...中略
};</code></pre>

<p><code>_selectWorkingArea()</code>は引数にbehavior配列<a href="#rana2011neta3_1">（※）</a>と、移動パターン中で「働く」回数を受け取ります。</p>

<p class="note" id="rana2011neta3_1">behavior配列とは、<a href="http://kaelab.ranadesign.com/blog/2011/04/rana2011neta1.html">ネタばらし記事その1</a>で書いたように、エリアIDが移動パターンとして順番に並んでいる配列です。<br />
例：<code>[0,5,8,11,10,12,16,22,23,21,24,27,26,28,29,25,19,18,20,22,23,17,14,15,13,9,4,6,7,1]</code></p>

<p>「behavior配列の中で、縦移動エリアを除いて、その中から指定した回数だけ「働く」エリアをランダムで選択し、配列として返す」という処理になっています。</p>

<p>縦移動エリアというのはハシゴになっている部分なので、ここでキャラクターが「働く」のはおかしいのでまず除外します。それが最初の処理部分です。</p>
<pre><code>
var arr2 = arr.concat(),
  newArr = [],
  newArr2 = [],
  noWorkingAreaMap = [0,1,8,9,16,17,24,25]; // 縦移動エリア
$.each(arr2, function (i) {
  // check area to work
  for (var j = 0, l = noWorkingAreaMap.length; j &lt; l; j++) {
    if (arr2[i] === noWorkingAreaMap[j]) {
      return true;
    }
  };
  newArr.push(arr2[i]);
});
</code></pre>
<p>最初に<code>var arr2 = arr.concat();</code>しているのは元の<code>arr</code>を変更しないようにするため。引数<code>arr</code>には元の配列が<em>参照渡し</em>されているため、<code>arr</code>を変更すると、元の配列も変更されてしまいます。</p>

<div class="note">
<p>ちなみに<code>Array.concat()</code>は配列同士を連結して新しい配列を返す組み込みメソッドです。</p>
<pre><code>var arr1 = ["hoge", "fuga"];
var arr2 = ["foo", "bar"];
var newArr = arr1.concat(arr2); // ["hoge","fuga","foo","bar"]</code></pre>
<p>引数を省略すると、空の配列が連結されることとなり、結果的に配列のコピーを作れます。</p>
</div>

<p><code>arr2</code>を<code>$.each()</code>ループでまわして<code>noWorkingAreaMap</code>と突き合わせ、もし該当エリアなら<code>return true;</code>することで次のループへ。該当しなかったら別の配列（<code>newArr</code>）に<code>push()</code>します。結果的に<code>newArr</code>は縦移動エリアを除いたエリアの配列となります。</p>

<p>そして次に、<code>newArr</code>をシャッフルします。この処理は<code>shuffle()</code>関数にまとめました。その方が処理の流れが分かりやすいので。<br />
<code>arr2</code>に代入しているのはただ単に配列名を使いまわしているだけです。別の変数を作って代入しても構いません。</p>
<pre><code>arr2 = shuffle(newArr);
...中略...
function shuffle(array) {
  var array2 = array.concat();
  $.each(array, function(i) {
    var index = Math.floor(Math.random() * array2.length);
    var element = array2[index];
    array2.splice(index, 1);
    array[i] = element;
  });
  return array;
}</code></pre>

<p><code>shuffle()</code>では配列をコピーして、ランダムで1個抽出して新しい配列に追加し、元の配列からは<code>splice()</code>で削除、ということをやっています。この処理については<a href="http://kaelab.ranadesign.com/blog/2009/10/javascript.html">複数のバナーをランダムに表示するJavaScript</a>というエントリーで取り扱った通りです。</p>

<p>そして引数<code>count</code>の分だけarr2を切り出して、別の配列変数（<code>newArr2</code>）に追加してやります。最後にそれを返せばこのメソッドはできあがりです。</p>
<pre><code>for (var i = 0; i &lt; count; i++) {
  newArr2[i] = arr2[i];
};
return newArr2;</code></pre>


さて次に<code>_checkWorking()</code>メソッドですがこちらはシンプルで、<code>_selectWorkingArea()</code>で設定された配列と、現在のエリアIDをループで突き合わせて、同じものがあったら1を返す、というものです。

<pre><code>_checkWorking: function (workingArea, currentArea) {
  var self = this,
	flag = 0;
  $.each(workingArea, function () {
	if (currentArea === parseInt(this)) {
	  flag = 1;
	  return false;
	}
  });
  return flag;
}</code></pre>

<code>_work()</code>メソッドは、<code>animate()</code>を使って実際にキャラクターをアニメーションさせる処理を含んでいます。キャラクターがエリアをまたぐ際（次の<code>animate()</code>が呼び出されようとするタイミング）に呼び出されます。


<pre><code>_work: function (map) {
  var self = this,
    randomN = Math.ceil(Math.random() * 5) + 1,
    newMap = {
      fromX: map.fromX,
      fromY: map.fromY,
      toX: Math.floor((map.toX - map.fromX) / randomN + map.fromX),
      toY: map.toY
    };
...
},</code></pre>

<p>まず「働く」座標を決定します。randomNという変数に2～6までのランダムな値を代入します。これが<br />
<code>randomN = Math.ceil(Math.random() * 5) + 1</code><br />
という処理です。</p>

<p>そして<code>newMap</code>という変数に、これからキャラクターを移動させる新しいmapデータを作成します。<code>map</code>のX座標移動量をrandomN（2～6）で割ってランダムな値を出し、<code>toX</code>にセットします。<br />
なお、<code>Math.floor()</code>は小数点以下切り捨てを行う組み込み関数です。</p>

<figure>
<img alt="エリアをランダムな数で分割してそこまで移動するの図" src="http://kaelab.ranadesign.com/blog/entry_assets/201104_rana2011neta3_1.png" width="600" height="160" class="mt-image-none" style="" />
<figcaption>エリアをランダムな数で分割してそこまで移動するの図</figcaption>
</figure>

<p>そしてキャラクターの<code>left</code>スタイルプロパティを<code>animate()</code>させます。</p>
<pre><code>...
// this.$characterBox -&gt; キャラクター画像の入ったdiv
this.$characterBox.animate({
    'left': newMap.toX
  },
  this._computeDuration(newMap),
  'linear',
  function () {
    // self.$character -&gt; キャラクター画像 
    self.$character.attr('src', imgSrc);
    setTimeout(function () {
      // 移動再開
      self.resetMove();
    }, 7500);
  }
);
...</code></pre>
<p><code>this._computeDuration</code>はKaeruクラスのメンバメソッドで、引数にmapオブジェクトを与えると、始点から終点までのduration値を返します。</p>

<p>animate()のコールバックで、キャラクター画像を「働く」画像に切り替え、7500ミリ秒後に移動再開の処理（Kaeruクラスのメンバメソッド<code>this.resetMove()</code>）を行うという流れです。</p>

<p>これでキャラクターが「働く」アクションを追加することができました。<br />
さて・・・その4におそらく続きます。</p>
</section>]]>
    </content>
</entry>

<entry>
    <title>RaNa design WEBSITE RENEWAL PROJECTのネタばらし その2</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/04/rana2011neta2.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.402</id>

    <published>2011-04-07T12:07:35Z</published>
    <updated>2011-04-15T09:36:56Z</updated>

    <summary>昨年末に公開したRaNa design WEBSITE RENEWAL PROJECTの舞台裏エントリーその2です</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rana" label="RaNa" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>昨年末に公開したRaNa design WEBSITE RENEWAL PROJECTの舞台裏エントリーその2です。<a href="/blog/2011/04/rana2011neta1.html">その1</a>の後に読んでいただくとよりお楽しみいただけます。</p>
<p>今回からはJavaScriptの実装についてより深く踏み込んでいきますが、全体のコードは長大なので、要点と思える部分だけ切り取っていく感じでお話できればと思っています。</p>
]]>
        <![CDATA[
<section>
<h3>JavaScriptのフレームワーク</h3>
<p>jQueryを使いました。これ以降の文章でjQueryのメソッド名とかを普通に説明に使っているので、前提になる話として。</p>
<p>フルスクリーンのグラフィックコンテンツなので<a href="http://raphaeljs.com/">Raphaël</a>なんかを使ってみたら面白いんじゃないかということで最初はこれを使ってごにょごにょ作業していたのですが、自分の習熟度が足りない上、スケジュールがあまりないということもあって馴染み深いjQueryだけでやることにしました。アニメーションは結局<a href="http://api.jquery.com/animate/"><code>.animate()</code></a>だけでやっています。</p>
</section>

<section>
<h3>設計と実装編 その2 - ページの構造</h3>
<p>アニメーションの話の前に、ページにどうやってフルスクリーンのコンテンツを乗っけるのかを説明します。簡単に言ってしまうとLightboxです。通常のHTMLから特定のイベントによってフルスクリーンのモーダルウィンドウを出し、その上にAjaxで読み込んだコンテンツを乗っけます。</p>
<p>モーダルウィンドウを出すスクリプトは以前自分で作ったものを改良して使いました。<br />
<a href="http://kaelab.ranadesign.com/blog/demo/smartModalWindow/">&quot;smartModalWindow&quot; jQuery plugin</a><br />
読み込むコンテンツは別のHTMLとして用意しておき、それをsmartModalWindowで読み込みます。</p>

<p>
<figure>
<img alt="RENEWAL PROJECTのネタばらし その2（1）" src="http://kaelab.ranadesign.com/blog/entry_assets/rana2011neta2_1.png" width="590" height="102" class="mt-image-none" style="" />
<figcaption>ファイル別、役割と関係についての概念図</figcaption>
</figure>
</p>

<p>必要なページは、カエルが動き回る初期画面（screen.php）、Twitterにログイン後に参加登録する画面（registration.php）、キャラクターの検索画面（search.php）です。<br />
トップページ（index.php）で全てのJSファイルを読み込み、init.jsによって処理を開始します。init.jsは</p>

<ul>
<li>モーダルウィンドウの呼び出し</li>
<li>画面に乗っかる看板（ナビゲーション）などの出し入れ</li>
<li>screen.phpに関するインスタンスの作成、処理の実行</li>
<li>cookieの処理</li>
</ul>

<p>などを行っています。<br />
基本的にはinit.js以外のJSファイルではクラスや、API用コールバック関数の定義をしているだけで、それを親となる別のファイルから利用している、という構造になっています。</p>

<p>Twitterとの連携については弊社<a href="http://kaelab.ranadesign.com/blog/author/yoshi-zou/">yoshi-zou</a>が、JSONPを生成するAPIを作ってくれましたのでこれを利用します。<br />
<span class="url">例： <a href="http://kaelab.ranadesign.com/api/rnrn/list.php">http://kaelab.ranadesign.com/api/rnrn/list.php</a></span>
</p>
<pre><code>$(&quot;&lt;script/&gt;&quot;, {
    &quot;src&quot;: &quot;http://kaelab.ranadesign.com/api/rnrn/list.php&quot;
}).appendTo(&quot;head&quot;);</code></pre>

<p>こういう感じで<code>script</code>タグとして突っ込むと、特定のコールバック関数が実行されるというもの。上記の例では</p>

<pre><code>function getList(res) {
    var data = res[&quot;block&quot;],
        result = res[&quot;result&quot;];
    if (result == 0) {
        // error
    } else {
        // success
        // script with data
    }
}</code></pre>

<p>こんな感じのコールバック関数を用意しておけば、データを受け取って処理ができます。データを受け取れさえすれば、おなじみの<code>$.ajax()</code>と同じノリでいけます。</p>
</section>


<section>
<h3>設計と実装編 その3 - キャラクターのアニメーション</h3>

<p>画面内のキャラクターは、専用のクラスのインスタンスとして実装します。<code>Kaeru</code>という名前のクラスを作り、prototypeのメソッドとしていろいろな処理をくっつけていきます。キャラクターが行う動作については全てこのクラスを通して行うようにします。<br />
クラス名がKaeruっていうのは安直ですが、すいません、正直何も考えていませんでした。</p>

<pre><code>function Kaeru(args) {
    // 引数でTwitterデータと、Screenオブジェクトを受け取る
    this.data = args.data;
    this.screen = args.screen;
    this.initialize();
}
Kaeru.prototype = {
    conf: { }, // インスタンスの共通設定
    initialize: function() { }, // 初期化処理
    preloadCharacterImgs: function() {}, // キャラクター画像プリロード
    moveInit: function() {}, // 初回の_move()
    resetMove: function() {}, // 特定の位置から移動を再開（マウスアウト時）
    _selectBehavior: function() {}, // behavior（エリアIDが並んだ配列）をランダムで選択して返す
    _move: function() {}, // 実際にキャラクターを動かすメソッド。.animate()を使う
    _getImgsrc: function() {}, // エリアからキャラクターの画像を選択して返す
    _setBaloon: function() {}, // Twitterの吹き出しを生成
    _showBaloon: function() {}, // Twitterの吹き出しを表示
    _hideBaloon: function() {}, // Twitterの吹き出しを隠す
    _computeDuration: function() {} // 次のアニメーションの終点までのdurationを計算して返す
};</code></pre>

<p>別ファイルのscreen.jsで<code>Screen</code>というクラスを定義していて、こいつから<code>Kaeru</code>クラスをインスタンス化して利用しています。「スクリーンの上にカエルが乗っている」というイメージです。ここまでの要件を満たすだけでこれだけの機能が必要になってしまいました・・・。自分にとって必然的にオブジェクト指向っぽい書き方で作った初めての案件かもしれません。</p>

<p>さて、アニメGIFの話をしましょう。弊社デザイナーの近藤が以下のようにバリエーションに飛んだ画像を作ってくれました。</p>

<p>
<figure>
<a href="http://kaelab.ranadesign.com/blog/entry_assets/rana2011neta2_2.png"><img alt="RENEWAL PROJECTのネタばらし その2（2）" src="http://kaelab.ranadesign.com/blog/assets_c/2011/04/rana2011neta2_2-thumb-450x600-82.png" width="450" height="600" class="mt-image-none" style="" /></a>
<figcaption>デザイナー近藤曰く「カエル特戦隊」</figcaption>
</figure>
</p>

<p>縦横の移動だけで、1キャラクターにつき3つの画像が必要です。縦移動（上・下共通）、左へ移動、右へ移動の3種類です。これをエリアが切り替わる際に適当な画像に切り替えることで、キャラクターが縦横無尽に動いているように見せています。（縦横無尽・・・に見えていますよね・・・？）</p>

<p>切り替える画像は<code>_getImgsrc</code>メソッドで適切なものを判断して返しています。コードはこんな感じ。</p>
<pre><code>_getImgsrc: function(map) {
    var direction, imgsrc;
    if ((map.fromX - map.toX) &gt; 0) {
        direction = &quot;left&quot;;
    } else if ((map.fromX - map.toX) &lt; 0) {
        direction = &quot;right&quot;;
    } else if ((map.fromY - map.toY) &gt; 0) {
        direction = &quot;up&quot;;
    } else {
        direction = &quot;down&quot;;
    }
    switch(direction) {
        // 左に進む画像をimgsrcにセット
        case &quot;left&quot;  : imgsrc = this.characterImg.src.moveLeft; break;
        // 右に進む画像をimgsrcにセット
        case &quot;right&quot; : imgsrc = this.characterImg.src.moveRight; break;
        // 上に進む画像をimgsrcにセット
        case &quot;up&quot;    : imgsrc = this.characterImg.src.moveUp; break;
        // 下に進む画像をimgsrcにセット
        case &quot;down&quot;  : imgsrc = this.characterImg.src.moveDown; break;
    }
    return imgsrc;
}</code></pre>

<p>引数mapのデータは前のエントリーで書いた、こんなデータです。<br />
<code>{ fromX: 810, fromY: -55, toX: 810, toY: 80 }</code><br />
また、上に進む画像と下に進む画像は実際は同じ画像です。</p>

<p><code>_move()</code>メソッドをざっくり説明すると</p>
<ul>
<li>次に進むべきをエリアを選択（初期化時にコースは決定している）</li>
<li>適切なキャラクター画像を選択</li>
<li>キャラクターを<code>.animate()</code></li>
</ul>
<p>というような処理を行っています。これを再帰的に実行することでキャラクターがエリアを次々に移動します。</p>
</section>

<p>さて、長くなった割にうまくまとまっていませんが、めげずに「その3」に続く予定です。</p>]]>
    </content>
</entry>

<entry>
    <title>RaNa design WEBSITE RENEWAL PROJECTのネタばらし その1</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/04/rana2011neta1.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.400</id>

    <published>2011-04-04T11:15:00Z</published>
    <updated>2011-04-07T12:33:51Z</updated>

    <summary>昨年末に公開したRaNa design WEBSITE RENEWAL PROJECTですが、どんな仕組みでできているのかネタばらしをしておきたいと思います。</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rana" label="RaNa" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>昨年末に公開したRaNa design WEBSITE RENEWAL PROJECTですが、どんな仕組みでできているのかネタばらしをしておきたいと思います。</p>

<section>
<h3>企画とデザイン</h3>
<p>サイトのトップが工事現場になって、そこにカエルの作業員が動き回る。Twitterとも連動する、というものでした。<br />
最初に受け取ったデザインはこんな感じ。</p>
<p><figure>
<a href="http://kaelab.ranadesign.com/blog/entry_assets/201104_teaser1.png"><img alt="Renewal Project ネタばらし その1（1）" src="http://kaelab.ranadesign.com/blog/assets_c/2011/04/201104_teaser1-thumb-600x450-73.png" width="600" height="450" class="mt-image-none" style="" /></a>
</figure></p>
</section>]]>
        <![CDATA[<section>
<h3>設計と実装編 その1 - キャラクターの移動パターン</h3>
<p>Twitter連動については弊社に実績があったのでなんとなるとして、問題はアニメーションでした。キャラクター自体の動きはGIFアニメで行うことが決まっており、画面内を動き回るアニメーションをJavaScriptでどうやって実現するかがポイントでした。</p>

<p>考えた末、画面内で動き回るところをエリア分割し、それぞれにIDとなる番号を振ることにしました。番号は上から順番に振っていきます。</p>

<p><figure>
<a href="http://kaelab.ranadesign.com/blog/entry_assets/201104_teaser2.jpg"><img alt="Renewal Project ネタばらし その1（2）" src="http://kaelab.ranadesign.com/blog/assets_c/2011/04/201104_teaser2-thumb-600x450-75.jpg" width="600" height="450" class="mt-image-none" style="" /></a>
<figcaption>エリアIDをガリガリ書き込んでみた。試行錯誤</figcaption>
</figure></p>

<p>デザインを印刷した紙に、エリアIDをガリガリ書き込んで、頭の中を整理します。（画像中の赤字のID番号は誤りで、後から書き込んだ青字のID番号が正解となります。エリアと移動方向はセットで考えた方が、データがシンプルになります。）</p>

<p>キャラクターが移動可能なのは、地面と足場×3からなる水平移動エリアと、はしご×4からなる垂直移動エリアです。こいつらの始点と終点の座標をとって、配列に格納して・・・という感じに設計は進んでいきます。具体的にはこの配列のデータは以下のような感じに。</p>

<pre><code>var maps = [
    { fromX: 810, fromY: -55, toX: 810, toY: 80 }, // 0
    { fromX: 810, fromY: 80 , toX: 810, toY: -55 }, // 1
...中略
    { fromX: 934, fromY: 674, toX: 534, toY: 674 }  // 29
];</code></pre>

<p>次はキャラクターがどのエリアをどういう順番で進むかを決めます。とりあえず、キャラクターは全て画面右上のはしごから登場し、同じはしごに戻ってきて画面外へ退場する、ということを決めました。<br />
<p>なのでエリアIDでいうと必ず0番で始まって、1番で終わるということです。さて、この間に通る順番を設定しなければなりません。</p>

<p><figure>
<img alt="Renewal Project ネタばらし その1（3）" src="http://kaelab.ranadesign.com/blog/entry_assets/201104_teaser3.png" width="600" height="120" class="mt-image-none" style="" />
<figcaption>画面の一部と、エリアID</figcaption>
</figure></p>

<p>当然ですが、ある1点からキャラクターが移動できるエリアには制限があります。<br />
例えば0番の移動を行った後に2番の移動を行うことはできません。キャラクターがワープしちゃいますからね･･･。</p>

<p>移動パターンは「エリアIDを順番に指定した配列を20種類くらい用意し、それをランダムに選ぶ」という実装にしました。<br />
（エリアをリアルタイムにランダム選択していくロジックを弊社<a href="/blog/author/keisukey/">山本</a>が書いてくれたのですが、エリア選択の処理が走り続けるので重くて採用しなかったという経緯があります）</p>

<pre><code>var behaviors = [
    [0,5,8,11,10,12,16,22,23,21,24,27,26,28,29,25,19,18,20,22,23,17,14,15,13,9,4,6,7,1],
    [0,6,7,5,8,11,10,12,16,21,24,28,29,25,19,18,20,17,14,15,13,11,10,9,3,2,4,6,7,1],
...中略
    [0,5,8,12,14,15,16,22,23,21,19,18,24,27,26,28,29,25,19,18,20,17,13,11,10,9,3,2,4,1]
];</code></pre>

<p>これでキャラクターをアニメーションさせる道筋が整いました。さー、動かすぞー、というところで今回の記事はここまでです。大分長くなりそうなので、続きはまた後日。</p>

</section>]]>
    </content>
</entry>

<entry>
    <title>Instagram APIとGoogle Maps APIのマッシュアップ 「Gramap」</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/02/instagram-apigoogle-maps-api.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.398</id>

    <published>2011-02-25T11:52:39Z</published>
    <updated>2011-02-28T16:14:43Z</updated>

    <summary>昨年後半くらいから人気がじわじわと出てきた「Instagram」という名のiPh...</summary>
    <author>
        <name>yoshi-zou</name>
        
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="googlemapsapi" label="Google Maps API" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="instagramapi" label="Instagram API" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[昨年後半くらいから人気がじわじわと出てきた「<a href="http://instagr.am/">Instagram</a>」という名のiPhone用カメラアプリ。<br />
その公式APIが出るという噂を聞いたのが先月くらい。<br />
<br />
そして、今月中旬にデベロッパー登録の受付が始まりいつになったら使えるのかと待ちわびていたのですが、先日たまたまデベロッパー用ページにアクセスしたら既にアプリ登録が出来るようになっていたので早速試しに作ってみました。<br />
※注意 2011/2/26現在まだプライベートベータ版です。<br />
<br />
<div id="instagramDemo"></div>
<script type="text/javascript">
$("#instagramDemo").demoEmbedder({
    src: "/blog/api/instagram/index.html",
    width: 600,
    height: 450,
    title: "Instagram & Google maps API Sample"
});
</script><br />
この地図のマーカーをクリックするとその場所で投稿された写真をスライドショーで眺めることができます。<br />
地図を移動させれば世界中の写真を観ることも可能です。<br />
（写真をクリックするとInstagramの個別ページに飛びます。）<br />
<br />
このウェブアプリを作るためにどのようなことをやったかというと<br />
<br />
1.Instagram APIのデベロッパー管理画面でアプリを登録しクライアントキー等を取得<br />
2.サーバサイドのスクリプトでOAuth認証をクリアしてアクセストークンを取得<br />
3.LOCATIONS APIを使って、経度緯度から半径1000m以内で登録された位置情報IDを取得。<br />
4.位置情報から地図のマーカーをセット。<br />
5.マーカーがクリックされた時、位置情報IDからその場所から投稿された写真データを取得。<br />
6.写真データをスライド表示。<br />
<br />
みたいな感じです。<br />
<br />
OAuthに関してはcurl使ってごにょごにょやったら突破出来ました。<br />
Twitterで使っているOAuth1.0と比べるとInstagram APIのOAuth2.0はシンプルで使いやすい感じがします。<br />
<br />
Instagramみたいに写真ありきでここまで流行ったアプリのAPIってあまりまだ無い気もするのでこれから色々出来そうですね。<br />
まだサーバもちょっと重い気がするので、今後の機能拡張も含め期待してます。<br />
<strike>（APIの制限は勘弁ですが。。）</strike><br />
※API制限ありました。1アクセストークンまたは1クライアントIDにつき、1時間5000アクセスまでとのこと。ただしメールでの申請により許可されれば制限をゆるくできるらしい。（2011/2/25現在）<br />
<br />
ちなみにこの素敵なスライドショーは弊社フロントエンドエンジニアの@keiskey氏によるものです。<br />
<br />
また何か良いアイデアを思いついたら紹介したいと思います。
]]>
        
    </content>
</entry>

<entry>
    <title>jQueryプラグインなスライダー slider.jsがWeb Designing 3月号で取り上げられました。</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/02/jquery-sliderjsweb-designing-3.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.397</id>

    <published>2011-02-25T04:13:30Z</published>
    <updated>2011-02-25T04:25:09Z</updated>

    <summary> というわけで、ちょっとだけ使いやすくしました。まだ付けたい機能があるので、おい...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
        <category term="JavaScript/Ajax" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="jquery" label="jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[ <p>というわけで、ちょっとだけ使いやすくしました。<br>まだ付けたい機能があるので、おいおい追加していきます。</p>

<p>使い方は以前の記事<a href="http://kaelab.ranadesign.com/blog/2010/10/jquery.html">「jQueryプラグインなスライダー slider.js」</a>を参考ください。</p>

<p>基本的には、以下のような感じで使えるお手軽仕様です。</p>

<pre><code>
	&lt;div class=&quot;slideFrame&quot; id=&quot;slide-00&quot;&gt;
		&lt;ul class=&quot;slideGuide&quot;&gt;
			&lt;li class=&quot;slideCell&quot;&gt;セル&lt;/li&gt;
			&lt;li class=&quot;slideCell&quot;&gt;セル&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;

	&lt;script&gt;
		$(&quot;#slide-00&quot;).slider();
	&lt;/script&gt;
</code></pre>]]>
        
    </content>
</entry>

<entry>
    <title>rgba()とfilterで背景だけを透過させる。</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/02/rgbafilter.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.396</id>

    <published>2011-02-22T13:56:24Z</published>
    <updated>2011-02-22T14:18:37Z</updated>

    <summary> &quot;背景だけ&quot;を透過させたい時には、background-colorにrgba(...</summary>
    <author>
        <name>山本圭助</name>
        
    </author>
    
        <category term="(X)HTML+CSS" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="css3" label="CSS3" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>
"背景だけ"を透過させたい時には、background-colorにrgba()で色と不透明度を指定してやるだけでOKです。<br />
･･･最近のブラウザは。
</p>
<p>
rgba()に対応してないブラウザ、まぁ主にアレですが･･･にもオリジナルな素晴らしい機能filter: alpha()があります。<br />
filter: alpha(opacity=50)とやると要素の不透明度が50％になるというやつです。<br />
0.5じゃなくて50と指定するところもまた強い自己主張を感じますね。昔気質とでも言いましょうか。
</p>
<p>
しかし、この素敵機能filter: alpha()では、"背景だけ"でなく子要素含め、すべて透過してしまいます。<br />
とても面倒見が良いです。
</p>
<p>
しかし、今回のように"背景だけ"に透過を適用したい。そんな時は"DirectX FilterのGradient Filter"の出番です。
</p>
<p>
これを使って背景にグラデーションしないグラデーションを適用してやるのです。<br />
</p>
<p class="note">
filter: progid:DXImageTransform.Microsoft.Gradient()<br />progidのコロンの後に空白を入れないように注意！</p>
<p><em>引数は以下の通り</em></p>
<ul>
<li>Enabled = 0 / 1<br />1(true)でグラデーション機能の有効化。デフォルトは1。</li>
<li>GradientType = 0 / 1<br />グラデーションの方向。0は縦方向。1は横方向。</li>
<li>StartColorStr = #00000000～#FFFFFFFF<br /><em>なんかちょっと長いここが今回のポイント！</em><br />
グラデーションの開始の透明度＋色をaRGB形式で指定します。aは00(透明)～FF(不透明)</li>
<li>EndColorStr = #00000000～#FFFFFFFF<br />
グラデーションの終了の透明度＋色。</li>
</ul>

<pre><code>// 白の半透明
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#99ffffff,EndColorStr=#99ffffff);
background-color: rgba(255, 255, 255, 0.5);
</code></pre>

<p>
IEはrgba()の指定を無視するので、これで「背景だけに透過」が適用されます。めでたしめでたし。
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Android 1.6で背景画像の表示が乱れる現象</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/02/android16imgload.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.395</id>

    <published>2011-02-21T11:52:58Z</published>
    <updated>2011-02-21T12:49:01Z</updated>

    <summary>Android 1.6（アップデートしていないExperia等）において、CSS Spriteで設定した画像の表示がボヤーッとボケたような表示になる現象を確認しました。これは背景に指定した画像の縦横サイズが一定以上の大きさになった際に起こります。</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="(X)HTML+CSS" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="android" label="Android" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="css" label="CSS" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[<p>Android 1.6（アップデートしていないExperia等）において、CSS Spriteで設定した画像の表示がボヤーッとボケたようになる現象を確認しました。<br />
結論から言うと、これは背景に指定した画像の縦横サイズが一定以上の大きさになった際に起こります。つまり、<strong>縦横が大きすぎる背景画像は正しくロードされないよ</strong>、ということです。<br />
検証のためにデモを作成しました。（CSS Spriteではありませんが）</p>

<p class="link"><a href="/blog/demo/android16imgload">Android 1.6で大きな画像を正しくロードできないデモ</a></p>

<figure>
<img alt="EXPERIA(SO-01B)でのスクリーンショット" src="http://kaelab.ranadesign.com/blog/assets_c/2011/02/android16imgload-thumb-480x854-71.png" width="480" height="854" class="mt-image-none" style="" />
<figcaption>EXPERIA(SO-01B)でのスクリーンショット</figcaption>
</figure>

<p>デモでは以下の4つのサイズのJPEG画像を背景に指定してみました。</p>

<ul class="disclist">
<li>768×480px</li>
<li>1024×640px</li>
<li>1280×800px</li>
<li>1680×1050px</li>
</ul>

<p>EXPERIAのスクリーンショットで分かるように、1680×1050pxではかなり画像が乱れています。仕様書を確認できたわけではないので詳細な仕様は分かりませんが、<strong>どうやら縦1000pxを超えた辺りから怪しくなるようです。</strong>また雰囲気的に、ファイルサイズは関係ないように思います。</p>

<p>もうお気づきかと思いますが対策はシンプルで、画像の縦横サイズを小さくするだけです。CSS Sprite画像の場合は2つに分割するなどして、ファイル1つ辺りの縦横サイズを小さくします。<br />
EXPERIAなどはAndroid 2.1へのアップデートが公開されていますので、Android 1.6のデバイスはこれから減少していくとは思いますが、<a href="https://twitter.com/kddipr/status/4422761896218624">auのIS01などは依然Android 1.6のままですので</a>これからも検証の際にこのような現象にでくわす機会があるかもしれません。</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Sassのデフォルトのオプションを変更する（Windows）</title>
    <link rel="alternate" type="text/html" href="http://kaelab.ranadesign.com/blog/2011/02/sasswindows.html" />
    <id>tag:kaelab.ranadesign.com,2011:/blog//1.394</id>

    <published>2011-02-17T03:50:18Z</published>
    <updated>2011-02-17T03:56:38Z</updated>

    <summary>Windows環境のSassで、デフォルトのオプションを変更する方法を調べました。</summary>
    <author>
        <name>Naoki Sekiguchi</name>
        <uri>http://kaelab.ranadesign.com/blog/author/naoki-sekiguchi/</uri>
    </author>
    
        <category term="Development" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Software" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="sass" label="Sass" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://kaelab.ranadesign.com/blog/">
        <![CDATA[

<p>最近ようやく<a href="http://sass-lang.com/">Sass</a>を使い始めたわけですが、いちいちコマンドラインでオプションを設定するのがめんどくさい・・・と思い、デフォルトのオプションを変更する方法を試行錯誤してみた結果、できました。</p>

<p>例えば、オプション <code>--style</code> のデフォルトは <code>nested</code> ですが、これを <code>--expanded</code> に変更してみます。<br />
まずディレクトリ <span class="path">C:\Ruby\lib\ruby\gems\1.9.1\gems\haml-3.0.25\lib\sass\plugin</span> にある <span class="file">configuration.rb</span> をテキストエディタで開きます。ディレクトリについてはRubyをインストールしたディレクトリに合わせて各自読み替えてください。</p>

<p><img alt="Windows環境でのconfiguration.rbの場所" src="http://kaelab.ranadesign.com/blog/entry_assets/sass_config.jpg" width="535" height="414" class="mt-image-none" style="" /></p>

<p>configuration.rb の末尾に以下のようにオプションを追加し、保存します。</p>

<pre><code>Sass::Plugin.options[:style] = :expanded</code></pre>

<p><img alt="configuration.rbを編集する" src="http://kaelab.ranadesign.com/blog/entry_assets/sass_config2.jpg" width="588" height="363" class="mt-image-none" style="" /></p>

<p>既にコマンドラインでSassを使っている状況でしたら、一旦シェルを閉じて、再起動しましょう。もうこれで、デフォルトのオプションが変更されています。</p>

<p>以下、参考リンクです。<br />
Windows環境でのSassの導入については<a href="http://twitter.com/hamashun">@hamashun</a>さんの記事が大変参考になります。</p>

<ul class="disclist">
<li><a href="http://www.hamashun.me/archives/1294573.html">hamashun.me : Windows PC に Ruby と Sass を導入する方法</a></li>
<li><a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options">File: SASS_REFERENCE - Options</a></li>
<li><a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#output_style">File: SASS_REFERENCE - Output Style</a></li>
</ul>
]]>
        
    </content>
</entry>

</feed>


