Nuove possibilità in Chrome 65
L'API CSS Paint (nota anche come "CSS Custom Paint" o "Houdini's paint worklet") è attivate per impostazione predefinita a partire da Chrome 65. Che cos'è? Cosa puoi fare ? E come funziona? Continua a leggere...
L'API CSS Paint ti consente di generare in modo programmatico un'immagine ogni volta che un CSS
prevede un'immagine. Proprietà come background-image
o border-image
vengono generalmente utilizzati con url()
per caricare un file immagine o con CSS integrato
come linear-gradient()
. Invece di utilizzarli, ora puoi usare
paint(myPainter)
per fare riferimento a un worklet di colorazione.
Scrivere un worklet di colorazione
Per definire un worklet di colorazione denominato myPainter
, dobbiamo caricare un worklet CSS
utilizzando CSS.paintWorklet.addModule('my-paint-worklet.js')
. In questo
possiamo utilizzare la funzione registerPaint
per registrare una classe di worklet di colorazione:
class MyPainter {
paint(ctx, geometry, properties) {
// ...
}
}
registerPaint('myPainter', MyPainter);
Nel callback paint()
, possiamo utilizzare ctx
nello stesso modo in cui
CanvasRenderingContext2D
come lo conosciamo da <canvas>
. Se sai come
disegna in un <canvas>
, puoi disegnare in un worklet! geometry
indica
e l'altezza della tela a nostra disposizione. properties
Lo farò
più avanti in questo articolo.
Come esempio introduttivo, passiamo a scrivere un foglio di lavoro sulla vernice a scacchiera e usarlo
come immagine di sfondo di un <textarea>
. (Uso un'area di testo perché
ridimensionabili per impostazione predefinita):
<!-- index.html -->
<!doctype html>
<style>
textarea {
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
paint(ctx, geom, properties) {
// Use `ctx` as if it was a normal canvas
const colors = ['red', 'green', 'blue'];
const size = 32;
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
const color = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x * size, y * size, size, size);
ctx.fill();
}
}
}
}
// Register our class under a specific name
registerPaint('checkerboard', CheckerboardPainter);
Se hai utilizzato <canvas>
in passato, il codice dovrebbe esserti familiare. Consulta
dal vivo
dimostrazione
qui.
La differenza rispetto all'utilizzo di un'immagine di sfondo comune in questo caso è che il motivo verrà ridisegnato su richiesta ogni volta che l'utente ridimensiona l'area di testo. Ciò significa l'immagine di sfondo sia sempre grande quanto deve essere, inclusa la di compensazione per i display ad alta densità.
Non male, ma è anche statico. Dovremmo scrivere un nuovo un worklet ogni volta che volevamo lo stesso motivo, ma con dimensioni diverse quadrati? La risposta è no.
Parametrizzazione del worklet
Fortunatamente, il worklet di colorazione può accedere ad altre proprietà CSS, dove è possibile
entra in gioco il parametro aggiuntivo properties
. Assegnando alla classe un'immagine
inputProperties
, puoi iscriverti alle modifiche a qualsiasi proprietà CSS,
incluse le proprietà personalizzate. I valori ti verranno forniti tramite
Parametro properties
.
<!-- index.html -->
<!doctype html>
<style>
textarea {
/* The paint worklet subscribes to changes of these custom properties. */
--checkerboard-spacing: 10;
--checkerboard-size: 32;
background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
// inputProperties returns a list of CSS properties that this paint function gets access to
static get inputProperties() { return ['--checkerboard-spacing', '--checkerboard-size']; }
paint(ctx, geom, properties) {
// Paint worklet uses CSS Typed OM to model the input values.
// As of now, they are mostly wrappers around strings,
// but will be augmented to hold more accessible data over time.
const size = parseInt(properties.get('--checkerboard-size').toString());
const spacing = parseInt(properties.get('--checkerboard-spacing').toString());
const colors = ['red', 'green', 'blue'];
for(let y = 0; y < geom.height/size; y++) {
for(let x = 0; x < geom.width/size; x++) {
ctx.fillStyle = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.rect(x*(size + spacing), y*(size + spacing), size, size);
ctx.fill();
}
}
}
}
registerPaint('checkerboard', CheckerboardPainter);
Ora possiamo utilizzare lo stesso codice per tutti i diversi tipi di scacchiera. Ma anche meglio, ora possiamo entrare in DevTools e giocare sui valori fino a trovare il look giusto.
Browser che non supportano il worklet di colorazione
Al momento della stesura di questo documento, solo Chrome ha implementato il worklet Paint. Mentre eri in sono segnali positivi di tutti gli altri fornitori di browser, non ci sono molti progressi. Per restare al passo con gli aggiornamenti, controlla Is Houdini Ready Yet? regolarmente. Nel frattempo, assicurati di usare il formato progressivo miglioramento per mantenere il codice in esecuzione anche se non è supportato un worklet. Per assicurarti che tutto funzioni come previsto, devi modificare il codice in due posizioni: il CSS e il codice JS.
Il rilevamento del supporto del worklet di colorazione in JS può essere eseguito selezionando l'oggetto CSS
:
js
if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('mystuff.js');
}
Per quanto riguarda CSS, hai due opzioni. Puoi utilizzare @supports
:
@supports (background: paint(id)) {
/* ... */
}
Un trucco più compatto consiste nell'utilizzare il fatto che CSS invalida e successivamente ignora un'intera dichiarazione della proprietà se contiene una funzione sconosciuta. Se specifichi una proprietà due volte: prima senza il worklet Paint e poi con di colorazione, si ottiene un miglioramento progressivo:
textarea {
background-image: linear-gradient(0, red, blue);
background-image: paint(myGradient, red, blue);
}
Nei browser che supportano il worklet "paint", la seconda dichiarazione
background-image
sovrascriverà la prima. Nei browser senza supporto
per il worklet Paint, la seconda dichiarazione non è valida e verrà eliminata,
lasciando in vigore la prima dichiarazione.
Pittura CSS Polyfill
Per molti utilizzi, è anche possibile usare Polyfill per vernice CSS, che aggiunge il supporto CSS Custom Paint and Paints ai browser moderni.
Casi d'uso
Esistono molti casi d'uso per i worklet di pittura, alcuni dei quali più evidenti
altri. Una delle più evidenti è l'uso di un worklet di colorazione per ridurne le dimensioni
del DOM. Spesso, gli elementi vengono aggiunti esclusivamente per creare abbellimenti
utilizzando CSS. Ad esempio, in Material Design Lite il pulsante
con l'effetto a onde contiene altri due elementi <span>
per implementare
ondeggiare. La presenza di molti pulsanti può determinare un bel numero
di elementi DOM e può portare a un peggioramento delle prestazioni sui dispositivi mobili. Se
implementare l'effetto onde usando un worklet di colorazione
al contrario, ci sono 0 elementi aggiuntivi e solo un worklet di colorazione.
Inoltre, si può avere qualcosa di molto più facile da personalizzare
parametrizzare.
Un altro vantaggio dell'utilizzo di un worklet di colorazione è che, nella maggior parte degli scenari, una soluzione l'utilizzo del worklet di colorazione è ridotto in termini di byte. Ovviamente, compromesso: il codice verrà eseguito ogni volta che le dimensioni della tela o uno qualsiasi dei vengono modificati i parametri. Quindi se il tuo codice è complesso e richiede molto tempo, potrebbe introdurre jank. Chrome si sta adoperando per spostare i worklet di colorazione dal thread principale in modo da anche i lavori di pittura a lunga durata non influiscono sulla reattività del .
Secondo me, la prospettiva più entusiasmante è che il worklet di colorazione consente una il polyfill delle funzionalità CSS di cui un browser non dispone ancora. Un esempio potrebbe essere per eseguire il polyfill dei gradienti conici fino a quando arrivano in Chrome in modo nativo. Un altro esempio: in una riunione CSS, che ora puoi avere più colori per i bordi. Mentre la riunione era ancora in corso, il mio collega Ian Kilpatrick ha scritto un polyfill per il nuovo CSS utilizzando il worklet di colorazione.
Pensare fuori dagli schemi
La maggior parte delle persone inizia a pensare alle immagini di sfondo e
alle immagini dei bordi quando
scopri di più sul worklet di colorazione. Un caso d'uso meno intuitivo per il worklet di colorazione è
mask-image
per fare in modo che gli elementi DOM abbiano forme arbitrarie. Ad esempio, un
diamante:
mask-image
acquisisce un'immagine che corrisponda alle dimensioni dell'elemento. Aree in cui
l'immagine della maschera è trasparente, l'elemento è trasparente. Aree in cui viene applicata la maschera
l'immagine è opaca, mentre l'elemento è opaco.
Ora in Chrome
Colorazione del worklet è stata utilizzata per un po' di tempo in Chrome Canary. Con Chrome 65, sono abilitate per impostazione predefinita. Prova le nuove possibilità si apre il worklet del dipinto, che ci mostra cosa hai costruito! Per ulteriore ispirazione, dai un'occhiata alla collezione di Vincent De Oliveira.