• Save
Building HTML5 Tablet Apps for iOS and Android
Upcoming SlideShare
Loading in...5
×
 

Building HTML5 Tablet Apps for iOS and Android

on

  • 61,271 views

 

Statistics

Views

Total Views
61,271
Views on SlideShare
60,305
Embed Views
966

Actions

Likes
111
Downloads
0
Comments
5

34 Embeds 966

http://abava.blogspot.com 213
http://labs.voronenko.com 184
http://minnewebcon.org 117
http://10.0.0.161 99
http://dvlbase.blogspot.com 74
http://labs.voronenko.info 59
https://si0.twimg.com 35
https://twimg0-a.akamaihd.net 23
http://bunupaylas.com 22
http://upknownow.blogspot.com 22
http://abava.blogspot.ru 20
http://www.scoop.it 16
http://www.dvlbase.blogspot.com 12
http://www.techgig.com 11
http://abava.blogspot.co.uk 11
http://localhost 9
http://minnewebcon.net 7
http://www.powerbeam.host22.com 6
http://faavorite.com 4
http://192.168.137.87 3
https://twitter.com 3
http://www.verious.com 2
http://abava.blogspot.gr 2
http://a0.twimg.com 2
https://www.google.ru 1
http://translate.googleusercontent.com 1
http://abava.blogspot.com.es 1
http://us-w1.rockmelt.com 1
http://dvlbase.blogspot.com.es 1
http://www.bettiblue.com 1
http://www.bunupaylas.com 1
http://abava.blogspot.in 1
http://www.tumblr.com 1
http://abava.blogspot.fr 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

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

Building HTML5 Tablet Apps for iOS and Android Building HTML5 Tablet Apps for iOS and Android Presentation Transcript

  • Building HTML5Tablet Appsfor iOS and Android@skirchmeier@mikebollingerMINNEWEBCON 2012
  • The elephant in the room:!HTML5 apps kinda suck.
  • Native vs. HTML5
  • Native HTML5-- Expensive to develop + Cheaper to develop-- One platform at a time + All platforms at a time+ Snappy -- Slower+ Refined (true native feel) -- Unrefined+ Full featured -- Limited features
  • Reasons
  • 1Money
  • 2Time
  • 3Audience
  • 4Control
  • 1 2 3 4Money Time Audience Control
  • 5 T A B L E T S   H A V E   F L E X I B L E  Design Patterns
  • 1 2 3 4Money Time Audience Control 5 Flexible Design Patterns
  • Change the game.
  • Examples
  • Best Buyhttp://bby-uv.appspot.com/ Financial Times http://app.ft.com Proof http://proofwhisky.com
  • Best Buy http://bby-uv.appspot.com/iOS Only >! Financial Times http://app.ft.comiOS Only >! Proof http://proofwhisky.com
  • Frameworks
  • jQuery Mobile jQTouch Sencha Touch
  • Native Wrappers
  • PhoneGap Titanium
  • Our Custom App
  • http://livefront.com/explore
  • How do we build this?
  • Step 1:Travel the world
  • Step 2:HTML (sorry)
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • <div id="content" class="page"> <div id="map"></div> <div id="photos"> <div id="slides-container"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <section id="slide-info"> <h1></h1> <div id="slide-details"> <p></p> <p class="location"></p> </div> </section> </div></div>
  • <div id="content" class="page"> <div id="map"></div> <div id="photos"> <div id="slides-container"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <section id="slide-info"> <h1></h1> <div id="slide-details"> <p></p> <p class="location"></p> </div> </section> </div></div>
  • <div id="content" class="page"> <div id="map"></div> <div id="photos"> <div id="slides-container"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <section id="slide-info"> <h1></h1> <div id="slide-details"> <p></p> <p class="location"></p> </div> </section> </div></div>
  • <div id="content" class="page"> <div id="map"></div> <div id="photos"> <div id="slides-container"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <section id="slide-info"> <h1></h1> <div id="slide-details"> <p></p> <p class="location"></p> </div> </section> </div></div>
  • <!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • Techniques
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Transitions Two ways to animate: 1. jQuery (.animate) 2. CSS (-webkit-transform)  
  • Transitions Two ways to animate: 1. jQuery (.animate) 2. CSS (-webkit-transform)  
  • TransitionsWhat can we do with CSS?
  • Transitions -webkit-transform translate scale skew rotate -webkit-animation
  • Transitions -webkit-transform translate scale skew rotate -webkit-animation
  • Transitions<!DOCTYPE html><html> <head> ... </head> <body> <div id="container"> <div id="splash" class="page"> ... </div> <div id="content" class="page"> ... </div> </div> </body></html>
  • Transitions div#splash div#content -webkit-transform: translate3d(100%, 0, 0);
  • Transitions div#splash div#content-webkit-transition: -webkit-transform: all 600ms ease-in-out; translate3d(100%, 0, 0);-webkit-transform: translate3d(0, 0, 0);  
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Touch EventsHow touch events work
  • Touch Events Touch Multi-Touch GestureiOS P P PAndroid 2.3 PAndroid 3 P PAndroid 4 P P
  • Touch Events Touch Multi-Touch GestureiOS P P PAndroid 2.3 PAndroid 3 P PAndroid 4 P P
  • Touch Events touchstart touchmove touchend touchcancel
  • Touch Eventsslides.bind(touchstart, function (e) { if (touchId !== null) { e.stopPropagation(); e.preventDefault(); } else { var touch = e.originalEvent.touches[0]; touchId = touch.identifier; touchStart(touch.clientX); }});
  • Touch Eventsslides.bind(touchstart, function (e) { if (touchId !== null) { e.stopPropagation(); e.preventDefault(); } else { var touch = e.originalEvent.touches[0]; touchId = touch.identifier; touchStart(touch.clientX); }});
  • Touch Eventsslides.bind(touchstart, function (e) { if (touchId !== null) { e.stopPropagation(); e.preventDefault(); } else { var touch = e.originalEvent.touches[0]; touchId = touch.identifier; touchStart(touch.clientX); }});
  • Touch Eventsslides.bind(touchstart, function (e) { if (touchId !== null) { e.stopPropagation(); e.preventDefault(); } else { var touch = e.originalEvent.touches[0]; touchId = touch.identifier; touchStart(touch.clientX); }});
  • Touch Eventsslides.bind(touchmove, function (e) { var touch = e.originalEvent.touches[0]; if (touch.identifier == touchId) { touchMove(touch.clientX); }});
  • Touch Eventsslides.bind(touchend, function (e) { var touch = e.originalEvent.changedTouches[0]; if (touch.identifier == touchId) { touchEnd(touch.clientX); }});
  • Touch Eventsfunction touchEnd(x) { ... if (Math.abs(deltaX) > threshold) { swipe(direction); } else if (Math.abs(deltaX) >Config.slideshowSwipeDistanceThreshold &&touchDuration <Config.slideshowSwipeDurationThreshold) { swipe(direction); } else { snapBack(); }}
  • Touch Eventsfunction touchEnd(x) { ... if (Math.abs(deltaX) > threshold) { swipe(direction); } else if (Math.abs(deltaX) >Config.slideshowSwipeDistanceThreshold &&touchDuration <Config.slideshowSwipeDurationThreshold) { swipe(direction); } else { snapBack(); }}
  • Touch Eventsfunction touchEnd(x) { ... if (Math.abs(deltaX) > threshold) { swipe(direction); } else if (Math.abs(deltaX) >Config.slideshowSwipeDistanceThreshold &&touchDuration <Config.slideshowSwipeDurationThreshold) { swipe(direction); } else { snapBack(); }}
  • Touch Eventsfunction touchEnd(x) { ... if (Math.abs(deltaX) > threshold) { swipe(direction); } else if (Math.abs(deltaX) >Config.slideshowSwipeDistanceThreshold &&touchDuration <Config.slideshowSwipeDurationThreshold) { swipe(direction); } else { snapBack(); }}
  • Touch Eventsfunction touchEnd(x) { ... if (Math.abs(deltaX) > threshold) { swipe(direction); } else if (Math.abs(deltaX) >Config.slideshowSwipeDistanceThreshold &&touchDuration <Config.slideshowSwipeDurationThreshold) { swipe(direction); } else { snapBack(); }}
  • Touch Events<div id="content" class="page"> <div id="map"></div> <div id="photos"> <div id="slides-container"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <section id="slide-info"> <h1></h1> <div id="slide-details"> <p></p> <p class="location"></p> </div> </section> </div></div>
  • Touch Events
  • Touch Events div#slides-containerdiv.slide div.slide div.slide
  • Touch Events div#slides-containerdiv.slide div.slide div.slide
  • Touch EventsGotcha #1: Android browser
  • Touch EventsGotcha #1: Android browser
  • Touch EventsGotcha #1: Android browser <img> vs. background-image
  • Touch EventsGotcha #2: Mobile Safari Bounce $(document).bind(touchmove’, function(event){ event.preventDefault(); });
  • Touch EventsGotcha #3: Testing on Desktop var hasTouch = ontouchstart in document.documentElement; var touchstart = hasTouch ? touchstart : mousedown; var touchmove = hasTouch ? touchmove : mousemove; var touchend = hasTouch ? touchend : mouseup;
  • Touch EventsGotcha #4: Click Events are Slow Click Event vs. Touch Event
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Hardware (GPS) JS - iOS JS - Android PhoneGapAccelerometer P PCompass P PGyroscope P PCamera PContacts PLocal Storage P P PGeolocation P P PNotifications P
  • Hardware (GPS) JS - iOS JS - Android PhoneGapAccelerometer P PCompass P PGyroscope P PCamera PContacts PLocal Storage P P PGeolocation P P PNotifications P
  • Hardware (GPS)
  • Hardware (GPS)function displayCurrentLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function (position) { var lat = position.coords.latitude; var lng = position.coords.longitude; ... // Display lat/lng } ); } };
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Work Offline Local Storage
  • Work Offline Gotcha: 5mb
  • Work Offlinevar hasLocalStorage = (function () { try { localStorage.setItem(test, test); localStorage.removeItem(test); return true; } catch(e) { return false; }})();
  • Work Offlinevar localStoragePhotoData = null;if (hasLocalStorage) { localStoragePhotoData = localStorage.getItem(key);}if (localStoragePhotoData === null) { if (hasLocalStorage) { // Save photo data to localStorage. var photoDataString = JSON.stringify(PhotoData); localStorage.setItem(key); ... }} else { // Use photo data cached in localStorage. var photoDataObject = JSON.parse(localStoragePhotoData); ...}
  • Work Offlinevar localStoragePhotoData = null;if (hasLocalStorage) { localStoragePhotoData = localStorage.getItem(key);}if (localStoragePhotoData === null) { if (hasLocalStorage) { // Save photo data to localStorage. var photoDataString = JSON.stringify(PhotoData); localStorage.setItem(key); ... }} else { // Use photo data cached in localStorage. var photoDataObject = JSON.parse(localStoragePhotoData); ...}
  • Work Offlinevar localStoragePhotoData = null;if (hasLocalStorage) { localStoragePhotoData = localStorage.getItem(key);}if (localStoragePhotoData === null) { if (hasLocalStorage) { // Save photo data to localStorage. var photoDataString = JSON.stringify(PhotoData); localStorage.setItem(key); ... }} else { // Use photo data cached in localStorage. var photoDataObject = JSON.parse(localStoragePhotoData); ...}
  • Work Offlinevar localStoragePhotoData = null;if (hasLocalStorage) { localStoragePhotoData = localStorage.getItem(key);}if (localStoragePhotoData === null) { if (hasLocalStorage) { // Save photo data to localStorage. var photoDataString = JSON.stringify(PhotoData); localStorage.setItem(key); ... }} else { // Use photo data cached in localStorage. var photoDataObject = JSON.parse(localStoragePhotoData); ...}
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Sizing Support different screens Handle rotation Hide browser chrome Disable zoomDisable other browser features
  • SizingSupport different screens Easier in HTML than native % based layouts background-size: cover; Absolute positioning is often necessary
  • SizingHandle rotation $(window).resize(doSomething);
  • SizingHandle rotation $(window).resize(reposition);
  • SizingHandle rotation Gotcha: You get notification after rotation is complete
  • SizingHide browser chrome <meta name="apple-mobile-web-app-capable" content="yes" />
  • SizingDisable zoom <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0" />
  • SizingDisable other browser features /* turn off default press states */ -webkit-tap-highlight-color: transparent; /* disable save image on long press */ -webkit-touch-callout: none; /* disable selection copy/paste */ -webkit-user-select: none; /* disable dragging images */ -webkit-user-drag: none;
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Distribution
  • DistributionTwo ways to distribute:1. Web only Reminder to bookmark2. App gallery Custom native wrapper Framework like PhoneGap  
  • DistributionTwo ways to distribute:1. Web only Reminder to bookmark2. App gallery Custom native wrapper Framework like PhoneGap  
  • Distributionhttps://github.com/cubiq/ add-to-homescreen
  • Distribution
  • Distribution<link rel="stylesheet" href="styles/ add2home.css"><script type="application/javascript" src="scripts/external/add2home.js"></script>
  • Distribution Home Screen Icon
  • Distribution 144 x 144
  • Distribution<link rel="apple-touch-icon" href="icon.png"/>
  • Transitions Work OfflineTouch Events SizingHardware (GPS) Distribution
  • Go explore.
  • Thanks!@skirchmeier@mikebollingerMINNEWEBCON 2012
  • APP:http://livefront.com/explore SOURCE CODE:http://github.com/livefront/minnewebcon2012-explore SLIDES:http://slideshare.net/livefront