Preflight

Checking compatibility...

If things look good, press to move on.

Bleeding Edge HTML5

  -  

Of course we're using Geolocation!

Who?

+


@


Blog:

HTML5

How did we get here?

evolutionofweb.appspot.com

Agenda

WARNING!

Web Apps

Smarter animations

Common technique for JS animations:

window.setTimeout(function() {
  // move element. Call this again.
}, 1000 / 60); // 60fps.

Preferred technique:

window.requestAnimationFrame = window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame || window.msRequestAnimationFrame;

var reqId_ = null;
(function callback(time) { // time is the Unix time.
  // move element.
  reqId_ = window.requestAnimationFrame(callback, opt_elem /* bounding elem */);
})();

Example

function draw() {
  var now = new Date().getTime();
  // update models.
  paintScene(canvas);
  window.setTimeout(draw, 10);
}
draw();

function draw(time) {
  // update models.
  paintScene(canvas);
  window.requestAnimationFrame(draw, canvas);
}
draw();

Page Visibility API / Prerendering

Determine if your app is visible or not:

document.addEventListener('visibilitychange', function(e) {
  console.log('hidden:' + document.hidden,
              'state:' + document.visibilityState)
}, false);

Demo

Prerendering pages:

<link rel="prerender" href="http://example.org/index.html">

Demo

Know when you're connected

Status:

if (navigator.onLine) {
  console.log('ONLINE!');
} else {
  console.log('Connection flaky');
}

Online/offline events:

window.addEventListener('online', function(e) {
  // Re-sync data with server.
}, false);

window.addEventListener('offline', function(e) {
  // Queue up events for server.
}, false);

Web Intents

The web has a problem...

Everyone is doing their own thing

The web has a problem...

Imagine integrating with all of these!

Web Intents is a framework for client-side service discovery and inter-application communication

How does it work?

  1. Service registers its intention to handle an action for the user
  2. App requests to start an action (share, edit, pick, view, ...)
  3. User selects which service to handle the action.

Sound familiar?

1. Service provider's application registers itself

Declare intention to handle image sharing:

<intent action="http://webintents.org/share" type="image/*" />
action
Required. A verb describing the action to be performed
type
Optional. Mimetype filters
href
Optional. If specified it will point to the action that is loaded when the user chooses the service. If undefined, use the current page.

2. Your app starts an action

App says it wants to use someone's sharing functionality:

var intent = new Intent('http://webintents.org/share', 'image/*');
intent.data = ['data:image/png;base64,R0lGO...'];

window.navigator.startActivity(intent, function(intentData) {
  var img = document.querySelector('img');
  img.src = intentData.data[0];
});

( 2b. user selects which awesome service to use )

3. Provider handles the action

Passed data ( optional ) is set on page load:

window.onload = function(e) {
  // window.intent.data contains the passed data.
};

Service: can post a callback message when it's done:

window.intent.postResult([ ... some data ... ]);

Then what?

Nothing! - you have just integrated your apps and services

Two-way communication

Client:

var intent = new Intent('http://webintents.org/pick', 'image/*');
intent.data = [imgData];

window.navigator.startActivity(intent, function(intentData) {
  var img = document.querySelector('img');
  img.src = intentData.data[0];
});

Service: can post a callback message when it's done:

window.intent.postResult([ ... some data ... ]);

Cloud Picker Demo

  1. User visits service. It registers itself for the pick action.
  2. User starts action in your app:

Get it today!

Multimedia

Camera & microphone access

Plugin-free camera, microphone, device access.

<video autoplay controls></video>
<input type="button" value="⚫" onclick="record(this)" id="start">
<input type="button" value="◼" onclick="stop(this)" id="stop" disabled>
var localMediaStream, recorder;

var record = function(button) {
  recorder = mediaStream.recorder();
};

var stop = function(button) {
  mediaStream.stop();
  recorder.getRecordedData(function(blob) {
    // Upload blob using XHR2.
  });
};

window.navigator.getUserMedia('video', function(stream) {
  document.querySelector('video').src = window.URL.createObjectURL(stream);
  localMediaStream = stream;
}, function(e) {
  console.log(e);
});

Fullscreen content

<video width="300" src="movie.webm" controls></video>
<button onclick="enterFullscreen()">Get Huge!</button>
function enterFullscreen() {
  var elem = document.querySelector('body');
  elem.onwebkitfullscreenchange = function(e) {
    console.log("Entered fullscreen!");
    elem.onwebkitfullscreenchange = onFullscreenExit;
  };
  elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}

Demo

Fullscreen API

Control of the entire document and elements:

document.webkitIsFullScreen ( bool )
document.webkitCurrentFullScreenElement ( DOMElement )
document.webkitFullScreenKeyboardInputAllowed ( bool )
document.webkitCancelFullScreen();
Element.webkitRequestFullScreen(); // Element.webkitRequestFullScreenWithKeys();

Control of media elements:

MediaElement.webkitSupportsFullscreen ( bool )
MediaElement.webkitDisplayingFullscreen ( bool )
MediaElement.webkitEnterFullScreen()
MediaElement.webkitExitFullScreen()

New pseudo-classes, and attributes:

Web RTC

What's the problem?

The demand for RTC is real!

GMail Video Chat
Google Plus Hangout
Facebook Video Chat
Tokbox

...all browser based. All requiring a special download or Flash

What is WebRTC?

high quality real-time voice/video communication in the browser


Architecture

Example

var pc = new PeerConnection('STUN example.com:8000', onSignalingMessage);

function onSignalingMessage(msg, source) {
  // send message to the other side via the signaling channel.
  pc.processSignalingMessage(msg);
}

pc.onaddstream = function(e) {
  remoteVideo.src = window.webkitURL.createObjectURL(e.stream);
};

pc.onremovestream = function(e) {
  video.src = '';
};

window.navigator.webkitGetUserMedia('video,audio', function(localStream) {
  localVideo.src = window.webkitURL.createObjectURL(localStream);
  pc.addStream(localStream); // Start sending video
}, function(e) { ... });

Build the future...

Robot

Community effort

Web Audio API

Don't we already have HTML5 <audio>?

Scheduled playback

var ctx = new window.webkitAudioContext();

function playSound(arrayBuffer) { // Obtain arrayBuffer from XHR2.
  ctx.decodeAudioData(arrayBuffer, function(buffer) {
    var src = ctx.createBufferSource();
    src.buffer = buffer;
    src.loop = false;
    src.connect(ctx.destination);
    src.noteOn(0); // Play immediately.
  }, function(e) {
    console.log(e);
  });
}

Shoot:

Generating sound

var sine = new Oscillator(DSP.SINE, 440, 1.0, 2048, 44100).generate(); // dsp.js

var src = ctx.createBufferSource();
src.buffer = ctx.createBuffer(1 /*channels*/, 2048, 44100);
src.buffer.getChannelData(0).set(sine);
src.loop = true;

src.connect(ctx.destination);
src.noteOn(0);

Sound Toy

Demo

Audio processing

var ctx = new webkitAudioContext();
var analyser = ctx.createAnalyser();

function initAudio(arrayBuffer) {
  ctx.decodeAudioData(arrayBuffer, function(buffer) {
    var src = ctx.createBufferSource();
    src.buffer = buffer;
    src.connect(analyser); // src -> analyser -> destination
    analyser.connect(ctx.destination);
    render(src);
  }, function(e) {
    console.log('Error decoding audio file', e);
  });
}

function render(src) {
  (function callback(timeStamp) {
    var byteData = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(byteData);

    // draw byteData to <canvas> visualization...

    window.requestAnimationFrame(callback, src);
  })();
}

That was a lot!

chromestatus.com

updates.html5rocks.com

Chrome Frame

Meta tag:

<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">

Header:

X-UA-Compatible: IE=Edge,chrome=1

Resources



Thanks! Questions?

@   +