Browsers with Wings

Post on 12-May-2015

6.469 views 2 download

Tags:

description

HTML5 is all the rage with the cool kids, and although there’s a lot of focus on the new language, there’s plenty for web app developers with new JavaScript APIs both in the HTML5 spec and separated out as their own W3C specifications. This session will take you through demos and code and show off some of the outright crazy bleeding edge demos that are being produced today using the new JavaScript APIs. But it’s not all pie in the sky – plenty is useful today, some even in Internet Explorer!

Transcript of Browsers with Wings

Browserswith

Wings:HTML5 & APIs

HTML5 brand

HTML5 is: markup, JavaScript, CSS, SVG, jQuery & your dinner.

HTML5 is: markup, JavaScript, CSS, SVG, jQuery & your dinner.

Lie.Don't be stoopid, but...

HTML5 is anything & everything to mere mortal beings.

Today

Media

<video src=bruce.mp4>

<video src=bruce.mp4> <a href="bruce.mp4">Download</a></video>

Codec Wars

<video> <source src=bruce.mp4> <source src=bruce.ogv></video>

<video> <source src=bruce.webm> <source src=bruce.mp4> <source src=bruce.ogv></video>

<video controls> <source src=bruce.mp4> <source src=bruce.ogv></video>

<video> works in IE6

<video> works in IE6Lie.

<video width="640" height="360" controls preload="none"> <!-- MP4 must be first for iPad! --> <source src="__VIDEO__.MP4" type="video/mp4" /><!-- WebKit video --> <source src="__VIDEO__.OGV" type="video/ogg" /><!-- Firefox / Opera --> <!-- fallback to Flash: --> <object width="640" height="384" type="application/x-shockwave-flash" data="__FLASH__.SWF"> <!-- Firefox uses the `data` attribute above, IE/Safari uses the param below --> <param name="movie" value="__FLASH__.SWF" /> <param name="flashvars" value="image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" /> <!-- fallback image. note the title field below, put the title of the video there --> <img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__" title="No video playback capabilities, please download the video below" /> </object></video><!-- you *must* offer a download link as they may be able to play the file locally. customise this bit all you want --><p> <strong>Download Video:</strong> Closed Format: <a href="__VIDEO__.MP4">"MP4"</a> Open Format: <a href="__VIDEO__.OGV">"OGG"</a></p>

http://camendesign.com/code/video_for_everybody

Custom player style

function toggle() { if (video.paused) { video.play(); this.innerHTML = 'Pause'; } else { video.pause(); this.innerHTML = 'Play'; }}

var play = document.getElementById('play');play.onclick = toggle;

function toggle() { if (video.paused) { video.play(); this.innerHTML = 'Pause'; } else { video.pause(); this.innerHTML = 'Play'; }}

var play = document.getElementById('play');play.onclick = toggle;

function toggle() { if (video.paused) { video.play(); this.innerHTML = 'Pause'; } else { video.pause(); this.innerHTML = 'Play'; }}

var play = document.getElementById('play');play.onclick = toggle;

function toggle() { if (video.paused) { video.play(); this.innerHTML = 'Pause'; } else { video.pause(); this.innerHTML = 'Play'; }}

var play = document.getElementById('play');play.onclick = toggle;

// get & setvideo.currentTime

// half speedvideo.playbackRate = 0.5

// actual loaded videovideo.currentSrc

// etc

video.ontimeupdate = function () { updatePlayhead(this.currentTime);};

Fullscreen?

⚠Warning! User agents should not provide a public API to cause videos to be shown full-screen. A script, combined with a carefully crafted video file, could trick the user into thinking a system-modal dialog had been shown, and prompt the user for a password. There is also the danger of "mere" annoyance, with pages launching full-screen videos when links are clicked or pages navigated. Instead, user-agent specific interface features may be provided to easily allow the user to obtain a full-screen playback mode.

Ca

nv

as

Cooler than a fake Han Solo.

First consider SVG: Standard Vertical Graphing

First consider SVG: Standard Vertical Graphing Lie.

First consider SVG: Standard Vertical Graphing Lie.

Not a lie.

SVG: Vector based, good for simple and interactive

Canvas: Pixel based, good for pixel manipulation & high animation

Check out raphaeljs.com

Mix & match to the technology's strength

pixelpushing

http://mugtug.com/darkroom

var ctx = canvas.getContext('2d');

ctx.getImageData(0,0,w,h)

ctx.getImageData(0, 0, w, h);

0 1 2 3

i = 0 r g b a

i = 1 r g b a

i... r g b a

pixels.data[i * 4 + 0];

0 1 2 3

i = 0 r g b a

i = 1 r g b a

i... r g b a

pixels.data[i * 4 + 1];

0 1 2 3

i = 0 r g b a

i = 1 r g b a

i... r g b a

pixels.data[i * 4 + 2];

0 1 2 3

i = 0 r g b a

i = 1 r g b a

i... r g b a

pixels.data[i * 4 + 3];

0 1 2 3

i = 0 r g b a

i = 1 r g b a

i... r g b a

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) {

}

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) {

}

This says loop over each pixel

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) { px.data[i+0] = 255 - px.data[i+0];

}

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) { px.data[i+0] = 255 - px.data[i+0]; px.data[i+1] = 255 - px.data[i+1];

}

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) { px.data[i+0] = 255 - px.data[i+0]; px.data[i+1] = 255 - px.data[i+1]; px.data[i+2] = 255 - px.data[i+2];

}

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) { px.data[i+0] = 255 - px.data[i+0]; px.data[i+1] = 255 - px.data[i+1]; px.data[i+2] = 255 - px.data[i+2]; // don't need to do the alphachannel}

var px = ctx.getImageData(0, 0, w, h), l = px.data.length, i;

for (i = 0; i < l; i += 4) { px.data[i+0] = 255 - px.data[i+0]; px.data[i+1] = 255 - px.data[i+1]; px.data[i+2] = 255 - px.data[i+2]; // don't need to do the alphachannel}

ctx.putImageData(px, 0, 0);

You can do that in SVG, but you can't do this:

http://mrdoob.com

canvas.toDataURL()

canvas.toDataURL()

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAgAElEQVR4Ae2dCaBd073/f2e692YghpAYQuYQQaP9U8UrnbyktEWjraFNVaU8Q4gSwXNbREIaqVKlpVFPq6G0pMmjeIpXw1NjBkmIVIhMZJDc3OEM/99v7b3P2efcfc49e5+9z9nDd4d79tl7r7V+67PWWd+95liOD8IBAiAAAiAAAjYJxG0+j8dBAARAAARAQBGAgCAjgAAIgAAIOCIAAXGEDY5AAARAAAQgIMgDIAACIAACjghAQBxhgyMQAAEQAAEICPIACIAACICAIwIQEEfY4AgEQAAEQAACgjwAAiAAAiDgiAAExBE2OAIBEAABEICAIA+AAAiAAAg4IgABcYQNjkAABEAABCAgyAMgAAIgAAKOCEBAHGGDIxAAARAAAQgI8gAIgAAIgIAjAhAQR9rVjTqHDxx5Kq9bzaC45+BVqcP

1. Silverlight Bridge2. excanvas.js

Shims

Storage

Cookies suck.

(for most situations)

The code for cookies is painful: so we google it.

"Session" cookies

leak across "sessions".

Non-session cookies require "special" date format

Deleting cookies,

doesn't delete, but sets it

in the past.

Fuck cookies.

Sexy Web Storage FTW

Key/value pair

One APIsetItem(key, value)

One APIsetItem(key, value)

string* getItem(key)

One APIsetItem(key, value)

string* getItem(key)

removeItem(key)

One APIsetItem(key, value)

string* getItem(key)

removeItem(key)

string key(index)

One APIsetItem(key, value)

string* getItem(key)

removeItem(key)

string key(index)

clear()

One APIsetItem(key, value)

string* getItem(key)

removeItem(key)

string key(index)

clear()

.length

Two instances

localStoragesessionStorage

localStorage

• Persists

• Applied to document origin, i.e. scheme/host/port tuple

• No expiry

sessionStorage

• Lasts whilst on the document origin

• Doesn't leak

• Exactly the same API as localStorage

var ss = sessionStorage;

ss.setItem('version', 12);

ss.getItem('version');

Values are strings

Warning!

Values are strings

Work around: JSON(and http://www.json.org/json2.js)

Warning!

var ss = sessionStorage,

user = { screen_name : ‘rem’,

rating : 11 };

ss.setItem(‘user’, JSON.stringify(user));

var obj = JSON.parse(ss.getItem(‘user’));

alert(obj.screen_name);

window.name shim

http://gist.github.com/350433

Alternatives

Web SQL Database

IndexedDB

Geolocation

navigator.geolocation

getCurrentPosition

watchPosition

clearPosition

var geo = navigator.geolocation;

geo.getCurrentPosition(function(data){

map(data.coords.latitude,

data.coords.longitude);

});

var geo = navigator.geolocation;

geo.getCurrentPosition(function(data){

map(data.coords.latitude,

data.coords.longitude);

});

var geo = navigator.geolocation;

geo.getCurrentPosition(function(data){

map(data.coords.latitude,

data.coords.longitude);

});

var geo = navigator.geolocation;

geo.getCurrentPosition(function(data){

map(data.coords.latitude,

data.coords.longitude);

});

var geo = navigator.geolocation;

geo.getCurrentPosition(function(data){

map(data.coords.latitude,

data.coords.longitude);

});

Check your accuracy

if (!navigator.geolocation) { navigator.geolocation = (function (window) { function getCurrentPosition(callback) { // source: http://www.maxmind.com/app/javascript_city var geourl = 'http://j.maxmind.com/app/geoip.js_' + Math.random(), iframe = document.createElement('iframe'), doc, win;

iframe.style.display = 'none'; window.document.body.appendChild(iframe); doc = iframe.contentDocument || iframe.contentWindow.document; win = iframe.contentWindow; // once the script has loaded, it triggers an onload event iframe.onload = function () { // assign all the captured values across to our geo object var geo = { coords: { latitude: win.geoip_latitude(), longitude: win.geoip_longitude() // other values are supported, i.e. accuracy, speed, heading, etc }, timestamp: (new Date()).getTime() }; // then remove the iframe from the body to clear the memory...I hope! window.document.body.removeChild(iframe); callback.call(callback, geo); }; // create a document on the fly doc.open(); doc.write('<' + 'script src="' + geourl + '"><' + '/script>'); doc.close(); } return { clearWatch: function () {}, getCurrentPosition: getCurrentPosition, // TODO shouldn't be too difficult :) watchPosition: function () {} };})(this); }

http://j.mp/geoshim

Sock

ets

Move over

comet.

Low latency.Direct connection.Simple API.

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

var url = 'ws://apps.leftlogic.com:8000/',

conn = new WebSocket(url);

conn.onmessage = function (event) {

console.log(JSON.parse(event.data));

};

conn.send('hello world');

http://rem.im/collab-drawing

http://rem.im/collab-drawing

http://rem.im/collab-drawing

Partial

Offline

Using a Manifest<!DOCTYPE html>

<html manifest="my.manifest">

<body>

<!-- my page -->

</body>

</html>

CACHE MANIFEST

app.html

css/style.css

js/app.js

#version 13

my.manifest

The Manifest

1. Serve as text/manifest, by adding to mime.types:

text/cache-manifest manifest

<IfModule mod_expires.c>

ExpiresActive on

ExpiresByType text/cache-manifest

↪ “access plus 0 seconds”

</IfModule>

tip Firefox caching

The Manifest

2. First line must be:

CACHE MANIFEST

The Manifest

3. Including page is implicitly included in the cache.

The Manifest

4. Include some versioning to cache bust your manifest

# version 16

The Manifest

5. Two futher namespaces: NETWORK & FALLBACK

FALLBACK:/ offline.html

CACHE MANIFEST

CACHE:app.jsapp.cssindex.html

NETWORK:/live/*

FALLBACK:* offline.html

CACHE MANIFEST

CACHE:app.jsapp.cssindex.html

NETWORK:/live/*

FALLBACK:* offline.html

Served from cache

CACHE MANIFEST

CACHE:app.jsapp.cssindex.html

NETWORK:/live/*

FALLBACK:* offline.html

Requests to

http://mysite.com/live/x

must go via the web

CACHE MANIFEST

CACHE:app.jsapp.cssindex.html

NETWORK:/live/*

FALLBACK:/ offline.html

Requests for files not

found in the cache,

are directed to

offline.html (when

offline).

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

Browser: request Server: serve allBrowser: I have a manifest, cache

assets

Server: serve manifest assets

Browser: applicationCache

updatedBrowser: reload

Browser: serve locally

Browser: only request manifest

file

Server: 304 Not Modified

File API

files[0].getAsDataURL()

files[0].getAsDataURL()

Link prefetching

Web Workers

Web Forms

Hash change event, history state management

Contenteditable

Native drag and drop - embedding of data

Microdata

Cross server messaging

embedded attribute data

mime-type registration

DXHTML6

Link prefetching

Web Workers

Web Forms

Hash change event, history state management

Contenteditable

Native drag and drop - embedding of data

Microdata

Cross server messaging

embedded attribute data

mime-type registration

DXHTML6Lie.

"Should I be using HTML5today?"

1. doctype, script & styles only

1. doctype, script & styles only

2. New HTML5 elements

1. doctype, script & styles only

2. New HTML5 elements

3. Existing APIs

1. doctype, script & styles only

2. New HTML5 elements

3. Existing APIs

4. Shims

Yes.