1

Is it possible to create a dynamic generated image from a service worker using some offscreen canvas?

I can imagine that it's a very new technology if it exist such a thing but i found no source in the spec about creating a canvas... Is it possible in any browser behind any experimental flag or even some discussion/issue about it?

Endless
  • 34,080
  • 13
  • 108
  • 131
  • My initial thought is no since the WebWorker would not have access to the DOM and would therefore not be able to access the canvas or create one of its own. I'm also not sure if you can pass canvas contexts to WebWorkers either, but that might be an avenue to research. See [Is there a way to create out of DOM elements in Web Worker?](http://stackoverflow.com/q/18056922/691711). What methods are you trying to utilize from canvas? – zero298 Oct 12 '16 at 14:04
  • Yeah, can't even pass the context, you'll get a `DataCloneError`. – zero298 Oct 12 '16 at 14:19
  • 2
    https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas will be of help though only for Firefox. – Blindman67 Oct 12 '16 at 14:41
  • 1
    @Blindman67 if you posted this as an answer i would mark it as accepted. just one question doe. How do you load imageData from a existing image from cache/server if you can't create `new Image()` inside a service worker? – Endless Oct 12 '16 at 14:51
  • You will have to read through the documentation. You could use one of the communications APIs (webSockets, webRTC) though not sure if they are available in worker context, though not much overhead to just pass the data to the worker via message system. – Blindman67 Oct 12 '16 at 14:58

2 Answers2

5

For firefox a very handy API that can be used in workers is the OffscreenCanvas

Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • That seems very handy indeed. But according to your link, it's also limited to webgl contexts for now... – Kaiido Oct 12 '16 at 23:36
  • @Kaiido there are a few javascript libraries that implement the full canvas2D API using webGL They can provide better performance than the Native 2D API under many common usage requirement. – Blindman67 Oct 13 '16 at 07:24
4

A code sample for generating on-the-fly notification image with OffscreenCanvas in the service worker:

// canvas.toDataURL() not available with OffscreenCanvas ?
const toDataURL = async (data) =>
  new Promise(ok => {
    const reader = new FileReader();
    reader.addEventListener('load', () => ok(reader.result));
    reader.readAsDataURL(data);
  });

const imageCanvas = async (title) => {
  const canvas = new OffscreenCanvas(192, 192);
  const ctx = canvas.getContext('2d');
  ctx.font = "30px Comic Sans MS";
  ctx.fillStyle = "red";
  ctx.textAlign = "center";
  ctx.fillText(title, canvas.width/2, canvas.height/2);
  // Hack-ish
  const blob = await canvas.convertToBlob();
  return await toDataURL(blob);
};

self.addEventListener("push", event =>
  event.waitUntil(Promise.resolve().then(async() => {
    let body, image;
    if (self.OffscreenCanvas) image = await imageCanvas('Hello Push');
    else body = 'Your Browser does not support OffscreenCanvas with Service Worker';
    console.log('[SW]', { image });
    return self.registration.showNotification('OffscreenCanvas Demo', {
      body,
      image,
      tag: 'canvas',
    });
  }));
);
kael
  • 185
  • 1
  • 8