Is HTML5 Ready? (workshop)
Upcoming SlideShare
Loading in...5
×
 

Is HTML5 Ready? (workshop)

on

  • 2,608 views

 

Statistics

Views

Total Views
2,608
Views on SlideShare
2,488
Embed Views
120

Actions

Likes
3
Downloads
59
Comments
1

5 Embeds 120

http://www.oscon.com 63
http://lanyrd.com 51
http://fasoulas.posterous.com 4
http://posterous.com 1
http://lanyrd.dev:8000 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Is HTML5 Ready? (workshop) Is HTML5 Ready? (workshop) Presentation Transcript

  • Is HTML5 ready forproduction?
  • Hi, I’m Remy@remremy@leftlogic.comI <3 JavaScriptQuestions: interrupt& ask!
  • Theres a lot more down here.
  • HTML5 is a spec
  • sort of"HTML5" is a ^brand
  • MOAR!!!"HTML5" Geolocation Web Workers Web Sockets Web SQL Databases Web Storage Offline applicationsHTML5 Offline events Canvas Video Web Forms
  • H TM L5N OTNOT HTM L5
  • CSS != HTMLBut maybe we should have been more careful
  • caniuse.com
  • When can Iuse "HTML5"?
  • Making itwork inthe "other"browser
  • PolyfillA shim that mimics a futureAPI providing a fallback to older browsers http://goo.gl/0Z9eI
  • ToolsModernizr to detect supportyepnode.js to conditionally load(available as part of Modernizr)
  • ToolsModernizr.load({ test: Modernizr.geolocation, nope: geo-polyfill.js, complete: initMyGeoApp});
  • Oh, and learnJavaScript
  • Web Storage
  • Cookiessuck.
  • Not the edible ones, duh.Cookiessuck.
  • The code for cookies is a pain - I always google it.
  • "Session" cookiesleak across sessions.
  • Persistent cookiesrequire special date format
  • Deleting a cookie, isnt really deleting, but setting in the past.
  • Varying degrees oflimitations on size and number.
  • Fuck cookies.
  • Sexy Web Storage FTW
  • One InterfacelocalStoragesessionStorage 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• Doesnt leak• Exactly the same API as localStorage
  • 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;Play store.setItem(name,rem); store.getItem(name); store.removeItem(name); Do it in the console!
  • APIsetter setItemgetter getItemdeleter removeItem
  • var store = sessionStorage;Play store.name = rem; store.name; delete store.name; Do it in the console!
  • t ip Theres no security protecting the API // Safari debugger broken: ss.setItem(key, 12);
  • Values are strings Work around: JSON (and http://www.json.org/json2.js)
  • Play var store = sessionStorage, user = { screen_name : ‘rem’, rating : 11 }; store.user = JSON.stringify(user)); var gotUser = JSON.parse(store.user); alert(gotUser.screen_name);
  • Events toowindow.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
  • t ip Firefox cookie security applies to Storage too :(
  • t ipvar 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 were good return (document.cookie.indexOf(id) !== -1);})();
  • Web SQL Databases http://flic.kr/p/drmCJ
  • IndexedDB http://flic.kr/p/5KXFwB
  • Questions?
  • CanvasCooler than this guy.
  • Canvas SVG
  • http://vimeo.com/6691519
  • • Its not one is better than the other, they do different things• Select canvas when it makes sense• Dont assume interactive means canvas• Check out raphaeljs.com
  • http://mrdoob.com
  • canvas-1.htmlPlay <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Canvas</title> </head> <body> <canvas></canvas> </body> </html> http://dev.w3.org/html5/canvas-api/canvas-2d-api.html
  • 2D APIctx = 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();
  • t ip Math.PI == 180°
  • t ip Math.PI *2 == 360°
  • t ip d * Math.PI / 180 == radian
  • t ip CSS stretches
  • Gradient fills
  • 1. Create a gradient object2.Add colour stops3.Set the gradient to the fillStyle4.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);
  • PlaycreateRadialGradient(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);
  • t ip invalid_state img.onload = function () { // now use image for canvas };
  • Playing with paths
  • • For drawing irregular shapes• Can be filled• ...or stroked.
  • lineWidth rect(x,y,h,w)lineTo(x,y) arc(x,y,r,s,e, anticw)moveTo(x,y) fill()beginPath() stroke()closePath()
  • drawImage
  • <img> <canvas> <video> <canvas>
  • drawImage(src, dx, dy)drawImage(src, dx, dy, dw, dh)drawImage(src, sx, sy, sw, sh, dx, dy, dw, dh)
  • Play img.onload = function () { // this == img canvas.width = this.width; canvas.height = this.height; ctx.drawImage(this, 0, 0); }; canvas-10.html
  • 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 3i = 0 r g b ai = 1 r g b ai... r g b a
  • pixels.data[i * 4 + 1]; 0 1 2 3i = 0 r g b ai = 1 r g b ai... r g b a
  • pixels.data[i * 4 + 2]; 0 1 2 3i = 0 r g b ai = 1 r g b ai... r g b a
  • pixels.data[i * 4 + 3]; 0 1 2 3i = 0 r g b ai = 1 r g b ai... 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
  • t ip security_err To use getImageData, your document must be served over http (or https) - i.e. it doesnt work offline.
  • /workshop/authors-large.jpgPlay 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; http://jsbin.com/aguho3/2/edit
  • canvas.toDataURL(image/png);
  • Play save.onclick = function () { window.open( canvas.toDataURL(image/png) ); }; canvas-13.html
  • Questions?
  • Offline Applications
  • Offline Apps• Application cache / manifest• Events: offline, online• navigator.onLine property
  • http://icanhaz.com/rubiks
  • Using a Manifest<!DOCTYPE html><html manifest="my.appcache"><body><!-- my page --></body></html>
  • my.appcacheCACHE MANIFESTapp.htmlcss/style.cssjs/app.js#version 13
  • The Manifest1. Serve as text/manifest, by adding to mime.types:text/cache-manifest appcache
  • t ip Firefox caching <IfModule mod_expires.c> ExpiresActive on ExpiresByType text/cache-manifest ↪ “access plus 0 seconds” </IfModule>
  • The Manifest2. First line must be: CACHE MANIFEST
  • The Manifest3. Including page is implicitly included in the cache.
  • The Manifest4. Two futher namespaces: NETWORK & FALLBACK FALLBACK: / offline.html
  • CACHE MANIFEST/index.htmlrange.jsdatastore.jsFALLBACK:# force everything through# the index url/ /# this wont match# anything unless its on# another domainNETWORK:*# v4
  • CACHE MANIFEST / index.htmlServed from cache range.js datastore.js FALLBACK: # force everything through # the index url / / # this wont match # anything unless its on # another domain NETWORK: * # v4
  • CACHE MANIFEST / index.html range.jsRequests for files not datastore.jsfound in the cache, are FALLBACK: # force everything through directed to / # the index url / / i.e. index.html # this wont match (when offline). # anything unless its on # another domain NETWORK: * # v4
  • CACHE MANIFEST / index.html range.js datastore.jsAny requests to urls FALLBACK:that dont match / - # force everything through # the index url i.e. on another / / domain, will be # this wont match # anything unless its onserved through the # another domain NETWORK: web. * # v4
  • CACHE MANIFEST / index.html range.js datastore.js FALLBACK: # force everything through # the index url / / Also ensures # this wont match browser even # anything unless its on # another domainattempts to load the NETWORK: * asset # v4
  • CACHE MANIFEST / index.html range.js datastore.js FALLBACK: # force everything through # the index url / /The contents of the # this wont match manifest must # anything unless its on # another domainchange to trigger an NETWORK: * update # v4
  • The Manifest5. Include some versioning to cache bust your manifest # version 16
  • The process
  • Browser: I have aBrowser: request Server: serve all manifest, cache assets Browser: Server: serve applicationCache Browser: reloadmanifest assets updated Browser: only Browser: serve Server: 304 Not request manifest locally Modified file
  • Browser: I have a Problem: serve allBrowser: requestServer: manifest, cache assets Change of content requires 2 refreshes reload Server: serve Browser: applicationCache Browser:manifest assets updated Browser: only Browser: serve Server: 304 Not request manifest locally Modified file
  • 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(); }};
  • t ip 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
  • onopenonmessageoncloseonerror
  • 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 -- remy@leftlogic.com @rem