Slide 1

Slide 1 text

Making of paint.js.org A Web Component-based Productivity PWA Christian Liebel @christianliebel Consultant

Slide 2

Slide 2 text

Hello, it’s me. Making of paint.js.org A Web Component-based Productivity PWA Christian Liebel Twitter: @christianliebel Email: christian.liebel @thinktecture.com Angular & PWA Slides: thinktecture.com /christian-liebel

Slide 3

Slide 3 text

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 Making of paint.js.org A Web Component-based Productivity PWA Demo

Slide 4

Slide 4 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 5

Slide 5 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 6

Slide 6 text

Web Components – The web’s native component model – Easy interop – Very basic: No data binding, dependency injection, … Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 7

Slide 7 text

Related APIs Custom Elements API Definition of custom HTML elements Interaction via custom DOM attributes, properties, and events Shadow DOM Can prevent DOM access from outside Can prevent CSS manipulation from outside HTML Templates (not used in this demo) Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 8

Slide 8 text

Lit – Provided by Google – Lightweight library (5 KB) – Custom lifecycle on top of Web Components – Tagged template literals for HTML and CSS to prevent XSS attacks including support for data binding – TypeScript decorators for component registration and attribute/property declaration Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 9

Slide 9 text

Lit @customElement('paint-tool-box') export class ToolBox { render(): TemplateResult { return html` ${tools.map( (tool) => html` this.selectTool(tool)}" >`, )} `; } } Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 10

Slide 10 text

Web Components Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 11

Slide 11 text

Store Pattern Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 12

Slide 12 text

Embedded https://node-projects.github.io/web-component-designer-demo/index.html Making of paint.js.org A Web Component-based Productivity PWA Web Components and Architecture

Slide 13

Slide 13 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 14

Slide 14 text

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+ Making of paint.js.org A Web Component-based Productivity PWA Canvas and Input

Slide 15

Slide 15 text

Canvas 2D Context fillRect(x, y, width, height) strokeRect(x, y, width, height) beginPath() moveTo(x, y) lineTo(x, y) fill() stroke() Making of paint.js.org A Web Component-based Productivity PWA Canvas and Input

Slide 16

Slide 16 text

Pointer Events Making of paint.js.org A Web Component-based Productivity PWA Canvas and Input 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

Slide 17

Slide 17 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 18

Slide 18 text

A Web Component-based Productivity PWA Making of paint.js.org Responsive Linkable Discoverable Installable App-like Connectivity Independent Fresh Safe Re-engageable Progressive

Slide 19

Slide 19 text

Making of paint.js.org A Web Component-based Productivity PWA Web App Manifest Service Worker

Slide 20

Slide 20 text

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. Making of paint.js.org A Web Component-based Productivity PWA Offline Capability and Installability

Slide 21

Slide 21 text

manifest.webmanifest { "short_name": "Paint", "name": "Paint Workshop", "theme_color": "white", "icons": [{ "src": "icon.png", "sizes": "512x512" }], "start_url": "/index.html", "display": "standalone", "shortcuts": [/* … */] } Making of paint.js.org A Web Component-based Productivity PWA Offline Capability and Installability Names Icons Display Mode Shortcuts Start URL Theme color (status bar/window bar)

Slide 22

Slide 22 text

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) Making of paint.js.org A Web Component-based Productivity PWA Offline Capability and Installability

Slide 23

Slide 23 text

Service Worker Making of paint.js.org A Web Component-based Productivity PWA Offline Capability and Installability Service Worker Internet Website HTML/JS Cache fetch

Slide 24

Slide 24 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 25

Slide 25 text

Making of paint.js.org A Web Component-based Productivity PWA

Slide 26

Slide 26 text

Project Fugu Making of paint.js.org A Web Component-based Productivity PWA Capabilities »Let’s bring the web back – API by API« Thomas Steiner, Google

Slide 27

Slide 27 text

Making of paint.js.org A Web Component-based Productivity PWA Capabilities https://goo.gle/fugu-api-tracker

Slide 28

Slide 28 text

Browser Making of paint.js.org A Web Component-based Productivity PWA Capabilities navigator.share({ url: 'http://example.com' }); ShareIntent DataTransferManager … NSSharingServicePicker

Slide 29

Slide 29 text

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 Making of paint.js.org A Web Component-based Productivity PWA Copy and Paste

Slide 30

Slide 30 text

Async Clipboard API const btnCopy = document.querySelector('#copy'); btnCopy.addEventListener('click', async () => { const blob = await toBlob(canvas); await navigator.clipboard.write([ new ClipboardItem({[blob.type]: blob}) ]); }); Making of paint.js.org A Web Component-based Productivity PWA Copy and Paste

Slide 31

Slide 31 text

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); } } } }); Making of paint.js.org A Web Component-based Productivity PWA Copy and Paste

Slide 32

Slide 32 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 33

Slide 33 text

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 Supported by Chrome, Edge Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 34

Slide 34 text

File System Access API 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(); }); Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 35

Slide 35 text

File System Access API 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); }); Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 36

Slide 36 text

File 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 Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 37

Slide 37 text

File Handling API "file_handlers": [{ "action": "/index.html", "accept": { "image/png": [".png"] } }] Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 38

Slide 38 text

File Handling API 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); } }); } Making of paint.js.org A Web Component-based Productivity PWA File Access and File Handling

Slide 39

Slide 39 text

Web Components and Architecture Canvas and Input Offline Capability and Installability Copy and Paste File Access and File Handling Dark Mode Making of paint.js.org A Web Component-based Productivity PWA Agenda

Slide 40

Slide 40 text

CSS Custom Properties – Also known as “CSS variables” – Cascade even through Shadow DOM boundaries, i.e. they can be accessed by subordinate components – Paint.js.org defines the Windows 95 color scheme on app root level :host { --button-face: rgb(192 192 192); --button-light: white; --button-dark: rgb(128 128 128); --button-darker: black; --button-text: black; } Making of paint.js.org A Web Component-based Productivity PWA Dark Mode

Slide 41

Slide 41 text

prefers-color-scheme CSS Media Feature – The prefers-color-scheme CSS media feature indicates which color scheme the user prefers – Takes two values: – light, if the user prefers a dark-on-light color scheme (or didn’t actively make a decision) – dark, if the user prefers a light-on-dark color scheme – Preference is usually inherited form the operating system’s settings – Changes are automatically reflected (e.g., when the operating system switches between light and dark mode based on time) Making of paint.js.org A Web Component-based Productivity PWA Dark Mode

Slide 42

Slide 42 text

CSS-Only Light Mode :host { --button-face: rgb(192 192 192); --button-light: white; --button-dark: rgb(128 128 128); --button-darker: black; --button-text: black; } Dark Mode @media (prefers-color-scheme: dark) { :host { --button-face: rgb(64 64 64); --button-light: rgb(128 128 128); --button-dark: rgb(32 32 32); --button-text: white; } } Making of paint.js.org A Web Component-based Productivity PWA Dark Mode

Slide 43

Slide 43 text

Making of paint.js.org A Web Component-based Productivity PWA Dark Mode

Slide 44

Slide 44 text

Web Components: Very robust, works consistently across evergreen browsers, perfect for integration scenarios. Lit: Shares basic concepts with other frameworks/libraries (such as Angular), but is much more lightweight. Paint.js.org is smaller (= transferred bytes) than the Windows 95 of Paint (320K)! Capabilities: Powerful APIs available on Chromium and WebKit-based browsers, fallbacks are used for other browsers. Conclusion: Successful project! 🥳 You can perfectly implement web- based (= cross-platform), desktop-class productivity applications. Making of paint.js.org A Web Component-based Productivity PWA Summary

Slide 45

Slide 45 text

Making of paint.js.org A Web Component-based Productivity PWA Outlook

Slide 46

Slide 46 text

Thank you for your kind attention! Christian Liebel @christianliebel [email protected]