html5 - daha flash bir web?
DESCRIPTION
2014 yılının sonunda sonlandırılması beklenen HTML standardının 5. sürümü çoktandır tarayıcılar tarafından destekleniyor. HTML5 ile gelen Canvas, Websockets ve diğer özelliklerle nasıl daha canlı, daha Flash uygulamalarına benzer, web uygulamaları geliştirebileceğimizi inceledik.TRANSCRIPT
Daha Flash bir web?
linkedin.com/in/mcalpayMurat Can ALPAY
mcatr.blogspot.com
● Ne sunulacak?● HTML5 mi? ● Yazılım projeleri mi?
VS?
● Adil mi?
İçerik
● Tarih● JavaScript● Canvas● Audio● WebSocket● Offline
Neden yeni bir HTML sürümü?
● oyun geliştirilmesi için mi?● video için mi?● 3d için mi?● ...
http://net.tutsplus.com/articles/general/a-brief-history-of-html5/
HTML5 Tarihi● 2004
○ WHATWG (Apple, Mozilla, Opera)● 2006
○ W3C XHTML● 2008
○ İlk versiyon○ Firefox 3, sonra diğerleri
● 2010○ Steve Jobs, Flash Andıçı
● 2014 ○ Final
http://net.tutsplus.com/articles/general/a-brief-history-of-html5/
W3C (HTML5 Tarihi)
● XHTML 2.0○ No Backward Compability!○ Strictly XML
http://net.tutsplus.com/articles/general/a-brief-history-of-html5/
WHAT WG
● 2004 W3C Workshop● Backward Compatible● Detailed Spec.
○ Non Strict HTML Parser
http://net.tutsplus.com/articles/general/a-brief-history-of-html5/
“The Web is, and should be, driven by technical merit, not consensus. The W3C pretends otherwise, and wastes a lot of time for it. The WHATWG
does not.” – Ian HicksonBenevolent Dictator for Life
<time> olayı
http://net.tutsplus.com/articles/general/a-brief-history-of-html5/
Jobs vs Adobe
● Kasım 2011 ○ Adobe: Mobil ve TV için Flash olmayacak
http://en.wikipedia.org/wiki/Adobe_Flash
HTML5 Bugün
● Youtube HTML5 test○ http://www.youtube.com/html5
● Mobile○ Amazon
HTML5 Tarayıcı Desteği
JavaScript ?
● Minecraft● Quake 3● Cut the rope
JS
Minecraft in JS
● Orjinal MC 17.5 Milyon sattı
JS
Quake in JShttp://media.tojicode.com/q3bsp/
JS
Cut The Ropehttp://www.cuttherope.ie/dev/
● Performance○ 37 - 62 FPS
JS
JavaScript ?for(i = 1; i <= 3; i++) {
print();
}
function print() {
for(i = 1; i <= 3; i++) {
console.log(i);
}
}
JS
JavaScript ? (var)
for(var i = 1; i <= 3; i++) {
print();
}
function print() {
for(i = 1; i <= 3; i++) {
console.log(i);
}
}
JS
JavaScript ? ( ?, var)for(i = 1; i <= 3; i++) {
print();
}
function print() {
for(var i = 1; i <= 3; i++) {
console.log(i);
}
}
JS
JavaScript ? (var, var)for(var i = 1; i <= 3; i++) {
print();
}
function print() {
for(var i = 1; i <= 3; i++) {
console.log(i);
}
}
JS
JavaScript ? (Tools)
● Chrome○ Developer Tools
● Ant Scripts
JS
Canvas
● Alt seviye çizim kütüphanesi● 2D● 3D
○ WebGL○ Three.js
Canvas (Context)<canvas id="canvas" width="800px" height="600px"/>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
Canvas (Rectangle)
ctx.fillStyle = "red";
ctx.fillRect(50,50,400,300);
Canvas (State)for(var i=0; i<data.length; i++) {
ctx.save();
ctx.translate(40+i*100, 460-dp*4);
var dp = data[i];
ctx.fillRect(0,0,50,dp*4);
ctx.restore();
}
Canvas (Gradient)var grad = ctx.createLinearGradient(0, 0, 800, 600);
grad.addColorStop(0, "red");
grad.addColorStop(1, "yellow");
ctx.fillStyle = grad;
Canvas (Path)ctx.beginPath();
...
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineTo(x3,y3)
ctx.closePath();
Canvas (Image)var spaceImg = new Image();
spaceImg.src = 'space.png';
ctx.drawImage(spaceImg, 0, 0);
Canvas (Edit an Image)var img = new Image();
img.onload = function() {
ctx.drawImage(img,0,0);
var data =
ctx.getImageData(0,0,
canvas.width,canvas.height);
...
ctx.putImageData(data,0,0);
}
img.src = "space.png";
Canvas (Text)ctx.fillStyle = "white";
ctx.font = 16 + "pt Arial ";
ctx.fillText("fps :" + Math.floor(1000 / diffTime), 10, 20);
Canvas (Mouse Events)canvas.addEventListener('mousemove', onMousemove, false);
canvas.addEventListener('mousedown', onMouseclick, false);
function onMousemove(ev) {
var x, y;
if (ev.layerX || ev.layerX == 0) { // Firefox
x = ev.layerX;
y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
}
Canvas (Animation)window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
window.requestAnimFrame(drawIt);
Audio
● 3D Positional Audio
Audio (Basic)var actx = new window.webkitAudioContext();
var request = new XMLHttpRequest();
request.open('GET', '/blast.wav', true);
request.responseType = 'arraybuffer';
request.onload = function (ev) {
actx.decodeAudioData(ev.target.response, function (buffer){
var source = actx.createBufferSource();
source.buffer = buffer;
source.connect(actx.destination);
source.noteOn(0);
});
};
request.send();
Audio (Gain)function playSource(buffer, gainVol, loop) {
var gnode = actx.createGainNode();
var source = actx.createBufferSource();
source.loop = loop;
source.buffer = buffer;
source.connect(gnode);
gnode.connect(actx.destination);
gnode.gain.value = gainVol;
source.noteOn(0);
}
Audio (AudioPannerNode)function playPositionalSource(holder, src, dest) {
var gnode = actx.createGainNode();
var source = actx.createBufferSource();
source.buffer = holder.src;
var panner = actx.createPanner();
panner.setPosition(src.x / 800, src.y / 600, 0);
panner.connect(gnode);
gnode.connect(actx.destination);
source.connect(panner);
actx.listener.setPosition(dest.x / 800, dest.y / 600, 0);
gnode.gain.value = holder.gain;
source.noteOn(0);
}
WebSocket
● Basit API● Fazladan Başlık Bilgisi Yok● Soket / Port Gerek● Sunucu Desteği
WebSocket (Callbacks)var connection = new WebSocket('ws://localhost:8080/play', ['text']);connection.onopen = function () {...}
connection.onerror = function (error) { console.log('WebSocket Error ' + error);}
connection.onmessage = function (e) { var jo = JSON.parse(e.data);...}
WebSocket (Send)function send(msg) { if(connection.readyState == 1) { connection.send(msg) }}
WebSocket (Jetty)
"Don't deploy your app. to Jetty, Deploy Jetty to your app."
WebSocket (WebSocketServlet)import org.eclipse.jetty.websocket.WebSocketServlet
public class WSGameServlet extends WebSocketServlet {
...
@Override
public WebSocket doWebSocketConnect(HttpServletRequest req,
String protocol) {
return new GameSocket(createNewPlayer(req), world);
}
}
WebSocket (WebSocket onOpen)import org.eclipse.jetty.websocket.WebSocket
public class GameSocket implements WebSocket,
WebSocket.OnTextMessage {
...
@Override
public void onOpen(Connection connection) {
this.connection = connection;
world.addSocket(this);
}
}
WebSocket (WebSocket onClose)import org.eclipse.jetty.websocket.WebSocket
public class GameSocket implements WebSocket,
WebSocket.OnTextMessage {
...
@Override
public void onClose(int closeCode, String msg) {
world.removeSocket(this);
world.removePlayer(avatar.getId());
}
}
WebSocket (WebSocket onMessage)import org.eclipse.jetty.websocket.WebSocket
public class GameSocket implements WebSocket,
WebSocket.OnTextMessage {
...
public void onMessage(String msg) {
try {
Map<String, String> attMap = getAttributeMap(msg);
String pathInfo = attMap.get("path");
if ("static".equals(pathInfo)) {
connection.sendMessage("static/" + staticGameMap);
} else if ("text".equals(pathInfo)) {
...
}
}
WebSocket (sockets)public class AxeWorld extends TimerTask implements World {
...
public final Set<GameSocket> sockets;
@Override public void addSocket(GameSocket gameSocket)...
@Override public void removeSocket(GameSocket gameSocket)...
@Override
public void run() {...
for (GameSocket gs : sockets) {
gs.sendMessage(msg);
...
Demo
3D
● WebGL○ experimental
● Three.js
3D (Three.js)
● https://github.com/mrdoob/three.js● High level● Renderers
○ Canvas○ WebGL○ SVG
3D (Three.js)
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
scene = new THREE.Scene();
geometry = new THREE.CubeGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
https://github.com/mrdoob/three.js
3D (Three.js)
function animate() {
// note: three.js includes requestAnimationFrame shim
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
https://github.com/mrdoob/three.js
3D (Three.js)
Storage
● Local
● Session
● Database
Storage (Local Storage)
● Cookies○ 4KB○ HTTP Headers
● 5 MB key/value
Storage (Local Storage)localStorage.commands = JSON.stringify(commands);
if (window.addEventListener) { window.addEventListener("storage", handle_storage, false);} else { window.attachEvent("onstorage", handle_storage);};
Storage (Session Storage)
● Oturum için
● sessionStorage
Storage (Database Storage)
● 5 MB'den fazlası
● Web SQL Database
Storage (IndexDB)
● Not yet
Application Cache
● Old Way Directives
● New Way Manifest
ApplicationCache (Cache Directives)
● HTTP
Application Cache (Manifest)
● Cache what?
● mime-type : text/cache-manifest
● CACHE, NETWORK, FALLBACK
Manifest<!DOCTYPE html><html manifest="cache.mf"><head>...
Manifest (CACHE)
http://www.html5rocks.com
CACHE MANIFEST
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
Manifest (NETWORK)
http://www.html5rocks.com
# online:
NETWORK:
login.php
/myapi
http://api.twitter.com
Manifest (FALLBACK)
http://www.html5rocks.com
# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg
*.html /offline.html
Demo
Teşekkürler
● Mert Çalışkan● Çağatay Çivici● Barış Bal
linkedin.com/in/mcalpayMurat Can ALPAY
mcatr.blogspot.com
Bir saattir, Riv Riv Riv