Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PWA-Bootcamp: von 0 auf MS Paint (hands-on)

PWA-Bootcamp: von 0 auf MS Paint (hands-on)

Progressive Web Apps sind ein plattformübergreifend einsetzbares Anwendungsmodell auf Web-Basis. Dank Project Fugu, einer Initiative der Chrome-Contributors Google, Microsoft und Intel, wird das Web um noch mächtigere Features erweitert. In diesem Bootcamp zeigt Ihnen Christian Liebel von Thinktecture, wie Sie in nur einem halben Tag eine vereinfachte Version von Paint implementieren und auf Ihrem Gerät installieren können – inklusive Dateisystemzugriff. Bitte bringen Sie Ihr Notebook (ohne Corporate-Proxys/Unternehmensrichtlinien) mit installiertem Google Chrome Canary und Microsoft Visual Studio Code mit.

Christian Liebel

October 27, 2020
Tweet

More Decks by Christian Liebel

Other Decks in Programming

Transcript

  1. Hello, it’s me. PWA Bootcamp Von 0 auf MS Paint

    Christian Liebel Twitter: @christianliebel Email: christian.liebel @thinktecture.com Angular & PWA Slides: thinktecture.com /christian-liebel
  2. Things NOT to expect - Blueprint for PWA development -

    No AuthN/AuthZ Things To Expect - Extensive/up-to-date insights into PWA and Project Fugu - A productivity app use case that works on your desktop & smartphone - Lots of fun - Hands-on exercises Von 0 auf MS Paint PWA Bootcamp
  3. https://paint.js.org – Productivity app – Draw images – Lots of

    actions & tools – Installable – Read/save files – Copy/paste images from/to clipboard – Share files to other apps – Register for file extensions PWA Bootcamp Von 0 auf MS Paint Demo Use Case
  4. (Workshop Edition) – Productivity app – Draw images – Lots

    of actions & tools – Installable – Read/save files – Copy/paste images from/to clipboard – Share files to other apps – Register for file extensions PWA Bootcamp Von 0 auf MS Paint Demo Use Case
  5. Canvas – Plain bitmap for the web – Cross-platform, hardware-

    accelerated graphics operations – Supports different contexts (2D, 3D: WebGL, WebGL 2.0) – Supported on all evergreen browsers and on IE 9+ PWA Bootcamp Von 0 auf MS Paint Paint
  6. Canvas Add a canvas element to index.html (line 11): <canvas

    id="canvas" width="600" height="480"></canvas> Query the canvas element in app.js (line 1): const canvas = document.querySelector('#canvas'); PWA Bootcamp Von 0 auf MS Paint Paint LAB
  7. Canvas 2D Context fillRect(x, y, width, height) strokeRect(x, y, width,

    height) beginPath() moveTo(x, y) lineTo(x, y) fill() stroke() PWA Bootcamp Von 0 auf MS Paint Paint
  8. Canvas 2D Context Get the 2D context and prepare the

    canvas in app.js: const canvas = document.querySelector('#canvas'); const ctx = canvas.getContext('2d'); ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'black'; PWA Bootcamp Von 0 auf MS Paint Paint LAB
  9. Low-latency Rendering PWA Bootcamp Von 0 auf MS Paint Paint

    Web pages need to synchronize with the DOM on graphics updates causing latencies that can make drawing difficult Low-latency rendering skips syncing with the DOM with can lead to a more natural experience Supported on Chrome (Chrome OS and Windows only)
  10. Low-latency Rendering Opt-in to low-latency rendering (app.js): const ctx =

    canvas.getContext('2d', { desynchronized: true }); PWA Bootcamp Von 0 auf MS Paint Paint LAB
  11. Pointer Events PWA Bootcamp Von 0 auf MS Paint Paint

    Users nowadays use different input methods, cross-platform apps should cover all of them Pointer Events offer an abstract interface to catch all input methods (pointerdown, pointermove, pointerup) event.offsetX/event.offsetY contain the pointer’s position relative to the listener
  12. Pointer Events Add event listeners (bottom of app.js): canvas.addEventListener('pointerdown', event

    => {}); canvas.addEventListener('pointermove', event => { // ~~ is the shorter Math.floor() ctx.fillRect(~~event.offsetX, ~~event.offsetY, 2, 2); }); canvas.addEventListener('pointerup', () => {}); PWA Bootcamp Von 0 auf MS Paint Paint LAB
  13. Bresenham Line Algorithm The user may move faster than the

    input can be processed For this case, we need to remember the previous point and interpolate the points in between The Bresenham line algorithm calculates the missing pixels between two given points PWA Bootcamp Von 0 auf MS Paint Paint
  14. Bresenham Line Algorithm 1. Add the following import to the

    top of app.js (“.js” is required, otherwise the request will 404): import {bresenhamLine} from "./helpers.js"; 2. Then, adjust the event listeners: let previousPoint = null; canvas.addEventListener('pointerdown', event => { previousPoint = { x: ~~event.offsetX, y: ~~event.offsetY }; }); PWA Bootcamp Von 0 auf MS Paint Paint LAB
  15. Bresenham Line Algorithm canvas.addEventListener('pointermove', event => { if (previousPoint) {

    const currentPoint = { x: ~~event.offsetX, y: ~~event.offsetY }; for(const point of bresenhamLine(previousPoint.x, previousPoint.y, currentPoint.x, currentPoint.y)) { ctx.fillRect(point.x, point.y, 2, 2); } previousPoint = currentPoint; } }); canvas.addEventListener('pointerup', () => { previousPoint = null; }); PWA Bootcamp Von 0 auf MS Paint Paint LAB
  16. Von 0 auf MS Paint PWA Bootcamp Responsive Linkable Discoverable

    Installable App-like Connectivity Independent Fresh Safe Re-engageable Progressive
  17. Web App Manifest Distinguishes Web Apps from Websites JSON-based file

    containing metadata for apps only Apps can be identified by search engines, app store providers, etc. PWA Bootcamp Von 0 auf MS Paint PWA
  18. manifest.webmanifest { "short_name": "Paint", "name": "Paint Workshop", "theme_color": "white", "icons":

    [{ "src": "icon.png", "sizes": "512x512" }], "start_url": "/index.html", "display": "standalone", "shortcuts": [/* … */] } PWA Bootcamp Von 0 auf MS Paint PWA Names Icons Display Mode Shortcuts Start URL Theme color (status bar/window bar)
  19. Manifest Display Modes PWA Bootcamp Von 0 auf MS Paint

    PWA browser minimal-ui standalone fullscreen
  20. Manifest Icon Purposes (any) any context (e.g. app icon) monochrome

    different color requirements (at risk) maskable user agent masks icon as required PWA Bootcamp Von 0 auf MS Paint PWA Safe Zone Windows iOS Android
  21. Web App Manifest 1. In index.html, add the following tag

    to the document’s <head> node (e.g., after the stylesheet): <link rel="manifest" href="manifest.webmanifest"> 2. Create the new file manifest.webmanifest and set: a) name and short_name to values of your choice b) display to standalone c) theme_color to #000080 and background_color to #808080 d) start_url to /index.html and scope to / e) icons to [{ src: "icon.png", sizes: "512x512" }] 3. Test manifest in DevTools: F12 > Application > Manifest PWA Bootcamp Von 0 auf MS Paint PWA LAB
  22. Manifest Shortcuts PWA Bootcamp Von 0 auf MS Paint PWA

    Secondary entrypoints for your application (e.g., home screen quick actions, jump lists, …) Static definition in Web App Manifest Dynamic API may follow in the future Supported by Google Chrome for Android
  23. Web App Manifest – Chrome Installability Signals Web App is

    not already installed Meets a user engagement heuristic (previously: user has interacted with domain for at least 30 seconds) Includes a Web App Manifest that has short_name or name, at least a 192px and 512px icon, a start_url and a display mode of fullscreen, standalone or minimal-ui Served over HTTPS Has a registered service worker with a fetch event handler PWA Bootcamp Von 0 auf MS Paint PWA
  24. Service Worker JavaScript snippet executed in an own thread, registered

    by the website Acts as a controller, proxy, or interceptor Has a cache to store responses (for offline availability and performance) Can wake up even when the website is closed and perform background tasks (e.g., push notifications or sync) PWA Bootcamp Von 0 auf MS Paint PWA
  25. Service Worker PWA Bootcamp Von 0 auf MS Paint PWA

    Service Worker Internet Website HTML/JS Cache fetch
  26. Workbox Toolchain by Google Includes a CLI Generates a service

    worker implementation from directory contents (e.g., build output, or our development directory) Allows you to modify the service worker behavior (maximum flexibility) PWA Bootcamp Von 0 auf MS Paint PWA
  27. Service Worker 1. In your console, run: a) npm run

    workbox wizard (use “src” as project root and defaults for the rest) b) npm run workbox generateSW 2. In index.html, add the following script to the bottom of the <body> node: <script> if (navigator.serviceWorker) { navigator.serviceWorker.register('sw.js'); } </script> 3. Test in DevTools: F12 > Application > Service Worker 4. Install the app: Address Bar > ⊕ Install PWA Bootcamp Von 0 auf MS Paint PWA LAB
  28. Service Worker Debugging More information on installed service workers can

    be found on • chrome://serviceworker- internals (Google Chrome) • about:serviceworkers (Mozilla Firefox) PWA Bootcamp Von 0 auf MS Paint PWA
  29. Lighthouse PWA Bootcamp Von 0 auf MS Paint PWA Auditing

    tool by Google, integrated in Chrome DevTools Automatically checks performance metrics, PWA support, accessibility, SEO and other best practices and gives tips on how to improve Can simulate mobile devices
  30. Lighthouse 1. Make sure only one tab/window of your PWA

    is open 2. Open DevTools: F12 > Lighthouse 3. Make sure to select at least the “Progressive Web App” category 4. Click “Generate report” PWA Bootcamp Von 0 auf MS Paint PWA LAB
  31. Project Fugu PWA Bootcamp Von 0 auf MS Paint Capabilities

    »Let’s bring the web back – API by API« Thomas Steiner, Google
  32. PWA Bootcamp Von 0 auf MS Paint Capabilities Contacts Picker

    Screen Wake Lock API File System Access API Shape Detection API
  33. PWA Bootcamp Von 0 auf MS Paint Capabilities navigator.share({ url:

    'http://example.com' }); ShareIntent DataTransferManager … NSSharingServicePicker
  34. File System Access API Some applications heavily rely on working

    with files (e.g. Visual Studio Code, Adobe Photoshop, …) File System Access API allows you to open, save and override files and directories Shipped with Google Chrome 86 PWA Bootcamp Von 0 auf MS Paint Capabilities
  35. File System Access API 1. Add the following buttons to

    the <nav> bar in index.html: <button id="open">Open</button> <button id="save">Save</button> <button id="copy">Copy</button> <button id="paste">Paste</button> <button id="share">Share</button> PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  36. File System Access API 2. At the top of app.js,

    change the import as follows: import {bresenhamLine, getImage, toBlob} from "./helpers.js"; 3. Add the following lines at the bottom of app.js: const fileOptions = { types: [{ description: 'PNG files', accept: {'image/png': ['.png']} }] }; PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  37. File System Access API 4. Add the following lines at

    the bottom of app.js: const btnSave = document.querySelector('#save'); btnSave.addEventListener('click', async () => { const blob = await toBlob(canvas); const handle = await window.showSaveFilePicker(fileOptions); const writable = await handle.createWritable(); await writable.write(blob); await writable.close(); }); PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  38. File System Access API Add the following code at the

    end of app.js: const btnOpen = document.querySelector('#open'); btnOpen.addEventListener('click', async () => { const [handle] = await window.showOpenFilePicker(fileOptions); const file = await handle.getFile(); const image = await getImage(file); ctx.drawImage(image, 0, 0); }); PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  39. Async Clipboard API Allows reading from/writing to the clipboard in

    an asynchronous manner (UI won’t freeze during long-running operations) Reading from the clipboard requires user consent first (privacy!) Supported by Chrome, Edge and Safari PWA Bootcamp Von 0 auf MS Paint Capabilities
  40. Async Clipboard API Add the following code at the end

    of app.js: const btnCopy = document.querySelector('#copy'); btnCopy.addEventListener('click', async () => { const blob = await toBlob(canvas); await navigator.clipboard.write([ new ClipboardItem({[blob.type]: blob}) ]); }); PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  41. Async Clipboard API const btnPaste = document.querySelector('#paste'); btnPaste.addEventListener('click', async ()

    => { const clipboardItems = await navigator.clipboard.read(); for (const clipboardItem of clipboardItems) { for (const type of clipboardItem.types) { if (type === 'image/png') { const blob = await clipboardItem.getType(type); const image = await getImage(blob); ctx.drawImage(image, 0, 0); } } } }); PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  42. Web Share API Allows sharing a title, URL, text, or

    files API can only be invoked as a result of a user action (i.e. a click or keypress) Files supported in Chrome on Android, Edge on Windows PWA Bootcamp Von 0 auf MS Paint Capabilities
  43. Web Share API const btnShare = document.querySelector('#share'); btnShare.disabled = !('canShare'

    in navigator); btnShare.addEventListener('click', async () => { const blob = await toBlob(canvas); const file = new File([blob], 'untitled.png', {type: 'image/png'}); const item = {files: [file], title: 'untitled.png'}; if (await navigator.canShare(item)) { await navigator.share(item); } }); PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  44. File System Handling API Register your PWA as a handler

    for file extensions Requires installing the application first Declare supported extensions in Web App Manifest and add imperative code to your application logic PWA Bootcamp Von 0 auf MS Paint Capabilities
  45. File System Handling API 1. Enable the following flag in

    Chrome Canary and restart the browser: chrome://flags/#file-handling-api 2. Add the following property to your manifest (manifest.webmanifest): "file_handlers": [{ "action": "/index.html", "accept": { "image/png": [".png"] } }] PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  46. File System Handling API 3. Add the following code to

    the bottom of app.js: if ('launchQueue' in window) { launchQueue.setConsumer(async params => { const [handle] = params.files; if (handle) { const file = await handle.getFile(); const image = await getImage(file); ctx.drawImage(image, 0, 0); } }); } 4. Re-generate Service Worker: npm run workbox generateSW PWA Bootcamp Von 0 auf MS Paint Capabilities LAB
  47. Overview Use available interfaces and functions of a system (opposite

    of Graceful Degradation) Users with modern, feature-rich browsers get a better experience Apps are available on older browsers, but with limited functionality Concept: Browser feature support should grow over time—thereby more users can enjoy an increasing number of features PWA Bootcamp Von 0 auf MS Paint Progressive Enhancement
  48. Overview if ('serviceWorker' in navigator) { navigator.serviceWorker.register(…) .then(() => /*

    … */); } In JavaScript: check whether an API/feature is available. If yes—use it! Otherwise: 1. Disable the functionality 2. Fall back to an alternative API (if available) PWA Bootcamp Von 0 auf MS Paint Progressive Enhancement
  49. Disabling unsupported features In app.js, disable the buttons in case

    the respective API does not exist, e.g.: btnOpen.disabled = !('showOpenFilePicker' in window); 1. Open: window.showOpenFilePicker() 2. Save: window.showSaveFilePicker() 3. Copy: navigator.clipboard + navigator.clipboard.read() 4. Paste: navigator.clipboard + navigator.clipboard.write() 5. Share: navigator.canShare() PWA Bootcamp Von 0 auf MS Paint Progressive Enhancement LAB
  50. New powerful APIs regularly ship with new releases of Chromium-based

    browsers Some only add minor finishing touches, others enable whole application categories as productivity apps to finally make the shift to the web Some APIs already made their way into other browsers (e.g., Web Share) Fugu process makes sure that capabilities are implemented in a secure, privacy-preserving manner Let’s make the web a more capable platform! PWA Bootcamp Von 0 auf MS Paint Summary