<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>Tomomi Imura &#8211; HTML5Experts.jp</title>
	<atom:link href="/girlie_mac/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>Node.jsでSlack Command Botをつくってみよう</title>
		<link>/girlie_mac/22535/</link>
		<pubDate>Fri, 03 Mar 2017 00:00:22 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ECMAScript]]></category>
		<category><![CDATA[ES6]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Slack]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[海外]]></category>

		<guid isPermaLink="false">/?p=22535</guid>
		<description><![CDATA[こんにちは。ごぶさたしています。以前の執筆から１年ちょっとになるのですが、その当時はInternet of Things(IoT)について書いたのですが、最近では市場がある程度まで到達したからでしょうか、それとも脆弱性の...]]></description>
				<content:encoded><![CDATA[<p>こんにちは。ごぶさたしています。以前の執筆から１年ちょっとになるのですが、その当時はInternet of Things(IoT)について書いたのですが、最近では市場がある程度まで到達したからでしょうか、それとも脆弱性の問題を問われることが多くなったせいでしょうか、話題は少し落ち着いてきたかに思われます。さて今ホットな話題は何でしょうか、ということで今回はChat Botsについて書いてみようと思います。</p>

<h3>E-Commerceから Conversational Commerceへ</h3>

<p>ここ最近話題になることが多いAIやBotsですが、私の周りではConversational interface、Conversational UXなどという言葉が去年からたびたび使われるようになっているようです。</p>

<p>これはAmazon Alexaなどのデバイスや、Facebook Messengerなどチャットアプリケーションなどの対話型テクノロジーをいかに活用しその使い勝手をよくするか、ということなのですが、必ずしもアプリケーションのUIデザインそのものを述べているわけではなく、既存のサービスを延長することを指していることも多いでしょう。例えば、今まではモバイル上のアプリケーションのみで車を呼べていたUberが、<a href="https://newsroom.uber.com/messengerlaunch/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Facebook Messenger のチャットからも車をを呼べるような機能</a>を加えたり、Slack上でTaco Bellからタコスをオーダーできる<a href="https://www.tacobell.com/feed/tacobot" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TacoBot</a>、というのもが挙げられます。</p>

<h3>Slack Botを書いてみよう</h3>

<p>さて、というわけで何かBotを書いてみたいと思いませんか？ここはNode.jsでSlack botを作成する方法を紹介したいと思います。</p>

<p>このチュートリアルでは、ディベロッパー向けのHTTPステータスコードのルックアップができるスラッシュ・コマンドを作ってみます。ここでは私が５年ほど前に何気なく作って、Mashableなどで紹介され思わぬ反響を得てしまった<a href="http://http.cat/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTTP Status Cats</a>を使ってみます。具体的には、Slack上でユーザが、<code>/httpstatus [code]</code> （例えば <code>/httpstatus 404</code>）と入力すると、そのステータスコードの意味と猫が一緒に表示される、という簡単なbotです。</p>

<p>まず試してみたい方は、<a href="http://www.girliemac.com/slack-httpstatuscats/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTTP Status Cats command for Slack</a>を自分がアドミン権限のあるのチャットチームにインストールしてみてください。</p>

<p><img src="/wp-content/uploads/2017/02/slack-httpstatuscats.gif" alt="slack-httpstatuscats gif animation" width="640" height="437" class="aligncenter size-full wp-image-22558" /></p>

<p>さて、このチュートリアルは２つのパートに分けられます。</p>

<ol>
<li>スラッシュ・コマンドを書いて、自分のSlackチームにインストールする
<li>OAuthを使ってボットを<a href="https://slack.com/apps" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slack&#8217;s App Directory</a>などで誰もがインストールできるようにする</ol>

<p></ol></p>

<p>とりあえず動くbotを書いてみたい、と思う方は１だけ試してみてで十分ですが、botをみんなにシェアしたい方は２も読んでみてください。</p>

<p><a href="https://github.com/girliemac/slack-httpstatuscats" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ソースコード</a>と実際のボットのインストールボタンは両方GitHubにあります。では始めましょう！</p>

<h2>1 プライベートなスラッシュコマンドボットの作成</h2>

<p>ここで作るのは、Slackの公式な用語でいうところの<a href="https://api.slack.com/custom-integrations" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Integrations</a>というもので、自分のチャットグループ専用のプライベートなbot、もしくはいわゆるAppとして発表する前にドライ・ランを行うことを指します。アカウントを持っていない方はまずサインアップしてから始めましょう。</p>

<h3>1.1 スラッシュコマンドの設定</h3>

<p>ログインして、<a href="https://my.slack.com/services/new/slash-commands" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">my.slack.com/services/new/slash-commands</a>でコマンドを選びます。ここでは<code>/httpstatus</code>と入力し<strong>Add Slash Command Integration</strong>ボタンをクリックして次のステップへ進みます。</p>

<p>Tokenなどの欄がありますが現時点では、(1) Command、 (2) URL、 (3) Method、の３つが必要になります。</p>

<p><img src="/wp-content/uploads/2017/02/slack-config-custom-integration.png" alt="slack-config-custom-integration" width="431" height="640" class="aligncenter size-full wp-image-22561" srcset="/wp-content/uploads/2017/02/slack-config-custom-integration.png 431w, /wp-content/uploads/2017/02/slack-config-custom-integration-202x300.png 202w, /wp-content/uploads/2017/02/slack-config-custom-integration-139x207.png 139w" sizes="(max-width: 431px) 100vw, 431px" /></p>

<p>(1)には、<code>/httpstatus</code>、(3)には、<code>POST</code>、そして(2)のURLは次のように設定してください。</p>

<p>開発中に使用するURLを取得するには<a href="https://ngrok.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ngrok</a>を使ってみましょう。いろいろなツールがあるのですが、これは自分のローカルホストをパブリックURLとしてトンネルできるというとても便利なツールなので私のイチオシです。開発途中にデプロイすることなく、Webhookが手軽に使えます。自分のローカルホスト、たとえば  <code>http://localhost:3000/</code> をつかったままOAuthのテストもできるのです。（注：よく聞かれるのですが、ngrokはあくまでも開発ツールですのでプロダクションには適していません。デプロイメントに関しては最後の章を読んでください）</p>

<p><a href="https://ngrok.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://ngrok.com/</a>から自分のマシンにngrokをインストールしたら、ターミナルで自分の使いたいポート番号（このチュートリアルでは 3000）を設定します。</p>

<p></p><pre class="crayon-plain-tag">$ ngrok http 3000</pre><p></p>

<p>すると下のスクリーンショットのように、Forwardingアドレスが取得できるので、そのURL（例えば<a href="https://71f03962.ngrok.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://71f03962.ngrok.io/</a>)をSlackセッティングの、上のスクリーンショットで示された(2)の欄で使います。</p>

<p><img src="/wp-content/uploads/2017/02/ngrok.png" alt="ngrok" width="640" height="349" class="aligncenter size-full wp-image-22538" srcset="/wp-content/uploads/2017/02/ngrok.png 640w, /wp-content/uploads/2017/02/ngrok-300x164.png 300w, /wp-content/uploads/2017/02/ngrok-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>すべての設定が終えたらSaveボタンを押します。&#8221;Your settings have been saved!&#8221;のメッセージが画面上部に現れるのを確認してください。</p>

<h3>1.2 Node.js を使ってレスポンスを書く</h3>

<p>基本的にbotは、ユーザがSlackインターフェイス上でコマンドを実行した際HTTP POST（または設定次第では GET)によって指定先のURLにメッセージが届け、プログラムでその応答をユーザに返す、という作業になります。</p>

<p>たとえばそのユーザが<code>/httpstatus 302</code>というコマンドを送信した場合、指定URLに送られるデータは次のようになります。</p>

<p></p><pre class="crayon-plain-tag">command=/httpstatus
text=302
response_url=https://hooks.slack.com/commands/1234/5678
…</pre><p></p>

<p>Botは、これに対する応答をユーザに返します。この場合はユーザが尋ねているステータス302の定義と<a href="https://http.cat/302" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">この猫</a>を返しましょう。</p>

<p>ではそのコードを書いてみましょう。</p>

<p>まず、<strong>Express.js</strong>と<strong>body-parser</strong>をインストールします。</p>

<p></p><pre class="crayon-plain-tag">$ npm install express body-parser --save</pre><p></p>

<p><strong>index.js</strong>で、<code>express</code>のインスタンスを作り、先ほどngrokで設定したポート番号、3000でサーバを始動します。</p>

<p></p><pre class="crayon-plain-tag">'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const server = app.listen(3000, () =&gt; { 
console.log('Express server listening on port %d in %s mode', server.address().port, app.settings.env);});</pre><p></p>

<p>次はHTTP POSTルートメソッドで、コマンドを扱います。</p>

<p></p><pre class="crayon-plain-tag">app.post('/', (req, res) =&gt; {
 let text = req.body.text;
 // ここでbotを書きます
});</pre><p></p>

<p>ここで<code>text</code>の値を取得します。HTTP Status botの場合、<code>/httpstatus</code> コマンドの値、例えば&#8221;404&#8243;が <code>text</code>の値になります。同時に、ユーザが数字以外を入力した際にエラーメッセージを送るなどのエラーチェックもしておきましょう。</p>

<p></p><pre class="crayon-plain-tag">if(! /^\d+$/.test(q.text)) { // not a digit
 res.send('Error: enter a valid status code, such as 200');   
 return;
}</pre><p></p>

<p>このエラーは、ユーザだけにプライベートに送信されるメッセージでチャットそのものには表示されません。</p>

<p>エラーがない場合は、コマンドに対する応答をJSONとしてレスポンスします。</p>

<p></p><pre class="crayon-plain-tag">let data = {
 response_type: 'in_channel', 
 text: '302: Found',
 attachments:[{
   image_url: 'https://http.cat/302.jpg'
 }]
};
res.json(data);</pre><p></p>

<p><code>response_type</code>を<code>in_channel</code>とすることで応答はチャットメンバー全員に見えるように送信されます。デフォルトはその逆の<code>ephemeral</code>で、コマンドを送ったユーザのみに表示されます。</p>

<p>このコマンドと応答は次のようになります。</p>

<p><img src="/wp-content/uploads/2017/02/slack-command.png" alt="slack-command" width="640" height="491" class="aligncenter size-full wp-image-22540" srcset="/wp-content/uploads/2017/02/slack-command.png 640w, /wp-content/uploads/2017/02/slack-command-300x230.png 300w, /wp-content/uploads/2017/02/slack-command-207x159.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>このサンプルコードでは、応答をわかりやすくハードコードで示してありますが、実際はストリングなどは別のファイルに定義しています。下のスクリーンショットのように存在しないHTTPステータスに対してのエラーメッセージも定義しましょう。実際のコードは<a href="https://github.com/girliemac/slack-httpstatuscats" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ソースコード</a>を参照してください。</p>

<p><img src="/wp-content/uploads/2017/02/slack-command-private.png" alt="slack-command-private" width="640" height="60" class="aligncenter size-full wp-image-22539" srcset="/wp-content/uploads/2017/02/slack-command-private.png 640w, /wp-content/uploads/2017/02/slack-command-private-300x28.png 300w, /wp-content/uploads/2017/02/slack-command-private-207x19.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ディスプレイはボーダー色などのカスタマイズが可能です。詳しくはSlackドキュメンテーションの<a href="https://api.slack.com/docs/message-formatting" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Basic message formatting</a>を参照してください。</p>

<p>次のステップでは、このボットを自分のチャットグループ以外に配布するために必要な認証とコードのデプロイについてです。</p>

<h2>2. Slack Botのディストリビューション</h2>

<p>この「Custom Integration」をインストール可能な「App」にするには、コードのデプロイをして他のチャットにもインストールできるようにせねばならないのですが、そのためにはあといつくかのステップが必要になります。</p>

<h3>2.1 Appセットアップ</h3>

<p>まず、自分のAppを申請し、クライアントIDやシークレットなどのクレデンシャルを取得します。<a href="https://api.slack.com/apps" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://api.slack.com/apps</a>で<strong>Create an App</strong>ボタンをクリックしてください。</p>

<p><img src="/wp-content/uploads/2017/02/slack-create-app.png" alt="slack-create-app" width="614" height="640" class="aligncenter size-full wp-image-22542" srcset="/wp-content/uploads/2017/02/slack-create-app.png 614w, /wp-content/uploads/2017/02/slack-create-app-288x300.png 288w, /wp-content/uploads/2017/02/slack-create-app-199x207.png 199w" sizes="(max-width: 614px) 100vw, 614px" /></p>

<p>このフォームにはいくつもの欄があり少しわかりづらいのですが、スラッシュコマンドのbotには次の3つが最低必要になります。</p>

<ul>
<li><strong>Basic Information</strong> (at <a href="https://api.slack.com/apps/YOUR_APP_ID/general%29" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://api.slack.com/apps/YOUR_APP_ID/general)</a></li>
<li><strong>OAuth &amp; Permissions</strong> (at …/YOUR_APP_ID/oauth)</li>
<li><strong>Slash Commands</strong> (at …/YOUR_APP_ID/slash-commands)</li>
</ul>

<h3>2.1.1 API Keyを.envファイルに保管</h3>

<p>ここで取得した<code>Client ID</code>、<code>Client secret</code>、<code>Verification token</code>は <strong>.env</strong> ファイルに別に保管してbotのメインのコードから切り離すことを推奨します。gitを使う場合は、このファイルを <strong>.gitignore</strong> ファイルに付け加えるのを忘れずに。</p>

<p></p><pre class="crayon-plain-tag">SLACK_CLIENT_ID=12345XXXXX.09876XXXXX 
SLACK_CLIENT_SECRET=535d2f9....
SLACK_VERIFICATION_TOKEN=42P829U...</pre><p></p>

<h3>2.1.2 Foremanを使う</h3>

<p>他にも手段はありますが、<a href="https://heroku.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Heroku</a>にデプロイするために私は<a href="http://strongloop.github.io/node-foreman/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Node Foreman</a>を使っています。Foremanを使うには、npmを使ってglobalフラッグでインストールしてください。</p>

<p></p><pre class="crayon-plain-tag">$ npm install -g foreman</pre><p></p>

<p>アプリケーションの Root に <code>.procfile</code> を作成し、この一行を加えます。</p>

<p></p><pre class="crayon-plain-tag">web: node index.js</pre><p></p>

<p>index.jsを実行するには <code>node index.js</code>の代わりに次のコマンドを使います。</p>

<p></p><pre class="crayon-plain-tag">$ nf start</pre><p></p>

<h2>2.2 ユーザの認証</h2>

<p>Slackは認証には<a href="https://oauth.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OAuth</a>を使っています。実際には自分でOAuthを実装しなくても、<a href="https://api.slack.com/docs/slack-button" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Slack ボタン</a>を使えば簡単に認証できるようになっています。</p>

<p>公式のドキュメンテーションのダイアグラムに手を加えて、流れをわかりやすくするためにGIFアニメーションにしてみました。</p>

<p><img src="/wp-content/uploads/2017/02/slack-oauth-1.gif" alt="slack-oauth gif animation" width="640" height="387" class="aligncenter size-full wp-image-22559" /></p>

<p>ここでの実際のフローは次のようになります。</p>

<ol>
<li>ウェブページを作成し、認証ボタンを置く。ユーザがボタンをクリックするとパラメータがSlackに送信される(ユーザは認証ページにリダイレクトされる)。
<li>Node appには、SlackからGETで10分だけ有効な仮のコードが送られる。
<li>アクセストークンを得るために <a href="https://api.slack.com/methods/oauth.access" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">oauth.access</a> API使い認証コードをPOSTする。Node app側から`200 OK`を受け取り次第、このプロセスが完了。
<li>オプションとして、このトークンを使ってSlackの他のAPIにもアクセス。例えば、認証後、ユーザをhttps://team-name.slack.comにリダイレクトするなど。/
</ol>

<h3>2.2.1 Slack ボタンの設定</h3>

<p>Slackボタンを使うには、まずウェブページを作成してください。私の場合はこのNode Appとは切り離した別のHTMLページを作成し、<a href="http://www.girliemac.com/slack-httpstatuscats/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GitHub Pages</a>にホストしました。</p>

<p>次にボタンを設定しましょう。 <a href="https://api.slack.com/docs/slack-button" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://api.slack.com/docs/slack-button</a> に行き、<strong>Add the Slack button</strong> までスクロールして下さい。</p>

<p><img src="/wp-content/uploads/2017/02/slack-generate-button.png" alt="slack-generate-button" width="640" height="268" class="aligncenter size-full wp-image-22543" srcset="/wp-content/uploads/2017/02/slack-generate-button.png 640w, /wp-content/uploads/2017/02/slack-generate-button-300x126.png 300w, /wp-content/uploads/2017/02/slack-generate-button-207x87.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>このボタン作成ツールの<strong>Commends</strong>のチェックボックスをチェックします。</p>

<p>上で示したフローの４を実行したい場合は、このGETパラメータを下のように変更します。</p>

<p></p><pre class="crayon-plain-tag">&lt;a href="https://slack.com/oauth/authorize?scope=commands+team%3Aread&amp;client_id=your_client_id"&gt;</pre><p></p>

<p>ここで<code>scope</code>に着目してみてください。<code>commands</code>の他に<code>team:read</code>(コロンは<strong>%3A</strong>とエスケープ)が必要になります。詳しくは<a href="https://api.slack.com/docs/oauth-scopes" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">OAuth scopes on the Slack API docs</a>で。</p>

<p><img src="/wp-content/uploads/2017/02/slack-button.png" alt="slack-button" width="139" height="40" class="aligncenter size-full wp-image-22548" /></p>

<h3>2.2.2 トークンの発行</h3>

<p>さて、Nodeコードに戻りましょう。仮のコード(<code>req.query.code</code>)をGETで取得するためにまたExpress.jsを使います。</p>

<p>何でもよいのですがここでは<code>/slack</code> routeを使いましょう。この場合ngrokのURL は <code>http://71f03962.ngrok.io/slack</code> のようになります。Slack App設定ページ（https://api.slack.com/apps/YOUR_APP_ID/oauth）の、<strong>OAuth &amp; Permissions</strong> セクションにある、<em>Redirect URL</em>の欄にはこのURLを設定してください。</p>

<p>仮の<code>code</code>を取得されたら、それを自分のAPIクレデンシャルとともにPOSTで送って、トークンと交換します。POSTするためにここではNode.jsのHTTPリクエストクライアントである、<code>Request</code>を使いましょう。</p>

<p></p><pre class="crayon-plain-tag">$ npm install request --save</pre><p></p>

<p>仮の<code>code</code>を取得し、それを<code>token</code>と交換するコードが下になります。</p>

<p></p><pre class="crayon-plain-tag">const request = require('request');

app.get('/slack', function(req, res){
 let data = {form: {
   client_id: process.env.SLACK_CLIENT_ID,
   client_secret: process.env.SLACK_CLIENT_SECRET,
   code: req.query.code
 }};

 request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {
   if (!error &amp;&amp; response.statusCode == 200) {
     // おしまい！
     // ここからはオプションでチーム情報を取得
     let token = JSON.parse(body).access_token; // Auth token
   } ...</pre><p></p>

<h3>2.2.3 オプショナル： ユーザをチームURLにダイレクトする</h3>

<p>認証が済んだらそこで終えてもよいのですが、この画面でユーザを置き去りにするのはあまりよいUXとはいえないので、チームページにリダイレクトしてみましょう。</p>

<p>リダイレクトURLのサブドメインとなるチーム名は<a href="https://api.slack.com/methods/team.info" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">team.info</a>APIで取得できます。</p>

<p>このAPIを使うにはトークンが必要なので前述のコードでの、トークンにアクセスする箇所に下のコードを追加します。</p>

<p></p><pre class="crayon-plain-tag">...
request.post('https://slack.com/api/team.info', {form: {token: token}}, function (error, response, body) {
 if (!error &amp;&amp; response.statusCode == 200) {
   let team = JSON.parse(body).team.domain;
   res.redirect('http://' +team+ '.slack.com');
 }
});</pre><p></p>

<p>これで API からチーム名(<code>team.domain</code>)が返されました。最終的にこれを使ってチームURLにリダイレクトしてできあがり！</p>

<p>このチュートリアルでは簡素化したコードを使いましたが、<a href="https://github.com/girliemac/slack-httpstatuscats" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">全ソースコードはGitHubで</a>見てみてください。</p>

<h2>2.3 サーバにデプロイする</h2>

<p>最後にデプロイしておしまいです。APIクレデンシャルの<strong>env vars</strong>設定を忘れないように！私はHerokuを使っているのですが、Herokuの場合、<code>heroku config</code>コマンドを使います。例えば、<code>heroku config:set API_KEY=123456</code>というふうに設定してください。</p>

<p>Slackの設定で画面で指定したngrok URLを、デプロイ先のURLに変更するのもお忘れなく。</p>

<p>さて、プロセスが少し面倒ですが、コード自体は簡単だったと思います。もし何か面白いボットを作った際にはぜひ教えてくださいね！</p>

<p><img src="/wp-content/uploads/2017/02/slack-worked.png" alt="slack-worked" width="200" height="200" class="aligncenter size-full wp-image-22546" srcset="/wp-content/uploads/2017/02/slack-worked.png 200w, /wp-content/uploads/2017/02/slack-worked-150x150.png 150w" sizes="(max-width: 200px) 100vw, 200px" /></p>
]]></content:encoded>
			</item>
		<item>
		<title>JavaScriptエンジニアへのIoTのすすめ：Node.jsとArduinoでスマートデバイスのプロトタイプをしてみよう</title>
		<link>/girlie_mac/17684/</link>
		<pubDate>Thu, 26 Nov 2015 00:00:36 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Internet of Things]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[PubNub]]></category>

		<guid isPermaLink="false">/?p=17684</guid>
		<description><![CDATA[ここ、HTML5Experts.jpでも今年になって IoTやWoT関連の話題がことかかず、みさなんも関心を持ち始めていることかと思われます。 私もフロントエンド・エンジニアではありますが、もともと関心があったことと、去...]]></description>
				<content:encoded><![CDATA[<p>ここ、HTML5Experts.jpでも今年になって IoTやWoT関連の話題がことかかず、みさなんも関心を持ち始めていることかと思われます。</p>

<p>私もフロントエンド・エンジニアではありますが、もともと関心があったことと、去年からデータ・ストリームのPaaS (platform as a service) 会社である<a href="http://pubnub.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PubNub</a>で働いていることもあって、IoTを避けずには通れなくなり、電子工作を始めるようになりました。</p>

<p>そこで、最近東京・渋谷で行われた、東京Node学園で登壇した際に話したテーマ、<a href="https://speakerdeck.com/girlie_mac/tokyo-nodefest-2015-hardware-hacking-for-javascript-developers-japanese-ri-ben-yu" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Hardware Hacking for JavaScript Developers</a> から、ArduinoとNode.jsを使ってプロトタイプする、という内容についてチュートリアル形式で書いてみたいと思います。</p>

<h3>Arduinoが変えたMakerムーブメント</h3>

<p>みなさん、<a href="https://www.arduino.cc/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Arduino</a>の名前は聞いたことがあると思います。Arduino、もしくはGenuinoとして知られているこのオープンソースのAVRマイクロコントローラ電子工作キットは、既存のマイコンボードと違い、安価で、I/Oポートもあり、USB接続で今すぐ始められます。開発環境（IDE）とサンプルコードなども簡単にダウンロード、インストールできることから初心者でも簡単に電子工作ができるようになったという面では、今までハードウェアに縁がなかったソフトウェアエンジニアが、Makerムーブメントに積極的に参加するようになった火付け役ともいえると思います。</p>

<p>しかし、同じソフトウェアといえども、ウェブエンジニアはどうでしょう？Arduinoで使用される言語はC-ベースのSketchということで敷居が高く感じたり、興味がなかったりするのではないでしょうか？でも、もし馴染みのJavaScriptで好きなことができたら、遊んでみたくなりませんか？</p>

<h3>Johnny-Five: JSロボティクス・フレームワーク</h3>

<p>そこで紹介したいのが、JavaScript ロボティクス・フレームワークである、<a href="http://johnny-five.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Johnny-Five</a>。日本ではまださほど知られていない感じがしますが、オープンソースでディベロッパ・コミュニティの結束も固く、<a href="http://nodebots.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">インターナショナル NodeBots Day</a>などでユーザ・コミュニティも大きくなってきたこのフレームワークを使えば、JavaScriptをで簡単にプログラマブル電子工作ができるようになります。ここは説明よりも実践してみるほうが理解も深まると思いますので、さっそくチュートリアルを始めましょう！</p>

<p><img src="/wp-content/uploads/2015/11/arduino-loves-j5.png" alt="arduino nodejs johnny-five" width="640" height="236" class="aligncenter size-full wp-image-17712" srcset="/wp-content/uploads/2015/11/arduino-loves-j5.png 640w, /wp-content/uploads/2015/11/arduino-loves-j5-300x111.png 300w, /wp-content/uploads/2015/11/arduino-loves-j5-207x76.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>1. Arduino のセットアップ</h2>

<p>用意するハードウェアとインストールの必要なソフトウェア</p>

<ul>
<li><a href="https://www.arduino.cc/en/Main/ArduinoBoardUno" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Arduino (Genuino) Uno</a></li>
<li><a href="http://arduino.cc/en/main/software" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Arduino IDE</a></li>
<li><a href="https://nodejs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Node.js</a> </li>
</ul>

<p>始めにセットアップから始めます。ArduinoボードをUSBで、コンピュータにつなぎます。Arduino IDEをダウンロード、インストールして、起動させたら、ボードとシリアルポートの設定をします。</p>

<p>メニューの<strong>ツール</strong> &gt; <strong>マイコンボード</strong>の中の<strong>Arduino Uno</strong>を選択し、 <strong>ツール</strong> &gt; <strong>シリアルポート</strong>の中の<strong>/dev/tty.usbmodem</strong>、もしくは<strong>cu.usbmodem</strong>という名前が含まれる項目を選びます。</p>

<p><img src="/wp-content/uploads/2015/11/arduino-johnnyfive-setup-jp.png" alt="Arduino setup" width="640" height="180" class="aligncenter size-full wp-image-17690" srcset="/wp-content/uploads/2015/11/arduino-johnnyfive-setup-jp.png 640w, /wp-content/uploads/2015/11/arduino-johnnyfive-setup-jp-300x84.png 300w, /wp-content/uploads/2015/11/arduino-johnnyfive-setup-jp-207x58.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Johnny-FiveはFirmataプロトコルを使ってArduinoと通信をするので、今度は<strong>StandardFirmata</strong>をインストールします。</p>

<p>メニューから<strong>ファイル</strong> &gt; <strong>スケッチの例</strong> &gt; <strong>Firmata</strong> &gt; <strong>StandardFirmata</strong>を選択すると新しいウィンドウが開きます。そこから左から２番目にあるアップロードボタンをクリックします。下のGIFアニメーションの通りです。</p>

<p><img src="/wp-content/uploads/2015/11/arduino-johnnyfive-firmata-jp.gif" alt="Arduino setup GIF animation" width="640" height="512" class="aligncenter size-full wp-image-17727" /></p>

<p>終わったら閉じ、このIDEはもうこれからは必要ありません。</p>

<h2>2. Hello World</h2>

<p>まずコンピュータに、Node.jsがすでにインストールされていることを、確認してください。そして適当なディレクトリ (e.g. /j5-hello/) を作ったら、そのディレクトリ内にパーケッジマネージャであるnpmを使って、Johnny-Fiveをインストールします。</p>

<p><code>$ npm install johnny-five</code></p>

<p>さっそくJohhny-Fiveを使ってはじめの一歩である、Hello Worldを書いてみましょう。新しい言語やフレームワークを学ぶ際に初めて書くプログラムは&#8221;Hello world&#8221;という2つの単語を出力する、というのが一般ですが、ここでは、ハードウェア界のHello Worldとも言える「Lチカ」（LEDを点滅させる）をしてみます。</p>

<h3>必要なハードウェア</h3>

<ul>
<li>セットアップ済みのArduino Uno</li>
<li>LED</li>
<li>ブレッドボード </li>
<li>ジャンパー・ワイヤー（両側がピン状になっているオス〜オス）</li>
<li>抵抗　（200-330Ω 程度）</li>
</ul>

<p><img src="/wp-content/uploads/2015/11/arduino-hello-world-jp.jpg" alt="Arduino LED blink" width="640" height="318" class="aligncenter size-full wp-image-17692" srcset="/wp-content/uploads/2015/11/arduino-hello-world-jp.jpg 640w, /wp-content/uploads/2015/11/arduino-hello-world-jp-300x149.jpg 300w, /wp-content/uploads/2015/11/arduino-hello-world-jp-207x103.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>まずはハードウェア側のセッティングです。
部品などどこで買ったらわからない、という方はAmazonなどでキットを買うのをお勧めします。</p>

<h3>LEDの基本</h3>

<p>LED（発光ダイオード）には、極性があり、その＋極を<strong>アノード</strong>、ー極を<strong>カソード</strong>と呼びます。普通のLEDには通常、足が二本ついていますので長い方がアノードです。これは回路を作るときに重要になってきますので必ず覚えておいてください！</p>

<p><img src="/wp-content/uploads/2015/11/led-anode-cathode-jp.png" alt="LED anode and cathode" class="aligncenter" /></p>

<h3>電気回路の作成</h3>

<p>ArduinoからLEDを光らせるための回路はこんな感じになります。ここでは便宜上、電源からつながるプラス側を赤、Groundにつながるマイナス側を黒のワイヤーで示してあります。何色を使っても構いませんが、混乱を避けるために2つの異なる色にすることをお勧めします。</p>

<p><img src="/wp-content/uploads/2015/11/arduino-uno-led_bb.png" alt="Fritzing Arduino Uno LED" width="640" height="483" class="aligncenter size-full wp-image-17716" srcset="/wp-content/uploads/2015/11/arduino-uno-led_bb.png 640w, /wp-content/uploads/2015/11/arduino-uno-led_bb-300x226.png 300w, /wp-content/uploads/2015/11/arduino-uno-led_bb-207x156.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ブレッドボードや抵抗についての基本、そしてこの「Lチカ」の回路については<a href="https://html5experts.jp/youtoy/12029/" data-wpel-link="internal">初心者でもわかる・できる！Arduinoを使った初めての電子工作実践</a>の<strong>「部品をつなぐ」</strong>セクションで豊田陽介さんが詳しく説明されているので、それを参考にしましょう。</p>

<h3>Johnny-FiveでLチカ</h3>

<p>では、適当なファイルネーム、例えば<code>blink.js</code>を作成し下のコードをコピーペーストしてください。</p>

<p></p><pre class="crayon-plain-tag">var five = require('johnny-five');
var board = new five.Board();

board.on('ready', function() {
  var led = new five.Led(13);
  led.blink(500);
});</pre><p></p>

<p>ターミナルからこのファイルを走らせましょう。</p>

<p><code>$ sudo node blink.js</code></p>

<p>正しく作動しましたか？回路が正しく、コードにエラーがない場合は、500ms間隔でLEDが点滅します。</p>

<p><img src="/wp-content/uploads/2015/11/arduino-johnnyfive-blink.gif" alt="LED blink animated GIF" class="aligncenter" /></p>

<p>これで、JavaScriptとハードウェアを使う基本を学びましたので、今度は実際にスマートデバイスのプロトタイプを作ってみましょう。</p>

<h2>3. スマート照明システムをプロトタイプする</h2>

<p><a href="http://www2.meethue.com/ja-JP/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Philips HUE</a>や、<a href="http://www.lifx.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">LIFX</a>は、ムードや状況によってスマートフォンやタブレットから、明かりの色や照度をカスタマイズできるLED電球です。さっそく Arduinoを使ってこれらのように色を自在に変えられるLEDを作ってみましょう。色を変えるためのコントローラはHTML５を使ってブラウザから操作できるようにしましょう。</p>

<h3>JavaScript で Internet of Things</h3>

<p>さて、ここで重要なのは、デバイス（ハードウェア）とモバイルUI (HTML5)をインターネットでつなげて、IoT化するということです。Bluetoothなどと違い、インターネットにさえ繋がっていれば、あなたが世界のどこにいようともモバイルから自宅の照明の操作をすることができるのです。この2ウェイ・コミュニケーションを可能にするにはソケット・コネクションが必要になります。ここで、この双方向通信を簡単に行うことにできるPubNubのJavaScript APIを使って、IoTのプロトタイプをしてみましょう。</p>

<p><a href="http://pubnub.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PubNub</a> はグローバルなデータストリームネットワーク (DSN) で、 このAPIを使ってリアルタイムアプリケーション、IoTデバイスなどを接続、拡張、管理することができます。今から作成するスマートLEDは下の図のようにモバイルデバイス（このプロトタイプの場合はブラウザ）とハードウェアをインターネットでつなげることが可能です。</p>

<p><img src="/wp-content/uploads/2015/11/pubnub-arduino.png" alt="How PubNub makes an Arduino as an IoT device" width="640" height="233" class="aligncenter size-full wp-image-17720" srcset="/wp-content/uploads/2015/11/pubnub-arduino.png 640w, /wp-content/uploads/2015/11/pubnub-arduino-300x109.png 300w, /wp-content/uploads/2015/11/pubnub-arduino-207x75.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>例えば、サンフランシスコにいるモバイルユーザが東京にあるArduinoを操作する場合：</p>

<ol>
<li>ユーザがモバイルから「緑い照明にしたい」と送信（パブリッシュ）</li>
<li>メッセージがPubNubのサンスランシスコデータセンターに送信される</li>
<li>データは世界各地のデータセンターと同期</li>
<li>Arduinoが東京データセンターからデータを受信（サブスクライブ）して、LEDを緑に</li>
</ol>

<p>この全てのオペレーションがわずか¼秒かそれ以下で行われるのが、PubNubの利点です。</p>

<p>このチュートリアルではJavaScriptを使ってプロトタイプを作りますが、PubNubの組み込みとモバイルのSDKを使えば、実際にHUEのようなスマートデバイスを製品化することも可能なのです。</p>

<h3>必要なハードウェア</h3>

<ul>
<li>Arduino Uno</li>
<li><a href="http://www.amazon.co.jp/100%E5%80%8B-5%E3%83%9F%E3%83%AA%E3%83%A1%E3%83%BC%E3%83%88%E3%83%AB-4%E3%83%94%E3%83%B3-RGB-%E3%82%AB%E3%82%BD%E3%83%BC%E3%83%89/dp/B00HIUDSJK/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">RGBフルカラーLED（カソードコモン）</a></li>
<li>ブレッドボード </li>
<li>ジャンパー・ワイヤー（オス〜オス）</li>
<li>抵抗　（220Ω x 2, 330Ω x 1）</li>
</ul>

<p><img src="/wp-content/uploads/2015/11/arduino-rgbled-jp.jpg" alt="Arduino RGB LED JP" width="640" height="273" class="aligncenter size-full wp-image-17702" srcset="/wp-content/uploads/2015/11/arduino-rgbled-jp.jpg 640w, /wp-content/uploads/2015/11/arduino-rgbled-jp-300x128.jpg 300w, /wp-content/uploads/2015/11/arduino-rgbled-jp-207x88.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>RGBフルカラーLEDの基本</h3>

<p>RGB (Red-Green-Blue) フルカラーLEDは、赤、緑、青の3色のLEDが一本になったもので、この三原色の組み合わせで無数の色を作り出すことができます。ほとんどのこのタイプのLEDは、各色のピンが一本づつと共通のカソード（もしくはアノード）の合計4本のピンがあります。このチュートリアルでは、カソードコモンのものを使用しています。</p>

<p><img src="/wp-content/uploads/2015/11/led-rgb-cathode-jp.png" alt="RGB LED JP" width="640" height="151" class="aligncenter size-full wp-image-17703" srcset="/wp-content/uploads/2015/11/led-rgb-cathode-jp.png 640w, /wp-content/uploads/2015/11/led-rgb-cathode-jp-300x71.png 300w, /wp-content/uploads/2015/11/led-rgb-cathode-jp-207x49.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>電気回路の作成</h3>

<p>Hello World を成功させたからには、この下の図の回路も問題なく作れるのではないでしょうか。がんばってみてください。</p>

<p>ワイヤーを差し込むピンは、単純な「Lチカ」とは違い、PWM (Pulse Width Modulation：パルス幅変調) ピンを使っています。Arduinoボードにラベルされているピン番号の前に「〜」が付いているものがPWMピンになります。</p>

<p>これらと他のピンの違いは、簡単にいえばアナログかデジタルかの違いになります。例えばLEDの場合、一般のデジタルピンにつなぐとオフかオンの2つのステートしか表現できません。Lチカ（点滅）はこのデジタル信号をオンとオフと交互に発しています。しかしRGBフルカラーLEDで無数の色を表現するには、各色の値の組み合わせで色を作り出すので中間の値が必要になりますので、アナログであるPWMピンを使います。</p>

<p><img src="/wp-content/uploads/2015/11/arduino-uno-rgb-led_bb.png" alt="Fritzing Arduino RGB LED" width="640" height="476" class="aligncenter size-full wp-image-17719" srcset="/wp-content/uploads/2015/11/arduino-uno-rgb-led_bb.png 640w, /wp-content/uploads/2015/11/arduino-uno-rgb-led_bb-300x223.png 300w, /wp-content/uploads/2015/11/arduino-uno-rgb-led_bb-207x154.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ここで抵抗を220Ωと330Ωにわけてあるのは、同じ抵抗だと赤が強くなるので、抵抗を増やして赤を控えめな明かるさになるように調整してあります。抵抗の計算方法やカラーコードの読み方については、ここで割愛しますが、自分でいろいろ調整してみてください。</p>

<h3>IoT リモートコントローラーUIの作成</h3>

<p>ブラウザでLEDの色をコントロールするUIを作ってみましょう。</p>

<p><img src="/wp-content/uploads/2015/11/hue-prototype-ui.png" alt="hue-prototype-ui" width="640" height="434" class="aligncenter size-full wp-image-17707" srcset="/wp-content/uploads/2015/11/hue-prototype-ui.png 640w, /wp-content/uploads/2015/11/hue-prototype-ui-300x203.png 300w, /wp-content/uploads/2015/11/hue-prototype-ui-207x140.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>HTML5の&#8220;、&#8221;R&#8221;、&#8221;G&#8221;、&#8221;B&#8221;の各色調整をするスライダーバーを描写します。各色は0から255まで(<code>min="0" max="255"</code>)の整数の値(<code>step="1"</code>)を、つまみで調節できるようなUIにしてみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;input id="red" type="range" min="0" max="255" step="1" value="0"&gt;</pre><p></p>

<p>これで赤色を調節するスライダーができました。このチュートリアルではCSS部分は省略しますが、スクリーンショットのようなスタイルにするには、<a href="https://github.com/girliemac/arduino-led-rgb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GitHubのソースコード</a>の<a href="https://github.com/girliemac/arduino-led-rgb/tree/gh-pages" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gh-pages ブランチ</a>を参照してください。</p>

<p>次はJavaScriptでこの値がユーザによって変更された時に、その値をArduino側に反映させるようにします。これを実現させるためにPubNub JavaScript APIで両デバイスを接続させてみましょう。</p>

<p>PubNub JavaScript API を使うには、まず自分の<a href="https://admin.pubnub.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">APIキーを取得</a>を取得したら、CDNライブラリ（もしくはローカルファイル）を読み込みます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="//cdn.pubnub.com/pubnub-3.7.15.min.js"&gt;&lt;/script&gt;</pre><p></p>

<p>そして自分のキーを使ってインスタンスを初期化します。</p>

<p></p><pre class="crayon-plain-tag">var pubnub = PUBNUB({
　subscribe_key : '自分の subscribe key',                          
　publish_key   : '自分の publish key'
});</pre><p></p>

<p>UIイベント発生時に自動的にLEDの色を変える仕様にしてみましょう。
スライダーDOMに<code>change</code>イベントが発生した時に、変更値をPubNubに <code>publish</code> メソッドを使って送信（パブリッシュ）します。</p>

<p></p><pre class="crayon-plain-tag">var red = document.getElementById('red');

red.addEventListener('change', function(){
  pubnub.publish({
    channel: 'smart-led', 
    message: {color: 'red', brightness: +this.value}
  });
}, false);</pre><p></p>

<p>この時の <code>channel</code> 名は何でも構いませんが、のちにこのデータを受信する際にはこれと同じチャンネル名にします。</p>

<p>では次はNode.jsを使ってハードウェア側でこの値を反映させてみましょう。</p>

<h3>Johnny-Five と PubNub で Arduino を IoTデバイスに</h3>

<p>Johnny-FiveでRGBフルカラーLEDを動かすコードは、いたって簡単。npmでjohnny-fiveをインストールしたら、次のコードを動かしてみてください。</p>

<p></p><pre class="crayon-plain-tag">var five = require('johnny-five');
var led;

five.Board().on('ready', function() {
  console.log('ready');

  // RGB LED を初期化
  led = new five.Led.RGB({
    pins: { // pin 番号
      red: 6,
      green: 5,
      blue: 3
    }
  });

  // テスト
  led.color({red: 255, blue: 0, green: 0});
  
  led.on();
});</pre><p></p>

<p>LEDが赤色に光ましたか？
何も起こらない場合はコードと配線などを確かめてください。それでも作動しない場合は、使っているRGB LED がカソードコモンではなくアノードコモンの可能性があります。その場合は、GND（図上の黒のワイヤー）を、Arduinoの5Vのピンに変えてみてください。</p>

<p>「テスト」とコメントされた行をみてください。<code>color</code> メソッドでLEDの色を指定しているのがわかると思います。この場合、赤の値が255で他が0となっているので、LEDを赤で光らせることができます。Johnny-Fiveでは、CSSのcolorプロパティと同じようにRGBの値を0～255で指定することができるのです。RGBの各値を変えながらどんな色になるか実験してみてください。</p>

<p>さて今度は、このRGBの値をブラウザUIからリモートコントロールして、動的にLEDの色を変えてみましょう。</p>

<p>さきほどのUI側からパブリッシュされたデータを受け取って、ハードウェアに反映させるには、PubNub <code>subscribe</code> メソッドで受信（サブスクライブ）しましょう。</p>

<p>まず、npm で pubnub をインストールします。</p>

<p><code>$ npm install pubnub </code></p>

<p>フロントエンドと同様に、pubnubインスタンスの初期化します。</p>

<p></p><pre class="crayon-plain-tag">var pubnub = require('pubnub').init({
  subscribe_key: '自分の subscribe key',
  publish_key:   '自分の publish key'
});</pre><p></p>

<p>UI側から送信されたデータは、同じ <code>channel</code> にアクセスすることによって自動的に送信することができます。データが送信された際には、<code>subscribe</code> メソッドの <code>callback</code> が返されます。このコールバック内で送信された色データをLEDに反映させます。</p>

<p></p><pre class="crayon-plain-tag">pubnub.subscribe({
  channel: 'smart-led',
  callback: function(m) {
    if(led) {
      r = (m.color === 'red') ? m.brightness : r;
      g = (m.color === 'green') ? m.brightness : g;
      b = (m.color === 'blue') ? m.brightness : b;

      led.color({red: r, blue: b, green: g});

      console.log( 'color change to...' );
      console.log( led.color() );
    }
  }
  error: function(err) {console.log(err);}
});</pre><p></p>

<p>送信されたメッセージ、<code>m</code> は、UIから送られたオブジェクト、例えば青の値が150の場合、<code>{color: 'blue', brightness: 150}</code>、となります。次に送信された値が、<code>{color: 'red', brightness: 150}</code> ならば、前の値の青＝150はそのままで、ここに赤＝150が加わることによって、LEDは紫に近い色になります。さらに赤緑青の3つの値が変われば、LEDはさまざまな色に変わります。</p>

<p><img src="/wp-content/uploads/2015/11/poormans-philips-hue.jpg" alt="IoT 101 Arduino with RGB LED" width="640" height="480" class="aligncenter size-full wp-image-17705" srcset="/wp-content/uploads/2015/11/poormans-philips-hue.jpg 640w, /wp-content/uploads/2015/11/poormans-philips-hue-300x225.jpg 300w, /wp-content/uploads/2015/11/poormans-philips-hue-207x155.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>全コードは、<a href="https://github.com/girliemac/arduino-led-rgb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GitHubのソースコード</a>の<a href="https://github.com/girliemac/arduino-led-rgb" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">master ブランチ</a>内の <code>/node/index.js</code>を参照してください。</p>

<p>さて、これでIoTスマート照明のプロトタイプができあがりました！</p>

<p><img src="/wp-content/uploads/2015/11/arduino-johnnyfive-hue.gif" alt="arduino-johnnyfive-hue" width="371" height="317" class="aligncenter size-full wp-image-17706" /></p>

<p>Johnny-FiveもPubNubもArduinoだけではなく、他のいろいろなマイクロコンピュータに使うことができます。いろいろなセンサーやカメラなどを組み合わせて、IoTプロトタイプに挑戦してみてください。</p>

<p>では、Happy hacking!</p>

<h2>References</h2>

<ul>
<li><a href="http://johnny-five.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Johnyy-Five</a>: The original JavaScript Robotics programming framework</li>
<li><a href="https://www.pubnub.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PubNub</a>: The global realtime Data Stream Network for IoT, mobile, and web applications</li>
</ul>
]]></content:encoded>
			</item>
		<item>
		<title>PolymerでMaterial Designなチャットアプリを作ろう</title>
		<link>/girlie_mac/12359/</link>
		<pubDate>Tue, 27 Jan 2015 01:29:37 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=12359</guid>
		<description><![CDATA[今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実...]]></description>
				<content:encoded><![CDATA[<p>今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実際に、PolymerとMaterial Designのデザインコンセプトを用いて、視覚的にもユーザエクスペリエンスにも優れたチャットアプリを実際に作ってみましょう。</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat-cover.png" alt="Material Design and Polymer" width="1360" height="600" class="aligncenter size-full wp-image-12358" srcset="/wp-content/uploads/2015/01/paper-chat-cover.png 640w, /wp-content/uploads/2015/01/paper-chat-cover-300x132.png 300w, /wp-content/uploads/2015/01/paper-chat-cover-1024x451.png 1024w, /wp-content/uploads/2015/01/paper-chat-cover-207x91.png 207w" sizes="(max-width: 1360px) 100vw, 1360px" /></p>

<p>まず始める前にこのライブデモ、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Kitteh Anonymous</a>をデスクトップまたはモバイルのモダンブラウザで実際に試してみてください。ここでは、このデモの簡略版である<a href="http://pubnub.github.io/paper-chat/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Liteバージョン</a>を実際に作成する方法をステップ・バイ・ステップで紹介したいと思います。</p>

<h3>必要な知識</h3>

<ul>
    <li><a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>の基礎知識</li>
    <li>パッケージマネージャ、<a href="https://www.polymer-project.org/docs/start/getting-the-code.html#using-bower" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Bower</a>の基本的な使い方（Polymerと依存するファイルをインストール、アップデートするのに使いますが、必ずしも使う必要はありません）</li>

</ul>

<p>泉水翔吾さんの記事、<a href="https://html5experts.jp/1000ch/11905/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう</a>や、佐藤歩さんの<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a>を先に読むのをおすすめします。</p>

<h3>PolymerとWebスタンダード</h3>

<p>ちまたに数多く存在する、JavaScript UI library。<a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>も単にまたそのひとつ、と思うかもしれません。しかしPolymerが他と違うのは、これがW3C WebプラットフォームプリミティブのWeb Componentsを基礎に作られていることです。このWeb Componentsファミリーに含まれるものに</p>

<ul>
    <li><a href="http://w3c.github.io/webcomponents/spec/shadow/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Shadow DOM</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/custom/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Custom Elements</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/imports/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">HTML Imports</a></li>
</ul>

<p>などが挙げられます。</p>

<p>そしてPolymerに含まれる<pre class="crayon-plain-tag">webcomponents.js</pre> は W3C DOM4の<a href="http://www.w3.org/TR/dom/#mutation-observers" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">DOM mutation observers</a>や ECMAScript standardsである <pre class="crayon-plain-tag">Object.observe()</pre> のPolyfillの役目を果たしています。</p>

<h3>レゴブロックのようにWebを構築しよう</h3>

<p><img src="/wp-content/uploads/2015/01/lego.png" alt="lego" width="150" class="alignright size-full wp-image-12352" srcset="/wp-content/uploads/2015/01/lego.png 300w, /wp-content/uploads/2015/01/lego-261x300.png 261w, /wp-content/uploads/2015/01/lego-180x207.png 180w" sizes="(max-width: 300px) 100vw, 300px" />
Polymer webコンポーネントはカプセル化された何度も再利用できるコンポーネント。まるでレゴで家を構築するかのように、既存のパーツを使ったり自分で組み立てたパーツを使ったりと、いろいろなパーツを組み合わせてWebアプリを作ることができます。</p>

<p>実際にPolymerでアプリを作るには、まず必要な要素をインポートしてから使うことになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- Import element --&gt; 
&lt;link rel="import" href="paper-fab"&gt; 
... 
&lt;!-- Use element --&gt; 
&lt;paper-fab icon="send"&gt;&lt;/paper-fab&gt;</pre><p></p>

<h3>Material DesignとPolymerの関係</h3>

<p><a href="http://www.google.com/design/spec/material-design" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Material Design</a>は、既存のどのスクリーンサイズやデバイスにでも対応できる、ビジュアルとインタラクションデザインにすぐれたデザインスペックで、もともとはAndroid 5.0 Lollipop用にデザインされたものが、のちにWeb用としてPolymerのPaper Elementsとして適応されるようにました。</p>

<h2>1. Paper Elementsを使ってみよう</h2>

<p>さて実際にこれらを使って自分のアプリを作ってみましょう。 まず、Polymerをインストール、そしてアプリ構築に必要なコンポーネントをインポートします。</p>

<h3>1.1. Polymerをインストール</h3>

<p><pre class="crayon-plain-tag">$ bower install --save Polymer/polymer</pre></p>

<p>これで必要最低限のファイルがそろいます。</p>

<p><img src="/wp-content/uploads/2015/01/install-polymer.png" alt="polymer file structure" width="1032" height="443" class="aligncenter size-full wp-image-12357" srcset="/wp-content/uploads/2015/01/install-polymer.png 640w, /wp-content/uploads/2015/01/install-polymer-300x128.png 300w, /wp-content/uploads/2015/01/install-polymer-1024x439.png 1024w, /wp-content/uploads/2015/01/install-polymer-207x88.png 207w" sizes="(max-width: 1032px) 100vw, 1032px" /></p>

<p>インストールが終わったら、index.htmlの <pre class="crayon-plain-tag">&lt;head&gt;</pre> セクションに、 <pre class="crayon-plain-tag">webcomponents.min.js</pre> のみをロードさせます。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt; 
&lt;html&gt; 
  &lt;head&gt; 
    &lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt; 
  &lt;/head&gt; 
  &lt;body&gt;
...</pre><p></p>

<h3>1.2. UI コンポーネントをインポート</h3>

<p>このデモのUIには、いくつかのPolymer CoreとPaper Elements、そして自作のカスタム要素が使われています。</p>

<ol>
    <li>core-scaffold (レスポンシブレイアウトを構成するheader、toolbar、menuなどがすでに揃った骨組み)</li>
    <li>core-item</li>
    <li>paper-input</li>
    <li>paper-fab</li>
    <li>カスタム (のちに作成しましょう)</li>
</ol>

<p><img src="/wp-content/uploads/2015/01/md-polymer-components.png" alt="polymer paper elements" width="855" height="345" class="aligncenter size-full wp-image-12356" srcset="/wp-content/uploads/2015/01/md-polymer-components.png 640w, /wp-content/uploads/2015/01/md-polymer-components-300x121.png 300w, /wp-content/uploads/2015/01/md-polymer-components-207x83.png 207w" sizes="(max-width: 855px) 100vw, 855px" /></p>

<p>Bowerを使って４つのcomponentsをインストールします。</p>

<p></p><pre class="crayon-plain-tag">$ bower install Polymer/core-scaffold 
$ bower install Polymer/core-item 
$ bower install Polymer/paper-input 
$ bower install Polymer/paper-fab</pre><p></p>

<p>インストールが終わったら、これらをHTML importsを使ってインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt;   

&lt;link rel="import" href="bower_components/core-scaffold/core-scaffold.html"&gt; 
&lt;link rel="import" href="bower_components/core-item/core-item.html"&gt; 
&lt;link rel="import" href="bower_components/paper-input/paper-input.html"&gt; 
&lt;link rel="import" href="bower_components/paper-fab/paper-fab.html"&gt;</pre><p></p>

<p>このようにすることで、これらの要素がDOM上で使われる前に依存ファイルを含めて全てがしっかりロードされることになります。</p>

<h3>1.3. ベーシックUIの構成</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> を使って、ベースとなるレイアウトを構成しましょう。この要素は、レスポンシブな骨組みを簡単に作る(scaffold）ことができる便利な要素で、サブコンポーネントとして <pre class="crayon-plain-tag">&lt;core-header-panel&gt;</pre> 、 
<pre class="crayon-plain-tag">&lt;core-toolbar&gt;</pre> 
、 <pre class="crayon-plain-tag">&lt;core-drawer-panel&gt;</pre> などがすでに含まれています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;core-scaffold&gt;

    &lt;!-- ドロウアーパネル --&gt;
    &lt;core-header-panel navigation flex&gt;
        &lt;core-toolbar class="tall"&gt;
            &lt;!-- an avatar and username will be here --&gt;
        &lt;/core-toolbar&gt;
    &lt;/core-header-panel&gt;

    &lt;!-- アプリのタイトル --&gt;
    &lt;div tool layout horizontal flex&gt;
        &lt;span flex&gt;Kitteh Anonymous&lt;/span&gt;
        &lt;core-icon icon="account-circle"&gt;&lt;/core-icon&gt;
        &lt;span&gt;&lt;!-- number of people online --&gt;&lt;/span&gt; 
    &lt;/div&gt;

    &lt;!-- メインコンテンツ --&gt;
    &lt;div flex&gt;
            ...
    &lt;/div&gt;
  &lt;/core-scaffold&gt;
&lt;/body&gt;</pre><p></p>

<p>これでアプリのコア・ストラクチャーができました。  <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> は実際はこの例よりもより簡単に使うとこができるのですが、このデモでは左のドロウアー部分のヘッダの高さをかえて、ベーシックスタイルよりも少し凝ったデザインにしています。</p>

<p>ここで <pre class="crayon-plain-tag">&lt;body&gt;</pre> に見慣れない属性が使われていることにお気づきかと思います。 この <pre class="crayon-plain-tag">fullbreed</pre> はbodyをビューポートにぴったり合わせるため、 <pre class="crayon-plain-tag">unresolved</pre> はスタイライズされていないコンテンツが一瞬画面に表示される現象(FOUC)を防ぐために使われています。</p>

<p>他、要素の要所に <pre class="crayon-plain-tag">flex</pre> 属性が使われています。PolymerはCSSスタンダードのFlexboxを属性として使っており、この子要素に <pre class="crayon-plain-tag">layout horizontal | vertical</pre> が使われた時、この子要素が横または縦に、スクリーンにある分だけのスペースに引き伸ばされます。下の図を見てください。ヘッダUIのタイトル部分が引き伸ばされているため、右のアイコンと数字がきれいに右端に寄せて表示されています。</p>

<p><img src="/wp-content/uploads/2015/01/flex.png" alt="flex" width="495" height="155" class="aligncenter size-full wp-image-12355" srcset="/wp-content/uploads/2015/01/flex.png 495w, /wp-content/uploads/2015/01/flex-300x93.png 300w, /wp-content/uploads/2015/01/flex-207x64.png 207w" sizes="(max-width: 495px) 100vw, 495px" /></p>

<h3>1.4. 個々のUI Elementsを使う</h3>

<p>次に、このベースレイアウトの中に、先ほど一緒にインポートした個々のUIパーツを使います。 例えば次に示すコードサンプルでは、スクリーン横幅にあわせスタイライズされたインプットと、送信ボタンを表示しています。</p>

<p>二重カーリーブラケットに囲まれた <pre class="crayon-plain-tag">{{input}}</pre> 、 <pre class="crayon-plain-tag">{{sendMyMessage}}</pre>に注目してださい。これは式や <pre class="crayon-plain-tag">on-</pre>で始まるイベントハンドラとして使われます。次のチャプターで簡単に説明します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- メインコンテンツ --&gt;   
&lt;div class="send-message" layout horizontal&gt;
 &lt;paper-input flex label="Type message..." id="input" value="{{input}}"&gt;&lt;/paper-input&gt;
 &lt;paper-fab icon="send" id="sendButton" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt; 
&lt;/div&gt;</pre><p></p>

<p>実際のアプリの中でコンポーネントがどのようにインポートされているかは、GitHub Repo上の<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">lite.html</a>のソースコードを見て確認してみてください。</p>

<h3>1.5. データバインディング</h3>

<p>PolymerはHTMLの新スタンダードである <pre class="crayon-plain-tag">&lt;template&gt;</pre>を使って、宣言的で双方向のデータバインディングをサポートしています。 Polymerのデータバインディングにはいくつか方法があるのですが、ここでは <pre class="crayon-plain-tag">&lt;template&gt;</pre> でアプリの全コードを囲むことによって自動バインディングを可能にしています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;template is="auto-binding"&gt;
    &lt;core-scaffold&gt;
      ...
    &lt;/core-scaffold&gt;
  &lt;/template&gt;
&lt;/body&gt;</pre><p></p>

<p>これで、前チャプター(1.4)で既出の<pre class="crayon-plain-tag">paper-input</pre> の例にあるように、ユーザが入力する値を<pre class="crayon-plain-tag">{{input}}</pre>を使って得ることができます。</p>

<p></p><pre class="crayon-plain-tag">var template = document.querySelector('template[is=auto-binding]');
doSomething(template.input);</pre><p></p>

<p>他、このデータモデルを使えば、要素を繰り返し使うようなマークアップを簡略化するなどということもできるのです。 実際にドロウアーパネルUIの中に、<pre class="crayon-plain-tag">core-item</pre>を使ったリストを作成してみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;template repeat="{{item in items}}"&gt;
  &lt;core-item icon="{{item.icon}}" label="{{item.title}}"&gt;&lt;/core-item&gt;
&lt;/template&gt;</pre><p></p>

<p><pre class="crayon-plain-tag">core-item</pre>のコンテンツは、JavaScript側で、items配列を使ってオブジェクトで指定します。 ここでは、<pre class="crayon-plain-tag">&lt;core-icons&gt;</pre>で既に用意されている<a href="http://www.polymer-project.org/components/core-icons/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アイコンのセット</a>を使っています。</p>

<p></p><pre class="crayon-plain-tag">template.items = [
  {title: 'Uno', icon: 'cloud'},
  {title: 'Dos', icon: 'polymer'},
  {title: 'Tres', icon: 'favorite'}
];</pre><p></p>

<p>これで、モデルを生成・変更した時に自動的にテンプレートにインスタンスが生成され、DOM上には下の図のように表示されます。
<img src="/wp-content/uploads/2015/01/core-item.png" alt="core-item" width="257" height="186" class="aligncenter size-full wp-image-12351" srcset="/wp-content/uploads/2015/01/core-item.png 257w, /wp-content/uploads/2015/01/core-item-207x149.png 207w" sizes="(max-width: 257px) 100vw, 257px" /></p>

<h2>2. カスタム要素の作成</h2>

<p>メインUIとなる部分にチャットの会話を表示させましょう。このUIパーツには、アバター、ユーザーID、チャットのテキストが表示させるようにしたいのですが、Polymer CoreにもPaperにもそういったバーツは存在しません。ですので自分でカスタム要素を作ってみましょう。</p>

<p>まず新規のHTMLファイルを作成します。ここではこのファイル名を、<pre class="crayon-plain-tag">x-chat-list.html</pre>とします。</p>

<p>このカスタム要素は、属性、<pre class="crayon-plain-tag">avatar</pre>、<pre class="crayon-plain-tag">color</pre>、 <pre class="crayon-plain-tag">username</pre>、<pre class="crayon-plain-tag">text</pre>を扱います。</p>

<p><img src="/wp-content/uploads/2015/01/x-chat-list.png" alt="custom element" width="450" height="188" class="aligncenter size-full wp-image-12354" srcset="/wp-content/uploads/2015/01/x-chat-list.png 450w, /wp-content/uploads/2015/01/x-chat-list-300x125.png 300w, /wp-content/uploads/2015/01/x-chat-list-207x86.png 207w" sizes="(max-width: 450px) 100vw, 450px" /></p>

<p>ここでは、カスタム要素の作製法を一から説明はしませんが、簡略化されたカスタム要素は次のようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="x-chat-list" attributes="avatar color username text"&gt;
  &lt;template&gt;
  &lt;section class="user-list" layout horizontal&gt;
    &lt;div class="avatar {{color}}" style="background-image: url({{avatar}})"&gt;&lt;/div&gt;
    &lt;div flex&gt;
      &lt;div class="username"&gt;{{username}}&lt;/div&gt;
      &lt;div class="text"&gt;{{text}}&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer('x-chat-list', { // デフォルト値を指定
      avatar: '', 
      color: '',
      username: '',
      text: ''
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>この例ではわかりやすく見せるために、 <pre class="crayon-plain-tag">&lt;style&gt;...&lt;/style&gt;</pre>部分が省略されていますが実際にUIのカスタム要素を作るにはCSSは不可欠でしょう。CSSを含む全ソースコードの<pre class="crayon-plain-tag">x-chat-list.html</pre> は<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/x-chat-list.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub Repo</a>で見てください。</p>

<p>できあがったら<pre class="crayon-plain-tag">index.html</pre>に戻って、このカスタム要素をインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="x-chat-list.html"&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list color="{{message.color}}" 
                 avatar="{{message.avatar}}" 
                 username="{{message.uuid}}" 
                 text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>データは実際の生のチャットの会話を、PubNubデータ・ストリームサービスを使って表示させます。詳しくは次のセクションで説明します。</p>

<p>かなりはしょってしまいましたが、カスタム要素を作る詳しい説明は<a href="https://www.polymer-project.org/docs/start/tutorial/step-2.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">公式のドキュメント</a>を参照してください。</p>

<h2>3.PubNub Elementでメッセージの送信・受信をする</h2>

<p><img src="/wp-content/uploads/2015/01/pubnub-polymer.png" alt="pubnub-element" width="231" height="160" class="aligncenter size-full wp-image-12353" srcset="/wp-content/uploads/2015/01/pubnub-polymer.png 231w, /wp-content/uploads/2015/01/pubnub-polymer-207x143.png 207w" sizes="(max-width: 231px) 100vw, 231px" /></p>

<p>アプリのUI部分はすべて完成しましたので、今度はチャットルームそのものを作ってみましょう。データの送受信は<a href="http://pubnub.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNub</a>が提供するリアルタイム・データストリームのPolymerエレメント版である、 <pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre> を使います。 今まで使った要素と違うのはこの要素にはユーザインターフェイスが伴わないことです。では何をしてくれるのかというと、要素でカプセル化されたPubNub APIがクラウドでデータのpublish / subscribeのやりとりをはたしてくれるのです。なので私たちがサーバを立てる必要はありません。</p>

<p><pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre>はサードパーティAPIを使用しますので、まず自分のAPI keysを作成しておく必要があります。 <a href="http://www.pubnub.com/get-started/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNubアカウントはここから取得してください</a>。短時間試してみたいだけならば、<pre class="crayon-plain-tag">publish_key</pre>と<pre class="crayon-plain-tag">publish_key</pre>を<em>demo</em>にして使うこともできます。</p>

<h3>3.1. &lt;pubnub-element&gt;をインストール・インポート</h3>

<p>インストールは、他の要素同様にBowerを使うことができます。</p>

<p><pre class="crayon-plain-tag">$ bower install --save pubnub-polymer</pre></p>

<p>インストール後は<pre class="crayon-plain-tag">index.html</pre>でこれをインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/pubnub-polymer/pubnub-element.html"&gt;</pre><p></p>

<h3>3.2. &lt;pubnub-element&gt;を使う</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-pubnub&gt;</pre>を使ってクライアントの初期化をします。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="your_pub_key" subscribe_key="your_sub_key" uuid="{{uuid}}"&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>ここで使われる<pre class="crayon-plain-tag">uuid</pre>とはチャットルームの各ユーザのユニークIDで、ランダムな文字列を使います。このアプリでは、おのおののユーザがアクセスした時に、<em>navy-siamese</em>（濃紺色・シャム猫）のように、色と猫の種類の文字列の組み合わせで構成されたIDが与えられるようにします。</p>

<p></p><pre class="crayon-plain-tag">var randomColor = function() {   
  var colors = ['navy', 'slate', 'olive',...];   
  return colors[(Math.random() * colors.length) &gt;&gt;&gt; 0];
};

var randomCat = function() { ... }; 

template.uuid = randomColor() + '-' + randomCat();</pre><p></p>

<p><img src="/wp-content/uploads/2015/01/cats.png" alt="cat avatars" width="626" height="46" class="aligncenter size-full wp-image-12350" srcset="/wp-content/uploads/2015/01/cats.png 626w, /wp-content/uploads/2015/01/cats-300x22.png 300w, /wp-content/uploads/2015/01/cats-207x15.png 207w" sizes="(max-width: 626px) 100vw, 626px" /></p>

<h3>3.3. メッセージの送信</h3>

<p><pre class="crayon-plain-tag">&lt;core-pubnub-publish&gt;</pre>はチャンネルのサブスクライバー全てにメッセージを送信することができる要素です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="demo" subscribe_key="demo"&gt;
  &lt;core-pubnub-publish id="pub" channel="polymer-chat" message="Hello"&gt;
  &lt;/core-pubnub-publish&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>では、ユーザが文字を入力して送信ボタン( <pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre> )をタップした時に、そのメッセージをサーバに送るコードを書きましょう。 Polymerは、<pre class="crayon-plain-tag">on-*</pre>イベントハンドラを使うので、この場合 <pre class="crayon-plain-tag">on-tap</pre>イベントを用いて<pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre>がこのアクションを引き起こすことができるようにしてみます。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-fab icon="send" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">template.sendMyMessage = function(e) {
  if(!template.input) return; // 入力フィールドが空の場合は何もしない

  template.$.pub.message = {
    uuid: uuid, 
    avatar: avatarUrl,
    color: color, 
    text: template.input  
  };
  template.$.pub.publish();
};</pre><p></p>

<p>これでユーザの情報とメッセージテキストが、サーバに送られました。次はすべてのユーザがこれを受信して、内容ををDOMに表示させてみましょう。</p>

<h3>3.4. 受信データのリアルタイムバインディング</h3>

<p>ネットワークに送られたメッセージは <pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>要素を使ってクライアント側で受信することができます。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub-subscribe 
  channel="polymer-chat" 
  id="sub" 
  messages="{{messages}}" 
  on-callback="{{subscribeCallback}}"&gt;</pre><p></p>

<p>ここでの<pre class="crayon-plain-tag">messages</pre>属性は受信されたメッセージオブジェクトの配列が含まれています。ではここで受け取ったデータを先ほど作成した<pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>カスタム要素を使って表示させましょう。 実は先のチャプター２で、既に <pre class="crayon-plain-tag">messages</pre> 配列のインスタンスが使われていることに気がついたでしょうか？ <pre class="crayon-plain-tag">messages="{{messages}}"</pre> 属性が&lt; <pre class="crayon-plain-tag">core-pubnub-subscribe&gt;</pre> と <pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>の間で双方向バインディングがすでに行われているのです。なので、自動的にDOM生成を行ってチャットの内容を表示することができるのです！</p>

<p>ではもう一度、<pre class="crayon-plain-tag">&lt;x-chatlist&gt;</pre>を見てみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list 
      color="{{message.color}}" 
      avatar="{{message.avatar}}" 
      username="{{message.uuid}}" 
      text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>メッセージが受信された際には、<pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>のコールバック、<pre class="crayon-plain-tag">on-callback</pre>が発生します。 このチャットの配列は時間順に並べられているので、新しいメッセージはスクリーンの一番下に表示されることになります。これではユーザの使い勝手が悪いので、コールバック発生時に自動的に最新チャットまでスクロールさせることにしましょう。</p>

<p></p><pre class="crayon-plain-tag">template.subscribeCallback = function(e) {
  template.async(function(){
    var chatDiv = document.querySelector('.chat-list');
    chatDiv.scrollTop = chatDiv.scrollHeight; // scroll to bottom
  });
};</pre><p></p>

<p>これで、PolymerでMaterial Designの美しいデザインを使った簡単なチャットルームが完成しました！</p>

<p>このチュートリアルではわかりやすくするために、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">デモ</a>で使われているすべてのフィーチャーについてや、Shadow DOMのスタイリングについての説明は省略してあるので、さらに知りたい方は是非、<a href="https://github.com/pubnub/paper-chat" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub のRepo</a>で確認してみてください。</p>

<p>デモとチュートリアル、楽しんでいただけたなら幸いです！Happy coding!</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat.gif" alt="polymer pubnub chat app animated gif" width="280" height="280" class="aligncenter size-full wp-image-12364" /></p>
]]></content:encoded>
			</item>
		<item>
		<title>モバイルWeb開発に役立つ！Chrome DevToolsの新機能「デバイスモード」</title>
		<link>/girlie_mac/8384/</link>
		<pubDate>Mon, 28 Jul 2014 00:00:32 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Google I/O 2014]]></category>
		<category><![CDATA[クロスデバイス]]></category>

		<guid isPermaLink="false">/?p=8384</guid>
		<description><![CDATA[連載： Google I/O 2014 特集 (5)今回のGoogle I/OはAndroidに特化していた傾向が強く、WebテクノロジーやChromeの扱いが比較的小さかったせいもあり、多くのWebフロントエンドディベ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2014-2/" class="series-191" title="Google I/O 2014 特集" data-wpel-link="internal">Google I/O 2014 特集</a> (5)</div><p>今回のGoogle I/OはAndroidに特化していた傾向が強く、WebテクノロジーやChromeの扱いが比較的小さかったせいもあり、多くのWebフロントエンドディベロッパーは不満を感じた部分もありました。<br>
そこでその中の数少ないChromeのセッションの中から、私が興味深く感じたクロスデバイス開発にはこの先欠かせなくなると思われる Chrome DevToolsの新機能についてレポートします。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="640" height="360" src="//www.youtube.com/embed/t1PxmN_QNFI" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>


<p>このセッションを行ったPaul Bakaus氏（以下、ポール氏）は、かつてjQuery UIやAvesゲームエンジンを開発したことでも知られています。一時期日本に在住していたこともあるので、この記事を読んでいる皆さんには既になじみのある方かもしれません。現在はGoogle Chromeチームの一員であるポール氏。<br>
今回この&#8221;Developing across Devices &#8211; DevTools in 2014&#8243;と題されたセッションでは、Chrome DevToolsの新機能と3つのワークフローについて、当日あったワールドカップのアメリカ対ドイツ（氏はドイツ人）戦のジョークをを交えつつ、とても面白く説明してくれました。</p>

<h2>コンテントは水のごとし</h2>

<p>「今の時代、モバイルWebを制する者がWebを制する！」と断言するポール氏。「Webコンテントは水のようにフローし（流れ）、どんなフォームファクター上でもフロー（描写）せねばならない」と、そのためのワークフローで重要な「Design」「Develop」「Iterate」の3つを挙げました。</p>

<p>Design（デザイン）は、はじめの重要な一歩。複数のフォームファクターを考えながらデザインをせねばなりません。</p>

<p>私たちディベロッパーは、マルチデバイス開発のためにブラウザのウィンドウの大きさを変えたりながらも、レスポンシブなWebを作り上げるのに大変な労力を費やしています。</p>

<p>この労力を軽減するためにChromeチームが開発し、そしてこの日初めて発表されたのがDevToolsのDevice Mode。現在 Chrome Canary(v38)のみに実装されているこのデバイスモードには、Nexus 5やSamsung Galaxyシリーズなどに多く使われているデバイスのプリセットが付属されます。そのため、各種のスクリーン解像度や高DPIスクリーンなどのエミュレーションが、今までよりも断然楽に行われるようになります。</p>

<h2>デバイスモード</h2>

<p>実際にこのデバイスモードを使ってみましょう。<br>
まず、インスペクターウィンドウを開き、デバイスアイコンをクリックします。するとWebページの表示がデバイスモードに切り替わります。ここでは表示の幅を自由に変えられるほか、プリセットからデバイスを選択して、自動的にその解像度に合わせたサイズにすることもできます。オリエンテーションの変更も簡単に行えます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/11/devtools-device-mode-1.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2015/11/devtools-device-mode-1.gif" alt="devtools-device-mode-1" width="640" height="434" class="aligncenter size-full wp-image-17798" /></a></p>

<p>そしてそのレスポンシブなデザインを実装する、フローその2はDevelop。</p>

<p>実際のデモで私たちオーディエンスをあっと言わせた、このMedia-queriesツールを使えば、メディアクエリのワークフローも今までよりさらに効果的に行えそうです。Device Modeの左端のMedia-queriesボタンをクリックすると、使用されているメディアクエリがルーラー上に表示され、さらにそれらを右クリックするとドロップダウンメニューにこのソースコードのパスが表示されます。これを選択するとSourceパネルにコードが表示されます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/11/devtools-device-mode-2.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2015/11/devtools-device-mode-2.gif" alt="devtools-device-mode-2" width="640" height="431" class="aligncenter size-full wp-image-17799" /></a></p>

<p>そしてさらに新しい機能のWorkspaceを使えば、ここで変更されたメディアクエリをローカルのファイルシステムに直接反映させることもできます。</p>

<p>その他のエミュレーション機能として、タッチイベント、アクセラメーターなどのセンサーなどもエミュレーションすることができます。</p>

<h2>ネットワーク環境のエミュレーション</h2>

<p>一言でWifiコネクションといっても、会社のWifiのように快適だったり、カンファレンスのWifiのように人が多すぎて全く役に立たなかったりもすることもあります。例えば同じ高速道路でも、ドイツの速度無制限のアウトバーンとアメリカの制限速度55マイルのハイウェイを走るのとでは体感が全然違う、とポール氏は面白おかしく述べています。</p>

<p>そのような遅い回線コネクションをエミュレートすることは、特にモバイル開発では欠かせないものです。そこで DevToolsの新機能のコネクティビティエミュレータでは、3G回線での接続やオフライン状態といった様々な通信環境をエミュレートすることができます。例えば、モバイルのEDGE回線で開発中のWebがどうレンダリングされるか、そしてそのレンダリングがいかにユーザーをイライラさせるものかを、目で知ることができるのです。そういったユーザー・エンクペリエンスをテストするのは非常に大事なのです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/11/devtools-device-mode-3.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2015/11/devtools-device-mode-3.gif" alt="devtools-device-mode-3" width="640" height="433" class="aligncenter size-full wp-image-17800" /></a></p>

<h2>スクリーンキャストでリモートデバッグ</h2>

<p>ワークフローの3つ目はIterate。エミュレーターは便利ではあるけれど、やはり実際のデバイスでテストしてみないことには分からない事実はいくつかあります。このプロセスで重要なのはこの3つ。</p>

<ul>
    <li>パフォーマンス・プロファイリング</li>
    <li>各デバイスに特化したバグや欠陥</li>
    <li>コンテクスト（外観と操作感）</li>
</ul>

<p>このテストを快適に行うために、DevToolsのリモートデバッグを使いましょう。</p>

<p>その前に、まずChrome Canaryを最新バージョン（7月22日以降のビルド、38.0.2101.0もしくはそれより新しいもの）にアップデートしてください。それからchrome://flags/#enable-devtools-experimentsを&#8221;enable&#8221;にします。そして、DevToolsのSettings（ギアアイコンをクリック）&gt; Experimentsからこの機能をオンにします。</p>

<p>AndroidデバイスのUSB Debugモードもオンにします。</p>

<p>そのデバイスをコンピューターにUSBでつなぐと、デバイスモードアイコンとは別にもう一つ小さなデバイスに「1」の数字がついたアイコンが表示されます。この数字はつながれているデバイスの数を示します。このアイコンをクリックすると、さらにデバイスパネルが下にあらわれます。</p>

<p><img src="/wp-content/uploads/2014/07/devtools-device-mode-screencast.jpg" alt="devtools-device-mode-screencast" width="800" height="521" class="aligncenter size-full wp-image-8968" srcset="/wp-content/uploads/2014/07/devtools-device-mode-screencast.jpg 640w, /wp-content/uploads/2014/07/devtools-device-mode-screencast-300x195.jpg 300w, /wp-content/uploads/2014/07/devtools-device-mode-screencast-207x134.jpg 207w" sizes="(max-width: 800px) 100vw, 800px" /></p>

<p>さらに、このパネルでTry Hereと表示されたボタンをクリックすると、実際のデバイス上のChromeの画面がChrome上にスクリーンキャストされるのです。デバイスで操作してみてください。動きがデスクトップブラウザのDevTools上に反映されるのがわかると思います。その逆も可能です。</p>

<p>これらのデバイス上での描写やレイヤーなどがDevTools上で可視化され、今までデスクトップで使っていたおなじみの機能をデバイスでも同じように使ってプロファイリングやデバッグすることが可能になります。</p>

<p>例えばこの3Dレンダリング。Layersパネルでレンダリングがレイヤーごとに可視化され、各レイヤーの様子も、レンダーオブジェクトをドラッグしながら360度各方向から見ることができます。さらにモバイルにありがちな描写の問題も、現在開発段階の新機能ペイントプロファイラを使ってピンポイントでどの描写に時間がかかっているとか、border-radius部分が極端に遅いなどとプロファイリングすることができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/11/devtools-device-mode-screencast.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2015/11/devtools-device-mode-screencast.gif" alt="devtools-device-mode-screencast" width="640" height="425" class="aligncenter size-full wp-image-17797" /></a></p>

<p>既存のProfilesパネルでavaScriptのCPUプロファイルを行ったり、Timelineパネルでグラフ化された描写速度を観察したりすることも、これまで通りモバイル上でも行えます。さらに、これらを同時にTimelineパネルで使えるようにするなど実験的に新機能も追加されるようです。これで視覚的にもさらに使い勝手のよいものになりそうです。</p>

<h2>まとめ</h2>

<p>これらのワークフローと、デバイスモードの機能のまとめを箇条書きにしてみます。</p>

<p>Design = Responsive Layouts 機能</p>

<ul>
<li>メディアクエリ・ビジュアルツール</li>
<li>メディアクエリ編集ツール</li>
<li>スタイル・フィルタリングツール</li>
<li>インライン・エミュレーション</li>
</ul>

<p>Develop = Rich Emulation 機能</p>

<ul>
<li>デバイス・プリセット</li>
<li>ビューポート・エミュレーション</li>
<li>センサー・エミュレーション</li>
<li>ネットワーク・スロットリング</li>
</ul>

<p>Iterate = Remote Debugging 機能</p>

<ul>
<li>プラグアンドプレイ</li>
<li>パワーアップした既存の機能</li>
<li>スクリーンキャスト</li>
<li>ポートフォワード</li>
</ul>

<p>最後に。この記事を書くにあたって私からの質問やバグについて答えてくれた、よき友人でもあるポール氏に感謝！ドイツのワールドカップ優勝おめでとう。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2014 特集]]></series:name>
	</item>
		<item>
		<title>HTML5で実現できる！環境光に合わせたレスポンシブなUI</title>
		<link>/girlie_mac/4558/</link>
		<pubDate>Wed, 22 Jan 2014 01:00:45 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[デザイン]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[W3C仕様]]></category>
		<category><![CDATA[ブラウザ]]></category>
		<category><![CDATA[モバイル]]></category>

		<guid isPermaLink="false">/?p=4558</guid>
		<description><![CDATA[フロントエンド開発やデザインに携っている皆さんにとって、ここ数年間「レスポンシブ・ウェブ」についての話題は避けて通れないものとなっているでしょう。モバイルやタブレット上でも、ユーザー・エクスペリエンスを失うことのないウェ...]]></description>
				<content:encoded><![CDATA[<p>フロントエンド開発やデザインに携っている皆さんにとって、ここ数年間「レスポンシブ・ウェブ」についての話題は避けて通れないものとなっているでしょう。モバイルやタブレット上でも、ユーザー・エクスペリエンスを失うことのないウェブを表現するには、CSS3 Media-queriesが欠かせないものとなってきました。</p>

<p>それでは実際、レスポンシブ・ウェブとは何についての対応（レスポンシブ）なのでしょうか。</p>

<p>現在のところ、私たちがいうレスポンシブ・ウェブデザインとは、どんなスクリーンの幅や表示領域、デバイスの画面解像度や画面の縦横の向きにも対応したウェブデザイン、というのが事実上の定義となっているようです。</p>

<p>そこで今回、私はその定義を超えたレスポンシブ・ウェブのユースケースについて考えてみました。</p>

<h2>太陽光下でのスクリーン・リーダビリティ</h2>

<p>私は普段の仕事ではNokia Lumiaというスマートフォンを使っているのですが、これがなかなかの優れもの。環境光センサーでスクリーンの輝度値を自動調整してくれるので、晴天の空の下でもスクリーンのコンテンツがはっきり読めるのです。ところが私の個人用で使ってる別機種の場合、そうもいきません。例えば読みたいウェブがたとえ「レスポンシブ」であれ「モバイル・ファースト」であれ、まぶしいカリフォルニアの空の下では、全くコンテンツが見えないので使い物にならないのです。</p>

<p>一方、W3CのCSSメーリングリストでは、次世代の<a href="http://dev.w3.org/csswg/mediaqueries4/#luminosity" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">CSS Media Queries 4</a>のひとつである<pre class="crayon-plain-tag">luminosity</pre>メディア・フィーチャーについて討議されています。<br>
ということは、もしこのスペックがブラウザに実装されることになれば、まさに環境光に反応するレスポンシブなウェブが作れることに！</p>

<p>しかしこれが実現するのは一体いつの日になることやら…</p>

<h2>Ambient Light Events API</h2>

<p>というわけで、今現在のブラウザでは、CSSを使って環境光の度合いに合わせてウェブのUIを調整するのは不可能。</p>

<p>しかし私たちには、HTML5を使ってブラウザから各種センサーやカメラなどのハードウェアが持つ機能にアクセスするための仕様、<a href="http://www.w3.org/2009/dap/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">デバイス API</a>のひとつである<a href="http://www.w3.org/TR/ambient-light/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Ambient Light Events</a>があるでないですか！<br>
これならJavaScriptを使って環境光センサーから照度を知ることができるはず。これを使えば、次世代メディアクエリをまねて、太陽や照明にレスポンシブなウェブが作れるかもしれない！<br>
そう思って私は、実験的に簡単なデモを書いてみました。</p>

<h2>Devicelight events</h2>

<p>デバイスのセンサーが照度の変化に反応すると、ブラウザ側では<pre class="crayon-plain-tag">DeviceLightEvent</pre>イベントが発生します。このとき、イベントハンドラのイベントタイプである<pre class="crayon-plain-tag">devicelight</pre>を使えば、コールバック関数の引数からイベントオブジェクトが得られます。</p>

<p>そこで得られるプロパティの値、<pre class="crayon-plain-tag">value</pre>  は照度をluxの単位で返されます。</p>

<p>実際、大変簡単にこう書くことができます。</p>

<p></p><pre class="crayon-plain-tag">window.addEventListener('devicelight', function(event) {
  console.log(event.value + 'lux');
});</pre><p></p>

<h2>照度にレスポンシブなウェブを作ってみる</h2>

<p>これを使って、環境光が変わってもウェブの内容を読みやすくするためのUIを考えてみました。</p>

<p>デフォルトではライトグレーの背景に黒の文字、明るい照度の時には白地に黒の文字、そして暗い時には暗めな背景に白の文字、というUIにしてみましょう。</p>

<p>例のAPIを使って、照度によってコンテンツのコンテイナー（このデモではわかりやすいように<pre class="crayon-plain-tag">document.body</pre>を使っています）のクラス名を変え、CSSで文字色などのビジュアルを定義します。</p>

<p></p><pre class="crayon-plain-tag">window.addEventListener('devicelight', function(e) {
  var lux = e.value;

  if(lux &lt; 50) {
    document.body.className = 'dim';
  }
  if(lux &gt;= 50 &amp;&amp; lux &lt;= 1000) {
    document.body.className = 'normal';
  }
  if(lux &gt; 1000)  {
    document.body.className = 'bright';
  } 
});</pre><p></p>

<p></p><pre class="crayon-plain-tag">body,
body.normal {
  background-color: #ddd;
  color: #111;
}
body.dim {
  background-color: #444;
  color: #fff;
}
body.bright {
  background-color: #fff;
  color: #333;
}</pre><p></p>

<p>実際に、このデモが動いている様子がわかる動画を作ってみました。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe src="//player.vimeo.com/video/79466285" width="500" height="279" 0="webkitallowfullscreen" 1="mozallowfullscreen" 2="allowfullscreen" scrolling="yes" class="iframe-class" frameborder="0"></iframe>


<p><br></p>

<h2>ブラウザサポートとデバイス</h2>

<p>このデモで使われた実際のソースコードは、<a href="http://codepen.io/girliemac/pen/pvmBs" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">CodePen</a>を見てください。</p>

<p>ほとんどの方の観覧しているブラウザ上では <em>&#8220;AmbientLightEvent is not supported.&#8221;</em> というメッセージが出ていて何も起こらないのではないでしょうか。というのも、残念ながら今のところ、このAPIをサポートしているのは<a href="https://developer.mozilla.org/en-US/docs/Web/API/DeviceLightEvent" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Firefox 22+</a> だけ、しかもデバイス側にも環境光センサーが必要。<br>
ですので、デスクトップから見ている皆さんには、どのブラウザを使っていてもこのデモは作動していないでしょう。私のデモで実際に使ったデバイスはNexus 7ですので、AndroidやFirefoxOSのデバイス持っている方は、ぜひFirefoxで試してみてください。</p>

<p>イベントが返す値も、デバイスによってばらつきがあるようです。私が実験した機種2機ではずいぶん違う結果が出ました。たぶんセンサーの精度にブレがあるのでしょう。</p>

<p><img src="/wp-content/uploads/2014/01/luminosity-devices.jpg" alt="luminosity-devices" width="600" height="354" class="aligncenter size-full wp-image-4561" srcset="/wp-content/uploads/2014/01/luminosity-devices.jpg 600w, /wp-content/uploads/2014/01/luminosity-devices-300x177.jpg 300w, /wp-content/uploads/2014/01/luminosity-devices-207x122.jpg 207w" sizes="(max-width: 600px) 100vw, 600px" /></p>

<p>この写真にあるデバイスは、Moto G(Android)と、Keon(FirefoxOS)です。暗めの部屋での照度が、一方が6lux、もう一方が61luxとなっています。</p>

<h2>CSS Media Queries Level 4 Luminosity</h2>

<p>さて、話題をメディアクエリに戻します。<br>
今現在の<a href="http://dev.w3.org/csswg/mediaqueries4/#luminosity" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">仕様</a>では、メディアクエリ・レベル4はまだeditor&#8217;s draftの段階なので、ブラウザに実装されるまでにはまだまだ時間がかかりそうです。</p>

<p>将来的に実装された際には、このデモで書かれたコードはCSSのみでこのように書き直すことができるようになります。</p>

<p></p><pre class="crayon-plain-tag">@media screen and (luminosity: normal) {
  body {background-color: #ddd; color: #111;}
}
@media screen and (luminosity: dim) {
  body {background-color: #444; color: #fff;}
}
@media screen and (luminosity: washed) {
  body {background-color: #fff; color: #333;}
}</pre><p></p>

<p>このように、<pre class="crayon-plain-tag">luminosity</pre>メディア・フィーチャーを使えば簡単に書くことができます。CSS3メディアクエリに既になじみのある皆さんなら、かなり直感的でわかりやすいことかと思います。</p>

<h2>おわりに</h2>

<p>近い将来、レスポンシブ・ウェブの定義も、デバイスなどの多様性に合わせて変わってくるのではないでしょうか。このユースケースも実際果たして本当に役に立つのかどうかもまだわかりませんが、発想の転換とブラウザの新しい可能性、という面でこの記事を楽しんでいただけたかと思います。</p>

<p>この記事は元々は私個人の<a href="http://girliemac.com/blog/2014/01/12/luminosity/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ブログ</a>（原文は英語）に掲載したのですが、TwitterやReddit、Hacker Newsで思いのほか話題になりました。やはりディベロッパ、デザイナは国境を問わず、みな新しい可能性に興味津々なのでしょう。</p>

<p>では。</p>
]]></content:encoded>
			</item>
	</channel>
</rss>
