CSS-Paint-API

Neue Möglichkeiten mit Chrome 65

Die CSS Paint API (auch bekannt als „CSS Custom Paint“ oder „Houdini’s Paint Worklet“) ist ab Chrome 65 standardmäßig aktiviert. Worum handelt es sich? Was kannst du tun? damit zu tun haben? Und wie funktioniert das? Na ja, lies weiter, ja ...

Mit der CSS Paint API können Sie ein Bild programmatisch generieren, wenn ein CSS-Code erwartet ein Bild. Attribute wie background-image oder border-image werden normalerweise mit url() zum Laden einer Bilddatei oder mit integriertem CSS verwendet. Funktionen wie linear-gradient(). Anstatt diese zu verwenden, können Sie paint(myPainter), um auf ein paint-Worklet zu verweisen.

Paint-Worklet schreiben

Um ein Paint-Worklet namens myPainter zu definieren, müssen wir ein CSS-Painting laden. Worklet-Datei mithilfe von CSS.paintWorklet.addModule('my-paint-worklet.js'). Dabei können wir mit der Funktion registerPaint eine Paint-Worklet-Klasse registrieren:

class MyPainter {
  paint(ctx, geometry, properties) {
    // ...
  }
}

registerPaint('myPainter', MyPainter);

Innerhalb des paint()-Callbacks können wir ctx genauso verwenden, wie wir CanvasRenderingContext2D, wie wir es von <canvas> kennen. Wenn Sie wissen, wie Sie Zeichnen Sie in einem <canvas>, dann können Sie in einem Pain-Worklet zeichnen. geometry teilt uns mit, Breite und Höhe des Canvas, das uns zur Verfügung steht. properties Ich werde werden wir später in diesem Artikel erläutern.

Schreiben wir als Einführungsbeispiel ein Schachbrett-Painting-Worklet und verwenden es als Hintergrundbild einer <textarea>. (Ich verwende einen Textbereich, die Größe kann standardmäßig angepasst werden.):

<!-- 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);

Wenn Sie <canvas> in der Vergangenheit verwendet haben, sollte Ihnen dieser Code bekannt vorkommen. Weitere Informationen finden Sie unter das Live- Demo hier.

. Textbereich mit Schachbrettmuster als Hintergrundbild
Textbereich mit einem Schachbrettmuster als Hintergrundbild.

Der Unterschied zur Verwendung eines üblichen Hintergrundbilds besteht darin, werden bei Bedarf neu gezeichnet, wenn der Nutzer die Größe des Textbereichs ändert. Das bedeutet, Das Hintergrundbild ist immer genau so groß, wie es sein muss, einschließlich der Kompensierung von hochauflösenden Displays.

Das ist ziemlich cool, aber auch ziemlich statisch. Würden wir eine neue das gleiche Muster, aber mit unterschiedlicher Größe, Squares? Nein.

Worklet parametrisieren

Glücklicherweise kann das Paint-Worklet auf andere CSS-Eigenschaften zugreifen. der zusätzliche Parameter properties ins Spiel. Indem Sie der Klasse eine statische inputProperties verwenden, können Sie Änderungen an allen Preisvergleichsportal-Properties abonnieren. einschließlich benutzerdefinierter Eigenschaften. Die Werte werden Ihnen über die properties-Parameter.

<!-- 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);

Jetzt können wir denselben Code für alle verschiedenen Arten von Schachbrettern verwenden. Aber selbst Besser können wir uns jetzt in den Entwicklertools mit den Werten herumschlagen. bis wir den richtigen Look gefunden haben.

Browser, die Paint-Worklet nicht unterstützen

Zum Zeitpunkt der Erstellung dieses Dokuments war das Paint-Worklet nur für Chrome implementiert. Während ich dort positive Signale von allen anderen Browser-Anbietern gibt, gibt es nicht viel Fortschritt. Wenn Sie auf dem Laufenden bleiben möchten, lesen Sie Is Houdini Ready Yet? (in englischer Sprache). regelmäßig. Verwenden Sie in der Zwischenzeit das Vollbildverfahren Verbesserung, damit Ihr Code auch dann ausgeführt wird, wenn keine Unterstützung für Paint Worklet zu erstellen. Damit alles wie erwartet funktioniert, müssen Sie Ihren Code in zwei Stellen: die CSS- und die JS-Datei.

Wenn in JS das Paint-Worklet unterstützt wird, können Sie das CSS-Objekt prüfen: js if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('mystuff.js'); } Auf der Preisvergleichsportal-Seite haben Sie zwei Möglichkeiten. Sie können @supports verwenden:

@supports (background: paint(id)) {
  /* ... */
}

Ein kompakterer Trick besteht darin, die Tatsache zu nutzen, dass CSS ungültig macht und ignoriert eine gesamte Property-Deklaration, wenn eine unbekannte Funktion darin enthalten ist. Wenn geben Sie eine Eigenschaft zweimal an – zuerst ohne Paint-Worklet und dann mit dem Paint-Worklet – Sie erhalten Progressive Enhancement:

textarea {
  background-image: linear-gradient(0, red, blue);
  background-image: paint(myGradient, red, blue);
}

In Browsern mit Unterstützung für Paint-Worklet wird die zweite Deklaration background-image überschreibt das erste. In Browsern ohne Unterstützung Für Paint-Worklet ist die zweite Deklaration ungültig und wird verworfen. sodass die erste Erklärung in Kraft bleibt.

CSS-Farbfüllung (Polyfill)

In vielen Fällen ist es auch möglich, die CSS Paint Polyfill um die Unterstützung von CSS Custom Paint und Paint Worklets für moderne Browser hinzuzufügen.

Anwendungsfälle

Es gibt viele Anwendungsfälle für Paint-Worklets, von denen einige offensichtlicher sind als andere. Eine der offensichtlichsten Methoden ist die Verwendung von Paint-Worklet zur Größenreduzierung. Ihres DOMs verwenden. Oft werden Elemente nur hinzugefügt, um Verzierungen zu kreieren. mit CSS. In Material Design Lite kann beispielsweise die Schaltfläche enthält mit dem Welleneffekt zwei zusätzliche <span>-Elemente zur Implementierung des sich ausbreiten. Bei vielen Schaltflächen kann dies eine ganze Menge von DOM-Elementen und kann auf Mobilgeräten zu Leistungseinbußen führen. Wenn Sie Ripple-Effekt mit Paint-Worklet implementieren Stattdessen haben Sie 0 zusätzliche Elemente und nur ein Paint-Worklet. Außerdem lässt sich die Funktion viel leichter anpassen parametrisieren.

Ein weiterer Vorteil von Paint Worklet besteht darin, dass in den meisten Szenarien eine Lösung Paint-Worklet ist in Bytes klein. Natürlich gibt es auch Kompromiss: Ihr Paint-Code wird immer dann ausgeführt, wenn die Größe des Canvas ändern. Wenn Ihr Code komplex ist und lange dauert, Verzögerung. Chrome arbeitet daran, Farb-Worklets aus dem Hauptthread zu verschieben, selbst lang andauernde Paint-Worklets nicht auf die Reaktionsfähigkeit der Haupt- Diskussions-Thread.

Für mich ist die interessanteste Idee, dass Paint-Worklet Polyfilling von CSS-Funktionen, die im Browser noch nicht verfügbar sind. Ein Beispiel wäre um konische Farbverläufe zu füllen, bis landen sie nativ in Chrome. Ein weiteres Beispiel: In einer Preisvergleichsportal-Besprechung beschlossen, dass Sie jetzt mehrere Rahmenfarben haben können. Während dieser Besprechung mein Kollege Ian Kilpatrick schrieb ein Polyfill für dieses neue CSS Paint-Worklet nutzen.

Über den Tellerrand blicken

Die meisten Menschen denken erst an Hintergrundbilder und Rahmenbilder, wenn sie etwas über Paint-Worklet. Ein weniger intuitiver Anwendungsfall für Paint-Worklet ist mask-image, damit DOM-Elemente beliebige Formen haben. Beispiel: diamond verwenden:

<ph type="x-smartling-placeholder">
</ph> Ein DOM-Element in Form einer Raute. <ph type="x-smartling-placeholder">
</ph> Ein DOM-Element in Form einer Raute.

mask-image nimmt ein Bild auf, das die Größe des Elements hat. Bereiche, in denen die Maskenbild ist transparent, das Element ist transparent. Bereiche, in denen die Maske Bild ist „undurchsichtig“, das Element „undurchsichtig“.

Jetzt in Chrome

Paint Worklet ist schon seit einiger Zeit in Chrome Canary verfügbar. Mit Chrome 65 ist standardmäßig aktiviert. Probieren Sie die neuen Möglichkeiten aus öffnet sich das Paint-Worklet und zeigt uns, was Sie gebaut haben! Weitere Anregungen finden Sie Sehen Sie sich Vincent De Oliveiras Kollektion an.