Download - HTML5の基礎と応用 ~Open Web Platform~
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://en.wikipedia.org/wiki/Stevedorehttp://en.wikipedia.org/wiki/File:Hafenarbeiter_bei_der_Verladung_von_Sackgut_-_MS_Rothenstein_NDL,_Port_Sudan_1960.png
http://en.wikipedia.org/wiki/Stevedorehttp://en.wikipedia.org/wiki/File:Stevedores_ny_1912.jpg
http://en.wikipedia.org/wiki/Container_shiphttp://en.wikipedia.org/wiki/File:Korean-war-merchant-marine-load.jpg
イノベーション
コンテナリゼーション
積み替えが容易に積み替えが迅速に梱包コストの削減積み重ねが容易
荷抜き・盗難が困難に
統一規格
インターモーダル輸送複合一貫輸送
http://en.wikipedia.org/wiki/Stevedorehttp://en.wikipedia.org/wiki/File:Starker_Gezeitenstrom,_Ladungsarbeiten_bei_schwierigen_Arbeitsbedingungen.jpg
http://en.wikipedia.org/wiki/Semi-trailer_truckhttp://en.wikipedia.org/wiki/File:Artic.lorry.arp.750pix.jpg
http://en.wikipedia.org/wiki/Double-stack_rail_transporthttp://en.wikipedia.org/wiki/File:Panama_Canal_Railway_-_Container_Train.JPG
http://en.wikipedia.org/wiki/Double-stack_rail_transporthttp://en.wikipedia.org/wiki/File:Cajon_Intermodal.jpg
コンテナリゼーションは多くの荷役の職を奪った。
坑夫
http://en.wikipedia.org/wiki/History_of_coal_mining_in_the_United_Stateshttp://en.wikipedia.org/wiki/File:Child_coal_miners_(1908)_crop.jpg
電話交換手
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
イノベーションは既存の仕組みを
破壊することがある
繰り返される歴史
近年では?
例えばコンパクトカセット
(カセットテープ)
http://en.wikipedia.org/wiki/Compact_Cassettehttp://en.wikipedia.org/wiki/File:Philips_EL3302.jpg
http://en.wikipedia.org/wiki/Compact_Cassettehttp://en.wikipedia.org/wiki/File:CassetteTypes1.jpg
イノベーション
コンパクトディスク
http://www.flickr.com/photos/kismihok/8928946658/
ITが破壊したもの
例えば写真フィルム
http://en.wikipedia.org/wiki/135_filmhttp://en.wikipedia.org/wiki/File:135_fuji_film_macro.jpg
イノベーション
デジタルカメラ
http://www.flickr.com/photos/jvcamerica/6193351840/
富士フィルム事業縮小現在は、液晶フィルム・医療機器・化粧品等
コニカ 現:コニカミノルタDPE部門と共に譲渡現在は、複合機・カメラ・計測機器・医療機器等
コダック破綻
アグファカメラ事業から撤退現在は、医療機器・印刷機器・製版・印刷材料等
携帯電話
http://www.toledoblade.com/Technology/2011/10/05/Apple-co-founder-Steve-Jobs-dead-at-56.html
破壊的イノベーション
最初期から真っ当に
評価されていたか
世界で最初のデジタルカメラ
http://www.flickr.com/photos/x1brett/4928370431/
http://www.digitaltrends.com/photography/two-pioneers-of-digital-photography-honored-by-national-inventors-hall-of-fame/
解像度は100 x 100白黒
カセットテープに記録
QV-10
デジタルカメラの普及の切っ掛けを
作った。
http://www.flickr.com/photos/ume-y/5439197136/
解像度は320 x 240ストロボなしピント固定
2MBの内蔵メモリに96枚バッテリが保たない(単3電池4本が96枚保たない)
『本日、Appleが電話を
再発明します』
http://blog.livedoor.jp/ma_oyabu/archives/1749687.html
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
狭義の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
インパクトの強そうな仕様の一部
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が適度に抽象化されている一部例外あり
やりたい事が簡単にできる参入障壁が非常に低い今後はアイディアが重要に...?
完
質疑応答
もう一度聞きたいところはありますか?
もっと詳しく聞きたいところはありますか?
ご清聴ありがとうございました