HTML5の基礎と応用 ~Open Web Platform~

Preview:

DESCRIPTION

簡易版はこちら => http://www.slideshare.net/You_Kinjoh/html5-websocket-webrtc-web-audio-api-webgl

Citation preview

HTML5の基礎と応用~Open Web Platform~

2013/11/11

金城 雄

NTTアドバンステクノロジ情報機器テクノロジセンタ所属

http://www.ntt-at.co.jp/

この資料は、先のスライドを見られない事を前提に書かれています。発表内容も同様です。できれば、このままそっと閉じて下さい。もちろん、文字が小さい・画面が見えない等であれば見て頂いて構いません。

この資料を手元に持っている人へNO

TICE

NOTICE

内容

HTML5の概要休憩HTML5のAPI 2つ (デモ込み)時間があれば休憩HTML5のAPI 2つ (デモ込み)HTML5のAPIの組み合わせ (デモ込み)

機能一覧が何度か

出てきますが全ての機能を

網羅していません。新しい仕様が今も増え続けています。

CAUTION

CAUTION

HTML5前史

所属会社や所属部署・業務

全て忘れて下さい。

CAUTION

CAUTION

注意

HTML5のインパクトを理解するために

しばらくお付き合い下さい。

かなりの量になりますがこれでも相当絞りました。

細部に間違いが

含まれている可能性があります。

他分野のイノベーションを大局的に振り返る。

20世紀後半

荷役・湾岸労働者

古くは沖仲仕(おきなかし/おきなかせ)と言っていましたが、現在では差別用語として扱われるそうです。

イノベーション

コンテナリゼーション

積み替えが容易に積み替えが迅速に梱包コストの削減積み重ねが容易

荷抜き・盗難が困難に

統一規格

インターモーダル輸送複合一貫輸送

コンテナリゼーションは多くの荷役の職を奪った。

坑夫

電話交換手

http://www.flickr.com/photos/24256351@N04/2680257100/in/photolist-55R24j-57gjm3-5fp9zV-5g8iNR-5jYcKK-5Hte1R-65Mqqi-68MrFn-6RT2ZZ-6Thg79-7mmujZ-7nkBSM-9uNQfa-9uRS6E-c6dR8j-9uNU5t-9zxT76-9yMWGo-fhqNsN-ad3ak2-frFrqi-fsBVc3-8V9DoA-cWLv4G-a1Pcua-8zCatd-djKVDF-9uMwMX-dX8YR4-cwbDVu-7Unejv-7UcBqs-89vVUr-9dYPWE-a9Z1v5-a8Z9yK-a9WcZv-9djc1S-9dJZ9n-8c6WdX-aqT2Hn-8XMCsQ-9d3LHi-bibXap-b3Kbup-abavwf-abavKw-cWLjQ9-f12PUU-dwNpHJ-8mppYJ

イノベーションは既存の仕組みを

破壊することがある

繰り返される歴史

近年では?

例えばコンパクトカセット

(カセットテープ)

イノベーション

コンパクトディスク

ITが破壊したもの

例えば写真フィルム

イノベーション

デジタルカメラ

富士フィルム事業縮小現在は、液晶フィルム・医療機器・化粧品等

コニカ 現:コニカミノルタDPE部門と共に譲渡現在は、複合機・カメラ・計測機器・医療機器等

コダック破綻

アグファカメラ事業から撤退現在は、医療機器・印刷機器・製版・印刷材料等

携帯電話

破壊的イノベーション

最初期から真っ当に

評価されていたか

世界で最初のデジタルカメラ

解像度は100 x 100白黒

カセットテープに記録

QV-10

デジタルカメラの普及の切っ掛けを

作った。

解像度は320 x 240ストロボなしピント固定

2MBの内蔵メモリに96枚バッテリが保たない(単3電池4本が96枚保たない)

『本日、Appleが電話を

再発明します』

2G/2.5G(GSM/GPRS/EDGE)

Appsがinstall不可Copy&Pasteが不可Flashをサポートなしバッテリの交換が不可

発表時のドコモはFOMA(3G)の903iシリーズ。発売時は904iシリーズ。

既存技術と比べると当初は

低機能に見える。

本質を理解しなくては予想を誤る。

業界が成立するには

ある種の制限が業界の成立に

大きく寄与していることが多い。

物理的制約社会的制約初期投資専門性

資格法律

比較的特殊な事例

とある業界内の問題を解決。業界の発展に貢献。

とある業界が成り立つための制限を解決する。業界存続の危機。

イノベーション

DTMの製作現場への寄与。CD化による市場拡大。

後にCDという物理的制約がITにより取り払われた。

音楽業界

技術が、制限を取り除くのではなく、特定の業界を守る目的で

制限を作るために用いられた比較的珍しい事例。

著作権保護技術(DRM)

セキュリティ技術は用途が違うため、珍しい事例には含みません。

ネットオークションに出品する一般消費者と競争することになった。

リサイクルショップ

昔は山の向こうは別の市場。交通網の発達は

物理的制約の緩和。市場は吸収されるか

結合する。

流通

市町村変遷パラパラ地図より島嶼部と地図外文字を削除して引用http://mujina.sakura.ne.jp/history/交通網以外の理由もあります。傾向としてみて下さい。

2001年01月21日

1889年05月01日

特別なことではない。これまでの延長上の事象。但し、交通網だけでなく通信網も制限緩和に関与。

グローバル化

言葉の壁はまだありますが...。

水平統合と

垂直統合

水平統合され主戦場が

ひとつ上のレイヤーに移動すると

その分野の勢力図を一旦リセットすることがある。

Windows登場以前と登場以後とでは

市場のプレイヤーが大きく違う。

レイヤーが変わると群雄割拠に。

市場は混沌とするがやがてプレイヤーは淘汰されていく。

既存企業は参加するかどうかの選択が迫られる。新レイヤーは

主戦場となるのか。コモディティ化しないか。

革新により制限が取り払われた場合。ビジネスのルールが変わる。

それまでの常識が通用しないことも。

ひとつの経済圏・分野のプレイヤー数

淘汰後は3~10前後 or 1

市場は健全である事が多い。囲い込みで垂直統合を計るが上手くいかないことが多い。不便さは上のレイヤーの水平統合の遠因にも。

3~10前後

ポイントカード他企業も真似するのですぐに横並びに。

電話料金価格競争からLCRにレイヤーが変化。

その後、マイライン・IP電話...

プロプライエタリなら独占。独占した上のレイヤーも圧勝することが多い。(ソフトウェア分野は特に。)

発展の速度が遅くなる。思わぬ所から独占が崩れる。

1

IBM互換機 (PC/AT互換機)ハードからソフトへの主戦場の変化を見誤る。

PC-98国内独占。Windowsの来襲による没落。

Windows上位のオフィススイートとブラウザも独占。

別カテゴリのOS台頭と上位レイヤーの標準化で...。

まずない。A < B + C である限り

どこかがキャスティングボードを

握る。

2は?

ネットワーク効果ネットワーク効果とは、同じ製品・サービスを利用するユーザが増えると、それ自体の効用や価値が高まる効果のこと。ネットワーク外部性・バンドワゴン効果

ロックイン効果ロックイン効果とは、顧客(ユーザ)がある商品を購入すると、その商品から他社の製品への乗り換えが困難となり、顧客との継続的関係が維持されやすくなる効果。http://www.exbuzzwords.com/static/keyword_3631.html

http://www.exbuzzwords.com/static/keyword_3632.html

人為的なロックオン効果。IT業界的には

ベンダーロックとも。同時にネットワーク効果を

狙う事も。

囲い込み戦略

業界を破壊する革新が存在する。革新は最初は低機能に見える。革新は業界の発展に寄与。業界に必要な制限を解決することも。革新が起こった業界ではなく他業界を破壊する事も。

ここまでのまとめ1

革新は市場を統合することがある。グローバル化もその一貫でしかない。水平統合と垂直統合は繰り返されている。水平統合されると群雄割拠。やがて収束し垂直統合。既存企業も否応なく巻き込まれる。

ここまでのまとめ2

ここまでの参考資料と

没にしたスライドの一部

http://amazon.jp/dp/4822245640

コンテナ物語世界を変えたのは「箱」の発明だった

http://amazon.jp/dp/4798100234http://www.seshop.com/product/detail/2241

イノベーションのジレンマ技術革新が巨大企業を滅ぼすとき

http://amazon.jp/dp/4062810530

父の子供時代には、会社の寿命は60年といわれていた。ところが1970年代に入ると会社の寿命は30年になり、現在では15年になってしまっている。これが2010年には10年にまで短命化するらしい。ピーター・ドラッカーによれば、このように会社や事業の寿命が個人の労働可能寿命よりも短くなることは歴史上はじめてのことである。これまではひとつの仕事、たとえば印刷工になれば一生そのスキルひとつで食っていけた。しかし今では、スキルを身につけても、まだ働けるのに会社のほうが先に寿命がきてしまう。それは一生の間に、いくつもの異なる分野で異なる能力を発揮しなければならないという、まったく新しい時代に生まれたことを意味する。

米デューク大教授のキャシー・デビッドソン(63)によると、いま、小学校に入る子供の65%は現在まだない職業に就くという。

日本経済新聞 2013/01/28

http://www.w3.org/html/logo/

狭義のHTML5と

広義のHTML5

HTML5 = HTML5 + CSS + JS

HTML5 = HTML5 + CSS + JS

広義

狭義

HTML5 = HTML5 + CSS + JS

広義

狭義 マークアップ言語の仕様従来のHTMLの改訂

新しいAPIも含まれるバズワード(マーケティング用語)

SemanticElements

MultiMedia

Canvas

HTML5Forms

OfflineSupport

Webm

H.264

Micro-Data

WebGL

WebSQL

IndexedDB

SVG

Server-Sent ev.

WebSockets

WebSockets

Geo-location

FileAPI

WebStorage

XHR2

MathML

WebAudio

LayoutMedia

Queries

HTML5

CSS3~Transform

Animation Regions

FlexBox

HTML5Parser

Mouse,Key ev.

Opus

ECMAScript ECMA

6th

USB

CSP

SPDY

WebCL

WebRTC

NetInfo

MP3

DeviceStorage

TCPSocket

NFC

File Sys

Notifi-cation

XHTML5

Orien-tation

WebWorkers

WebMessag-

ing

DOM4

SMIL Vibra-tion

Proxi-mity

XPathRSS

RDF

OGPSchema

.org

WAI-ARIA

W3C

WHATWG

other

Khronos

ECMA

IETF

WOFF

BatteryStatus

Radio

Tel

HTML

DNT

http://www.slideshare.net/dynamis/toward-firefox-os/26 より引用

http://www.slideshare.net/dynamis/toward-firefox-os/22 より引用

SemanticElements

MultiMedia

HTML5Forms

OfflineSupportHTML5HTML5

Parser

Mouse,Key ev.

XHTML5WAI-ARIA

W3C

HTML5 = HTML5 + CSS + JS

本日のコンテキスト

これ

HTML5 = HTML5 + CSS + JS

本日のコンテキスト

これ

最近ではバズワードを避けて、一部の人は

Open Web Platformと呼んでいる。

で、HTML5で何ができるように

なるの?

できることはこれまでと変わらない

これまでブラウザで

できなかったことができるようになる

だけ

元々はWeb Pageを閲覧するためのものだった

ブラウザで、Web Applicationを実行できるようにするために、

必要なものを追加

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

Typed Arraysブラウザ上でバイナリデータを操作できるようにしたよ

今まで出来なかったことがおかしい

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

Web Audio APIブラウザ上で音声データを操作・再生できるようにしたよ

今まで出来なかったことがおかしい

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

Web Workersバッググランドで処理ができるようになったよ

今まで出来なかったことがおかしい

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

CSS3画像を使わなくても、角丸・グラデーション使えるよ

今まで出来なかったことがおかしい

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

SVGベクターデータが使えるようになったよ

今まで出来なかったことがおかしい

( ・`ω・´)ドヤァ

('・ω・` ) ('・ω・` )

(広義の)HTML5

色々できるようになったよ

でも、まだまだ全然機能足りてないじゃん!

機能一覧だけ見ていると

本質を見失う。

機能一覧には現れない

HTML5の特徴

HTML5

OSの機能がブラウザ上で使える低レイヤーのAPIがWeb APIで共通化特許に制限されない誰もが利用可能Webプラットフォーム上で統合

OSの機能がブラウザ上でOSの機能が、ブラウザを介してサイトに提供されるアドレス帳 ネットワーク情報 バッテリー状態 通知ストリーム メディアデータ オーディオ ビデオ 字幕

Webカメラ マイク Audioの波形操作2D(ラスター,ベクター) 3DCG 音声入力 音声合成暗号化 ファイルシステム データベース スレッド通信(WebSocket,TCP,UDP) Bluetooth

加速度センサ 傾きセンサ ジャイロ バイブレーションGPS 電子コンパス 温度センサ 湿度センサ 気圧センサ

環境光センサ 近接センサ 磁気センサ etc.ネット接続が前提のもの・仕様策定中のもの・WebOS向けのものも含まれています。

Web APIで共通化

低レイヤーのAPIがWeb APIで共通化されるOSに非依存実行環境に基本的に非依存環境による制限はありえる

センサ未搭載・端末性能等の理由や用途による理由(例:電子書籍)等が制限として考えられます。

特許に制限されない

Openであることが特徴パテント・フリーロイヤリティ・フリー

いわゆる業界団体よりもオープン仕様だけでなく策定過程も公開

特定の組織の利益よりも人類の利益を市場原理に左右される側面もあり。理想と現実は違う...。

誰もが利用可能世界中の誰もが利用可能な機能限られた組織の限られた人しか使えない仕様はオープンではない

今も100年後も自由に使える「古文書の一部が、DRMで保護されていて見られない」のない未来に(電子書籍の仕様にも関連しているため)

DRMについての議論が始まったそうです。

Web P/F上で統合

これら全てが、OpenWebプラットフォーム上で統合アイディア次第で新しい物が誰にでも日曜プログラミングで音声合成夏休みの宿題でビデオチャット作成

これらの知見はWeb上に蓄積

HTML5そのもののインパクト

ポテンシャルを最大限に発揮した場合を考察

充分成りうる。適度に抽象化されたAPI。新興企業にとって魅力的。既存企業も移らざるを得ない可能性。機能面だけ見れば既存企業にとっても、得意領域以外の機能が簡単に使える魅力。

新しいレイヤーと成りうるか

多大。これまでの常識、コンパイルが前提で実行ファイルを売買が通用しない。これまでも、スクリプト言語もあったがサーバサイド。今後、コードのオープンが前提になる。コンテンツ保護の議論、コードにはない。コーデック等の特許も組み込めない。

IT業界への影響は?

多分多大。破壊的イノベーションになる可能性。既にITに巻き込まれているなら尚更。

他業界への影響は?

他業界との距離が接近する可能性。IT系でも棲み分けが出来ていた他分野とも距離が接近。敷居が下がることで一般の人の参入も。

プレイヤー

今後も国境を越えた競争。言葉の壁は有り得る。英語圏でシェアを取られると、ネットワーク効果で太刀打ちできなくなる。これまで言語の壁で守られていたが、今度はそれが仇に成りうる。

コードが見られるため、サービスのクローンが容易。速く市場にリリースし、市場を握る事がこれまで以上に重要に。技術力よりもアイディア勝負。(もちろん技術力も大事だが...)

開発スタイル

IT史上最大の水平統合オープンなレイヤー

Open Web Platform

http://platform.html5.org/ より引用 (2013/04/04 版)

http://platform.html5.org/ より引用 (2013/04/04 版)

インパクトの強そうな仕様の一部

WebSocketWebRTCWeb Audio APIWebGL

休憩

インパクトの強そうな仕様の一部

WebSocketWebRTCWeb Audio APIWebGL

WebSocket

WebSocket

高速・双方向通信2つの仕様WebSocket ProtocolWebSocket API

Cometよりも低負荷 <- 今回は詳細にはふれません

DEMO

何故双方向通信が可能か

サーバ側から情報を送るにはrequest/responseでないと届きにくい

Client Serverrequest

response

FireWallNATProxy

access

access×

何故双方向通信が可能か

HTTPでWebSocketのハンドシェイクを行なう

Client Server

request

response

GET / HTTP/1.1Upgrade: websocketConnection: Upgrade(略)

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: Upgrade(略)

handshake

厳密にはHTTPと完全互換ではありません。

何故双方向通信が可能か

ハンドシェイク後、双方向通信が可能となる

Client Server

request

responsehandshake

SwitchingProtocols

何故双方向通信が可能か

切断しない限り、双方向通信が可能

Client Server

request

responsehandshake

何故双方向通信が可能か

HTTPを模しているため通過しやすいが100%ではない

HTTP (port 80) 67% HTTP (port 61985) 86% HTTPS (port 443) 95%

http://www.ietf.org/mail-archive/web/tls/current/msg05593.html

何故高速通信が可能かあるHTTP requestのHeaderGET / HTTP/1.1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip,deflate,sdchAccept-Language: ja,en-US;q=0.8,en;q=0.6Cache-Control: max-age=0Connection: keep-aliveHost: localhostIf-Modified-Since: Tue, 08 Oct 2013 17:46:38 GMTIf-None-Match: "3e031b2-13a1-4e83e59bcbb80"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36

400 Bytes over!

何故高速通信が可能かWebSocketのHeader FIN 1 bit RSV1 1 bit RSV2 1 bit RSV3 1 bit Opcode 4 bits Mask 1 bit Payload length 7 bits, 7+16 bits, or 7+64 bits Masking-key 0 bytes or 4 bytes

2~14 Bytes

何故高速通信が可能か送信データが「Hello, world」の場合

HTTP12 bytes + 400 bytes → 412 Bytes97.1%がHeader

WebSocket (Client => Server)12 bytes + 6 bytes → 18 Bytes33.3%がHeader

何故高速通信が可能か送信データが「Hello, world」の場合

HTTP12 bytes + 400 bytes → 412 Bytes97.1%がHeader

WebSocket (Client => Server)12 bytes + 6 bytes → 18 Bytes33.3%がHeader

HTTP12 bytes + 400 bytes →97.1%がHeader

WebSocket (Client => Server)12 bytes + 6 bytes →33.3%がHeader

同じ文字列を送信するために約23倍のデータ量

Cometよりも低負荷

今回は詳細にはふれません

SAMPLE

WebSocket Servernode.js サーバサイドJavaScriptws WebSocketライブラリ)

以下はインストール済みとするnvm nodeのバージョン切り替えツールnpm nodeのパッケージ管理ツール

WebSocket Chat 作成

% mkdir chat ←ディレクトリ作成% cd chat ←ディレクトリ移動% nvm use v0.10.21 ←バージョン指定% npm install ws ←wsインストール

node.jsとwsのセットアップ

サーバ側

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

WebSocket Serverクラス取得

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

WebSocket Serverクラスのインスタンス化(ポート番号8080)

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

コネクションの保存領域作成

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

接続時の動作を指定

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

接続時にコネクションを保存

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

メッセージ受信時の動作を指定

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

メッセージ受信時に受け取ったメッセージの表示と保存しているコネクションに送信

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

切断時の動作を指定

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

切断時にコネクションを削除

var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8080});var clients = [];wss.on('connection', function(ws) { clients.push(ws); ws.on('message', function(message) { console.log(message); clients.forEach(function(c) { c.send(message); }); }); ws.on('close', function() { clients = clients.filter(function(c) { return c !== ws; }); });});

Server解説用に書いた問題のあるコードです。このままでも動きますが使わないで下さい。

クライアント側

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

テキストボックス・ボタン・メッセージエリアの表示とScript要素

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

WebSocketで接続

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

メッセージ受信時の動作を指定

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

メッセージ受信時に受け取ったメッセージを表示

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

ボタンクリック時の動作を指定

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

ボタンクリック時にメッセージを送信して入力欄を空に

<!DOCTYPE html><input id="msg" /><input type="button" value="send" id="send" /><div id="disp"></div><script>var ws = new WebSocket('ws://localhost:8080');ws.addEventListener('message', function(e) { var disp = document.getElementById('disp'); var text = document.createTextNode(e.data); disp.appendChild(text);}, false);document.getElementById('send') .addEventListener('click', function(e) { var msg = document.getElementById('msg'); ws.send(msg.value); msg.value = ''; }, false);</script>解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

Client

WebSocket まとめ

高速・双方向通信HTTPからSwitching ProtocolsHTTPSなら95%で接続可能Headerが小さいことが高速通信の理由のひとつCometよりも低負荷

WebRTC

WebRTCボイス・ビデオチャット / P2P2つの仕様Media Capture and Streams (getUserMedia)WebRTC 1.0: Real-time Communication Between Browsers

Media Capture and Streams (getUserMesia)

ブラウザからマイクやカメラにアクセス利用範囲はWebRTC以外とも音声処理(with Web Audio API)ボイスチェンジャー etc.

画像処理(with Canvas)顔検出 etc.

顔認識ができるようになるのも時間の問題か?

DEMO

SAMPLE

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ビデオ要素の表示とScript要素

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ユーザメディアの取得開始

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

取得するユーザメディアはカメラとマイク

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ユーザメディア取得時の動作を指定

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ビデオ要素の取得ユーザメディアの指定再生開始

<!DOCTYPE html><video id="video" /><script>navigator.getUserMedia( {video: true, audio: true}, function(stream) { var video = document .getElementById('video'); video.src = window.URL .createObjectURL(stream); video.play(); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

WebRTC 1.0: Real-time Communication Between

Browsers

ブラウザとブラウザを接続シグナリングSIPXMPPWebSocket <- 今のところ一番使われているetc.

DEMO

WebRTC 1.0: Real-time Communication Between

Browsers

NAT通過・ ネゴシエーションICE(STUN + TURN + α)

STUNP2P・UDPホールパンチング

TURNサーバ経由

WebRTC 1.0: Real-time Communication Between

Browsers

データ通信MediaStream音声データ・映像データ

DataChannelテキストデータ・バイナリデータ

Web Server

WebSocketServer

ICE Server(STUN)

Browser Browser

NAT NAT

HTML+JS+CSS

Global IP/Port

signaling

HTML+JS+CSS

Global IP/Port

signaling

data

WebRTC DataBlack Magic

別資料

https://speakerdeck.com/feross/webrtc-data-black-magic

P18~53 をご覧下さい

WebRTC 1.0: Real-time Communication Between

Browsers

APIが複雑でわかりにくい

抽象化した仕様の多いHTML5のAPIの中では非常に複雑

WebRTC まとめ

ボイス・ビデオチャットが可能テキスト・バイナリの通信も可能P2PNAT通過の仕組みAPIが複雑ライブラリを使うという選択肢も

定番と言われるようなライブラリはまだありません。

Web Audio API

Web Audio API

オーディオ波形操作フィルタリングミキシング加工

動的に波形を生成することも可能SE等の短い音声に特に威力を発揮

音声処理の種類ウェーブシェイパーコンボルバ(畳み込み)

リバーブ(残響)

ディレイ(遅延)ダイナミックコンプレッサーゲイン

双2次フィルタローパスフィルタ

ハイパスフィルタ

バンドパスフィルタ

ローシェフフィルタ

ハイシェフフィルタ

ピーキングフィルタ

ノッチフィルタ

オールパスフィルタ

Delay0.2s

in/out間をノードで接続

outputinput

Gain20%

Echo

in側とout側の種類inputマイクMediaStreamバイナリデータオシレータAudio要素Video要素

outputスピーカーMediaStream

プログラマブルScriptProcessorNodeinputとoutputの両方で使えるinput and/or outputinput例getUserMediaから取得した音声を加工WebRTCで取得した遠隔地の音声を解析

output例ゼロから音声データの生成が可能

output

input

生成

加工

解析

音源とリスナーを3D空間上に

PannerNode・AudioListener音源とリスナーを3D空間上に配置音源の方向・移動速度も指定可能左右の音量差・ドップラー効果等WebGLと同時によく使われるOpenALに近い

音源とリスナーを3D空間上に

◎ ◎ ◎

音源とリスナーを3D空間上に

◎ ◎ ◎左右スピーカーの音量の差

ドップラー効果

SAMPLE

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

Script要素

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

AudioContextクラスのインスタンス化

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ゲイン(音量調整)ノード作成ディレイ(遅延)ノード作成

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ゲイン(音量調整)に20%を指定ディレイ(遅延)に0.2秒を指定

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ユーザメディアの取得開始取得するユーザメディアはマイク

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ユーザメディア取得時の動作を指定

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

メディアストリームからWeb Audio APIのオブジェクトを作成

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

source(インプット)をdestination(アウトプット)に接続

第一のルート

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

source・ディレイ・ゲイン・destinationの順に接続

第二のルート

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

ゲインからディレイに接続(遅延・音量調整をループ)

第三のルート

<!DOCTYPE html><script>var context = new AudioContext();var gain = context.createGainNode();var delay = context.createDelayNode();gain.gain.value = 0.2;delay.delayTime.value = 0.2;navigator.getUserMedia( {audio: true}, function(stream) { var source = context.createMediaStreamSource(stream); source.connect(context.destination); source.connect(delay); delay.connect(gain); gain.connect(context.destination); gain.connect(delay); });</script>解説用に書いたコードです。 ベンダープレフィックスがないため動きません。

Web Audo API まとめ

ノードを接続し処理を行なう多数のinput/output音声データの編集ができるJavaScriptで直接編集も可能3D空間にも対応

WebGL

WebGL

3DグラフィックのAPIOpenGLのサブセット的な位置付けGPUを利用する互換レイヤーを挟んでいるDirectX(Windows)でも利用可能GLSLの知識が必要で非常に高難度

three.js

デファクトスタンダードのライブラリWebGL界のjQuery3DCDの知識があればハードルは低いCSS3D等のレンダラーも選択可能

geometry

mesh

環境光の色ハイライトの色

テクスチャ透明度・屈折率 etc. material

mesh

環境光の色遠景の処理 etc.

light

camera

geometry(形状)テキスト円平面立方体円柱チューブ球体

円環体(トーラス)リング等 四面体

八面体二十面体多面体パラメトリック曲線etc.

material物体の色ハイライトの色ハイライトの大きさ発光色金属か否か環境光の色屈折率透明度

mapテクスチャ画像

バンプ(表面の凹凸)画像スケール

環境マッピング(擬似的な背景)etc.

scene & etc.カメラライト(照明)環境光メッシュフォグパーティクルレンズフレア

レンダラー選択可能

ピッキングマウスによる選択等

軌道制御マウスでカメラ移動

ポストプロセスetc.

SAMPLE

<!DOCTYPE html><div id="disp"></div><script src="three.min.js"></script><script>// next slide...</script>

解説用に書いた問題のあるコードです。 このままでも動きますが使わないで下さい。

表示とthree.jsの読み込みとScript要素

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

レンダラーを作成し、サイズと色を指定

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

描画領域をDOMに追加

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

カメラを作成カメラの位置と方向を指定

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

色を指定し、ライトを作成ライトの位置を指定

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

大きさと目の細かさを指定し、形状(球)を作成

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

色を指定し、マテリアルを作成

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

形状とマテリアルからメッシュを作成

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

シーンを作成し、ライト・メッシュをシーンに追加

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

シーンとカメラと指定しレンダリング(描画)

var renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(500, 500);renderer.setClearColorHex(0xcccccc, 1);var disp = document.getElementById('disp');disp.appendChild(renderer.domElement);var camera = new THREE.PerspectiveCamera();camera.position = new THREE.Vector3(0, 0, 8);camera.lookAt(new THREE.Vector3(0, 0, 0));var light = new THREE.DirectionalLight(0xcccccc);light.position = new THREE.Vector3(1, 1, 1);var geometry = new THREE.SphereGeometry(3, 32, 16);var material = new THREE.MeshPhongMaterial({color: 0xff0000});var mesh = new THREE.Mesh(geometry, material);var scene = new THREE.Scene();scene.add(light);scene.add(mesh);renderer.render(scene, camera);

WebGL まとめ

OpenGLのサブセットGPUを利用Windowsでも使えるGLSLは難解three.jsを使おう

Combination

APIを組み合わせて使う

色々見てみよう!

HTML5の効能Webプラットフォーム上組み合わせて使いやすいAPIが適度に抽象化されている一部例外あり

やりたい事が簡単にできる参入障壁が非常に低い今後はアイディアが重要に...?

質疑応答

もう一度聞きたいところはありますか?

もっと詳しく聞きたいところはありますか?

ご清聴ありがとうございました

Recommended