OffscreenCanvas – przyśpiesz pracę kanw, korzystając z narzędzia internetowego

Tim Dresser

Popularny sposób to Canvas. możliwość rysowania wszelkiego rodzaju grafiki na ekranie i wejścia do świata WebGL. Pozwala rysować kształty i obrazy, uruchamiać animacje, a nawet wyświetlać i przetwarzać treści wideo. Często jest wykorzystywany do tworzenia atrakcyjnych treści dla użytkowników w multimediach aplikacji internetowych, w grach online.

Można tworzyć skrypty, co oznacza, że treści narysowane na płótnie mogą być tworzone automatycznie, np. w JavaScripcie. Daje to dużą elastyczność.

Jednocześnie wykonywanie skryptów w nowoczesnych witrynach jest jedną z najczęstszych źródła problemów z czasem reakcji użytkownika. Logika kanwy i renderowanie odbywa się w tym samym wątku co interakcja użytkownika, (czasami intensywne obliczenia) związane z animacjami mogą mieć negatywny wpływ na działanie i postrzegana skuteczność.

Na szczęście OffscreenCanvas to odpowiedź na to zagrożenie.

Obsługa przeglądarek

  • 69
  • 79
  • 105
  • 16.4

Źródło

Wcześniej możliwości rysowania na płótnie były powiązane z elementem <canvas>, co oznacza, że bazuje bezpośrednio na DOM. OffscreenCanvas, jak sama nazwa wskazuje, oddziela DOM i interfejs Canvas API, przenosząc go poza ekran.

Dzięki temu odłączeniu renderowanie interfejsu OffscreenCanvas jest całkowicie odłączone od DOM, oferuje więc pewne przyspieszenie działania w porównaniu ze zwykłym obszarem roboczym, ponieważ brak synchronizacji. między nimi.

Co więcej, można jej używać w środowisku Web Worker, chociaż nie Interfejs DOM jest dostępny. Pozwala to na wiele ciekawych przypadków użycia.

Używanie funkcji OffscreenCanvas w instancji roboczej

Instancje robocze to internetowa wersja wątków, która umożliwia uruchamianie zadań w tle.

Przeniesienie części skryptów do pracowników zapewnia aplikacji więcej możliwości wykonywania zadań o krytycznym znaczeniu dla użytkownika w wątku głównym. Bez funkcji OffscreenCanvas nie można było używać interfejsu Canvas API w instancji roboczej, brakowało DOM.

Parametr OffscreenCanvas nie zależy od DOM, więc można go używać. W tym przykładzie użyto elementu OffscreenCanvas aby obliczyć kolor gradientu w instancji roboczej:

// file: worker.js
function getGradientColor(percent) {
  const canvas = new OffscreenCanvas(100, 1);
  const ctx = canvas.getContext('2d');
  const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  gradient.addColorStop(0, 'red');
  gradient.addColorStop(1, 'blue');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, ctx.canvas.width, 1);
  const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1);
  const colors = imgd.data.slice(percent * 4, percent * 4 + 4);
  return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`;
}

getGradientColor(40);  // rgba(152, 0, 104, 255 )

Odblokuj wątek główny

Przeniesienie zadań do wykonania obliczeń na potrzeby pracownika pozwoli Ci zwolnić znajdziesz w nim więcej przydatnych materiałów. Użyj funkcji transferControlToOffscreen. powielanie zwykłego obszaru roboczego w instancji OffscreenCanvas. Operacje zastosowane do Elementy offline będą automatycznie renderowane w źródłowym obszarze roboczym.

const offscreen = document.querySelector('canvas').transferControlToOffscreen();
const worker = new Worker('myworkerurl.js');
worker.postMessage({canvas: offscreen}, [offscreen]);

W przykładzie poniżej zaawansowane obliczenia są przeprowadzane, kiedy zmienia się motyw kolorystyczny. Powinny one zajmuje tylko kilka milisekund nawet na szybkim komputerze. Możesz uruchamiać animacje w wątku głównym. lub w maszynie roboczej. W przypadku wątku głównego nie możesz wchodzić w interakcję z przyciskiem jest uruchomiony – wątek jest zablokowany. W przypadku pracownika nie ma to wpływu na responsywności interfejsu użytkownika.

Prezentacja

Działa to też w drugi sposób: zajęty wątek główny nie wpływa na animację jako robot. Dzięki tej funkcji możesz uniknąć zacinań i zagwarantować płynną animację. pomimo ruchu w głównym wątku, jak pokazano w tej prezentacji.

Prezentacja

W zwykłym obszarze roboczym animacja zatrzymuje się, gdy wątek główny zostanie sztucznie przeciążony. a funkcja OffscreenCanvas w środowisku roboczym działa płynnie.

Jako że interfejs OffscreenCanvas API jest zasadniczo zgodny ze zwykłym elementem Canvas, w postaci coraz większych udoskonaleń, a także z niektórymi bibliotekami graficznymi wiodącymi na rynku.

Możesz na przykład wykryć cechy i zastosować je za pomocą Three.js przez określenie funkcji opcję kanwy w konstruktorze mechanizmu renderowania:

const canvasEl = document.querySelector('canvas');
const canvas =
  'OffscreenCanvas' in window
    ? canvasEl.transferControlToOffscreen()
    : canvasEl;
canvas.style = {width: 0, height: 0};
const renderer = new THREE.WebGLRenderer({canvas: canvas});

Wyjaśnienie jest takie, że Three.js wymaga, aby obiekt canvas miał właściwości style.width i style.height. Metoda OffscreenCanvas, która jest całkowicie odłączona od modelu DOM, nie ma jej, więc trzeba ją udostępnić samodzielnie, albo przez jej skrócenie, albo podanie logiki, która wiąże te wartości z pierwotną wartością. wymiarów obszaru roboczego.

Poniższy przykład pokazuje, jak uruchomić podstawową animację Three.js w instancji roboczej:

Prezentacja

Pamiętaj, że niektóre interfejsy API związane z DOM nie są łatwo dostępne w instancji roboczej, jeśli więc Jeśli chcesz używać bardziej zaawansowanych funkcji Three.js, takich jak tekstury, możesz potrzebować dodatkowych rozwiązań. Aby dowiedzieć się, jak zacząć z nimi eksperymentować, obejrzyj film z konferencji Google I/O 2017.

Jeśli intensywnie korzystasz z graficznych funkcji kanwy, OutscreenCanvas może mieć wpływają na wydajność aplikacji. Zwiększa możliwości udostępniania kontekstów renderowania kanwy równoległości w aplikacjach internetowych i lepiej wykorzystywać systemy wielordzeniowe.

Dodatkowe materiały