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&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
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:
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://github.com/gimite/web-socket-js/
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.
Top Related