Interfejs API CSS Paint

Nowe możliwości w Chrome 65

CSS Paint API (znany też jako „CSS Custom Paint” lub „Pracownia malowania Houdini'ego”) jest włączone domyślnie od Chrome 65. Co to jest? Co możesz zrobić z nim? Jak to działa? Czytaj dalej, cóż...

Interfejs CSS Paint API umożliwia automatyczne generowanie obrazu za każdym razem, gdy w kodzie CSS usługi oczekuje obrazu. Właściwości takie jak background-image lub border-image są zwykle używane z tagiem url() do wczytywania pliku graficznego lub z wbudowanym CSS takie jak linear-gradient(). Zamiast ich używać, paint(myPainter), aby odwołać się do Workletu malowania.

Pisanie farby

Aby zdefiniować obszar roboczy malowania o nazwie myPainter, trzeba wczytać arkusz CSS paint. Worklet za pomocą funkcji CSS.paintWorklet.addModule('my-paint-worklet.js'). Pod tym kątem możemy użyć funkcji registerPaint do zarejestrowania klasy Worklet paint:

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

registerPaint('myPainter', MyPainter);

W wywołaniu zwrotnym paint() możemy użyć parametru ctx w taki sam sposób, jak CanvasRenderingContext2D jak wiemy z <canvas>. Jeśli wiesz, jak narysuj w <canvas>, możesz rysować farbą. geometry informuje nas szerokości i wysokości płótna. properties Tak co wyjaśnimy w dalszej części tego artykułu.

Na początek napiszmy arkusz malowania w szachownicę i wykorzystamy go. jako obraz tła w aplikacji <textarea>. (Używam obszaru tekstowego, ponieważ jest to domyślnie można zmienić).

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

Jeśli zdarzyło Ci się już korzystać z usługi <canvas>, ten kod powinien wyglądać znajomo. Zobacz na żywo demonstracja tutaj.

Pole tekstowe ze wzorem w szachownicę jako obraz tła
, Obszar tekstowy ze wzorem w szachownicę jako obraz tła.

Różnica w porównaniu ze standardowym obrazem tła polega na tym, będzie ponownie rysowana na żądanie, gdy użytkownik zmieni rozmiar pola tekstowego. Oznacza to, że Obraz tła jest zawsze odpowiednio duży, włącznie z dla wyświetlaczy o dużej gęstości.

To całkiem fajne, ale też dość statyczne. Czy możemy napisać nowy za każdym razem, gdy chcialiśmy ten sam wzór, ale w różnym rozmiarze kwadraty? Odpowiedź brzmi: nie.

Parametrowanie Worklet

Na szczęście obszar roboczy farby ma dostęp do innych właściwości CSS, w którym pojawia się dodatkowy parametr properties. Przedstawienie zajęć inputProperties, możesz subskrybować zmiany w dowolnej usłudze CSS, łącznie z właściwościami niestandardowymi. Wartości zostaną Ci przekazane w pliku 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);

Teraz możemy używać tego samego kodu do różnych rodzajów szachownicy. Ale nawet jeśli możemy teraz przejść do Narzędzi deweloperskich i poeksperymentować z wartościami aż znajdziemy właściwy wygląd.

Przeglądarki, które nie obsługują Workletu malowania

W momencie pisania tego tekstu tylko Chrome miał zaimplementowany obszar roboczy malowania. Chociaż to pozytywne sygnały od wszystkich innych dostawców przeglądarek, nie jest duży postęp. Najnowsze informacje znajdziesz w sekcji Is Houdini Ready Ready jeszcze? regularnie. Tymczasem używaj trybu progresywnego, udoskonalenie pozwalające na nieprzerwane działanie kodu nawet wtedy, gdy nie jest dostępna funkcja paint. Worklet. Aby wszystko działało zgodnie z oczekiwaniami, dostosuj kod w w 2 miejscach: CSS i JS.

Obsługę Workletu malowania w JS można wykryć za pomocą obiektu CSS: js if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('mystuff.js'); } Jeśli chodzi o usługę porównywania cen, masz 2 opcje. Elementów @supports możesz używać:

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

Bardziej kompaktowa sztuczka polega na wykorzystaniu tego, że CSS unieważnia, a następnie ignoruje całą deklarację właściwości, jeśli zawiera ona nieznaną funkcję. Jeśli musisz określić właściwość dwukrotnie – najpierw bez malowania, a następnie za pomocą metody narzędzia malowania — otrzymujesz stopniowe ulepszenia:

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

W przeglądarkach z obsługą Worklet malowania druga deklaracja wartości Pierwszy z nich zostanie zastąpiony przez background-image. w przeglądarkach bez obsługi. w przypadku Workletu druga deklaracja jest nieprawidłowa i zostanie odrzucona, pozostawienie w życiu pierwszej deklaracji.

Polyfill CSS z farbą

W wielu zastosowaniach można również użyć funkcji CSS Paint Polyfill, , który dodaje obsługę niestandardowych procesów renderowania i malowania CSS w nowoczesnych przeglądarkach.

Przypadki użycia

Istnieje wiele przypadków użycia Workletów malowania. Niektóre z nich są bardziej oczywiste niż reszta. Jedną z bardziej oczywistych metod jest użycie Workleta malowania w celu zmniejszenia rozmiaru obrazu. modelu DOM. Elementy są często dodawane wyłącznie w celu utworzenia ozdób za pomocą CSS. Na przykład w Material Design Lite przycisk z efektem fali zawiera 2 dodatkowe elementy <span>, które implementują fale. Jeśli masz dużo przycisków, może to przynieść całkiem sporą liczbę. elementów DOM, co może prowadzić do pogorszenia wydajności na urządzeniach mobilnych. Jeśli wdróż efekt fali za pomocą farby w workletze zamiast tego ma się 0 dodatkowych elementów i 1 pracownik malowania. Poza tym masz coś, co można znacznie łatwiej dostosować, .

Kolejną zaletą korzystania z trybu malowania jest to, że w większości przypadków w ramach malowania jest to nieduża liczba bajtów. Oczywiście istnieje na kompromis: kod malowania będzie uruchamiany zawsze, gdy rozmiar płótna . Jeśli kod jest złożony i zajmuje dużo czasu, może wprowadzić zacinanie. Chrome pracuje nad przeniesieniem Workletów malowania z głównego wątku, nawet długotrwałe Worklety malowania nie wpływają na responsywność w wątku.

Uważam, że najbardziej ekscytująca perspektywa jest taka, powielania funkcji CSS, których nie ma jeszcze przeglądarka. Na przykład: do wypełniania gradientów stożkowych do otwierają ją natywnie w Chrome. Inny przykład: na spotkaniu usługi porównywania cen że można wybrać wiele kolorów obramowania. Gdy to spotkanie było mój kolega Ian Kilpatrick napisał kod polyfill dla tej nowej usługi porównywania cen jak działa malowanie.

Nieszablonowe myślenie

Większość osób zaczyna myśleć o obrazach tła i obramowaniach, (dowiedz się więcej o malowaniu). Jedno z mniej intuicyjnych zastosowań procesu malowania to: mask-image, aby elementy DOM miały dowolne kształty. Na przykład diament:

Element DOM w kształcie rombu.
Element DOM w kształcie rombu.

mask-image pobiera obraz, który ma rozmiar elementu. Obszary, w których obraz maski jest przezroczysty, a element jest przezroczysty. Obszary, w których maskowana jest maska obraz jest nieprzezroczysty, a element – nieprzezroczysty.

Teraz w Chrome

Worklet jest od jakiegoś czasu w Chrome Canary. Dzięki Chrome 65 domyślnie włączone. Wypróbuj nowe możliwości który się otworzy i pokaż nam, co udało Ci się stworzyć. Aby znaleźć więcej inspiracji, obejrzyj kolekcję Vincenta De Oliveiry.