Is html5-ready-workshop-110727181512-phpapp02
-
Upload
pl-dream -
Category
Technology
-
view
839 -
download
0
Transcript of Is html5-ready-workshop-110727181512-phpapp02
Is HTML5 ready for
production?
Hi, I’m Remy
I <3 JavaScript
Questions: interrupt & ask!
There's a lot more down here.
HTML5 is a spec
"HTML5" is a brandsort of
^
HTML5
Offline applications
Offline events
Canvas
Video
Web Form
s
"HTML5"
Web Storage
Web SQ
L Databases
Web Sockets
Web W
orkersG
eolocationM
OA
R!!!
NOT HTML5
NOT HTML5
CSS != HTMLBut maybe we should have been more careful
caniuse.com
When can I use "HTML5"?
Making it work in the "other" browser
PolyfillA shim that mimics a futureAPI providing a fallback to
older browsershttp://goo.gl/0Z9eI
ToolsModernizr to detect support
yepnode.js to conditionally load(available as part of Modernizr)
ToolsModernizr.load({ test: Modernizr.geolocation, nope: 'geo-polyfill.js', complete: initMyGeoApp});
Oh, and learn JavaScript
Web Storage
Cookies suck.
Cookies suck.
Not the edible ones, duh.
The code for cookies is a pain - I always
google it.
"Session" cookies leak across sessions.
Persistent cookies require special date
format
Deleting a cookie, isn't really deleting, but setting in the past.
Varying degrees of limitations on size and
number.
Fuck cookies.
Sexy Web Storage FTW
One Interface
localStoragesessionStorage
http://dev.w3.org/html5/webstorage/
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
How much space do you want?
5mb?Done! \o/However: utf-16 ∴ 2½Mb
APIvoid setItem(key, value)
any* getItem(key)
void removeItem(key)
string key(index)
void clear()
readonly number length
var store = sessionStorage;
store.setItem('name','rem');
store.getItem('name');
store.removeItem('name');
Play
Do it in the console!
APIsetter setItem
getter getItem
deleter removeItem
var store = sessionStorage;
store.name = 'rem';
store.name;
delete store.name;
Play
Do it in the console!
// Safari debugger broken:
ss.setItem('key', 12);
tipThere's no security protecting the API
Values are strings
Work around: JSON(and http://www.json.org/json2.js)
var store = sessionStorage,
user = { screen_name : ‘rem’,
rating : 11 };
store.user = JSON.stringify(user));
var gotUser = JSON.parse(store.user);
alert(gotUser.screen_name);
Play
Events too
window.addEventListener('storage', function (event) {
console.log(event);
}, false);
http://jsbin.com/ahafa3
Storage in all browsers
window.name
sessionStorage = (function () { var data = window.name ? JSON.parse(window.name) : {};
return { clear: function () { data = {}; window.top.name = ''; }, getItem: function (key) { return data[key] || null; }, removeItem: function (key) { delete data[key]; window.top.name = JSON.stringify(data); }, setItem: function (key, value) { data[key] = value; window.top.name = JSON.stringify(data); } };})(); http://gist.github.com/350433
Firefox cookie security applies to Storage too :(
tip
tipvar cookiesEnabled = (function () { // the id is our test value var id = +new Date();
// generate a cookie to probe cookie access document.cookie = '__cookieprobe=' + id + ';path=/';
// if the cookie has been set, then we're good return (document.cookie.indexOf(id) !== -1);})();
Questions?
Ca
nv
as
Cooler than this guy.
Canvas SVG
• It's not one is better than the other, they do different things
• Select canvas when it makes sense
• Don't assume interactive means canvas
• Check out raphaeljs.com
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><title>Canvas</title></head><body> <canvas></canvas></body></html>
Play
canvas-1.html
http://dev.w3.org/html5/canvas-api/canvas-2d-api.html
2D API
ctx = canvas.getContext('2d')
Start Simple
fillRect, strokeRect & colours
ctx.fillRect(10, 10, 100, 100);
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(100, 75, 50, 50);
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(100, 75, 50, 50);
ctx.strokeStyle = '#0c0';
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(100, 75, 50, 50);
ctx.strokeStyle = '#0c0';
ctx.lineWidth = 5;
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(100, 75, 50, 50);
ctx.strokeStyle = '#0c0';
ctx.lineWidth = 5;
ctx.arc(100,50,25,0,Math.PI*2,true);
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = '#c00';
ctx.fillRect(100, 75, 50, 50);
ctx.strokeStyle = '#0c0';
ctx.lineWidth = 5;
ctx.arc(100,50,25,0,Math.PI*2,true);
ctx.stroke();
Math.PI == 180°
tip
Math.PI *2 == 360°
tip
d * Math.PI / 180 == radian
tip
tip CSS stretches
Gradient fills
1. Create a gradient object
2.Add colour stops
3.Set the gradient to the fillStyle
4.Draw
var w = canvas.width, h = canvas.height;
var gradient = ctx.createLinearGradient(0, 0, w, h);
var w = canvas.width, h = canvas.height;
var gradient = ctx.createLinearGradient(0, 0, w, h);gradient.addColorStop(0, '#fff');gradient.addColorStop(0.5, '#f00');gradient.addColorStop(1, '#000');
var w = canvas.width, h = canvas.height;
var gradient = ctx.createLinearGradient(0, 0, w, h);gradient.addColorStop(0, '#fff');gradient.addColorStop(0.5, '#f00');gradient.addColorStop(1, '#000');
ctx.fillStyle = gradient;
var w = canvas.width, h = canvas.height;
var gradient = ctx.createLinearGradient(0, 0, w, h);gradient.addColorStop(0, '#fff');gradient.addColorStop(0.5, '#f00');gradient.addColorStop(1, '#000');
ctx.fillStyle = gradient;ctx.fillRect(0, 0, w, h);
Play
createRadialGradient(x0,y0,r0,x1,y1,r1)
Pattern Fills
var img = new Image();
img.src = url;
var pattern = ctx.createPattern(img,'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, w, h);
tip invalid_state
img.onload = function () { // now use image for canvas};
Playing with paths
• For drawing irregular shapes
• Can be filled
• ...or stroked.
lineWidth
lineTo(x,y)
moveTo(x,y)
beginPath()
closePath()
rect(x,y,h,w)
arc(x,y,r,s,e, anticw)
fill()
stroke()
drawImage
<canvas>
<img> <video><canvas>
drawImage(src, dx, dy)
drawImage(src, dx, dy, dw, dh)
drawImage(src, sx, sy, sw, sh, dx, dy, dw, dh)
Play
canvas-10.html
img.onload = function () { // this == img canvas.width = this.width; canvas.height = this.height; ctx.drawImage(this, 0, 0);};
pixelpushing
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 pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) {
}
var pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) {
}
This says loop over each pixel
var pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) { // red: pixels.data[i+0]
}
var pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) { // red: pixels.data[i+0] // green: pixels.data[i+1]
}
var pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) { // red: pixels.data[i+0] // green: pixels.data[i+1] // blue: pixels.data[i+2]
}
var pixels = ctx.getImageData(0, 0, w, h), l = pixels.data.length, i;
for (i = 0; i < l; i += 4) { // red: pixels.data[i+0] // green: pixels.data[i+1] // blue: pixels.data[i+2] // alpha: pixels.data[i+3]}
ctx.putImageData(pixels, 0, 0)
ctx.putImageData(pixels, 0, 0)
Needs to be a CanvasPixelArray
object
tip security_err
To use getImageData, your document
must be served over http (or https) -
i.e. it doesn't work offline.
Play
http://jsbin.com/aguho3/2/edit
greyscale = r*.3 + g*.59 + b*.11;
r = g = b = greyscale;
saturation = (Math.max(r,g,b) + Math.min(r,g,b))/2;
r = g = b = saturation;
/workshop/authors-large.jpg
canvas.toDataURL('image/png');
save.onclick = function () { window.open( canvas.toDataURL('image/png') );};
Play
canvas-13.html
Questions?
Offline Applications
Offline Apps
• Application cache / manifest
• Events: offline, online
• navigator.onLine property
Using a Manifest<!DOCTYPE html>
<html manifest="my.appcache">
<body>
<!-- my page -->
</body>
</html>
CACHE MANIFEST
app.html
css/style.css
js/app.js
#version 13
my.appcache
The Manifest
1. Serve as text/manifest, by adding to mime.types:
text/cache-manifest appcache
<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. Two futher namespaces: NETWORK & FALLBACK
FALLBACK:/ offline.html
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
Served from cache
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
Requests for files not
found in the cache, are
directed to /
i.e. index.html
(when offline).
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
Any requests to urls
that don't match / -
i.e. on another
domain, will be
served through the
web.
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
Also ensures
browser even
attempts to load the
asset
CACHE MANIFEST
/index.htmlrange.jsdatastore.js
FALLBACK:# force everything through # the index url/ /
# this won't match # anything unless it's on # another domainNETWORK:*
# v4
The contents of the
manifest must
change to trigger an
update
The Manifest
5. Include some versioning to cache bust your manifest
# version 16
The process
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
Problem:Change of contentrequires 2 refreshes
document.body.onOnline = function () { // fire an update to the cache applicationCache.update();};
applicationCache.onUpdateReady = function () { if (confirm("New version ready. Refresh?")) { // reload window.location.refresh(); }};
tip
Do offline last
Questions?
Web Sockets
Native or polyfilled
http://github.com/gimite/web-socket-js/
new WebSocket(url)
http://dev.w3.org/html5/websockets/
ws://node.remysharp.com:8000
http://github.com/miksago/node-websocket-server
onopen
onmessage
onclose
onerror
var data = JSON.parse(event.data);
.send
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
Play
Questions?To contact me after my presentation – text NHT to INTRO (46876)
Or [email protected]@rem