1// Inspired by https://gist.github.com/ahem/d19ee198565e20c6f5e1bcd8f87b3408
2const worker = new Worker('worker.js');
3
4const canvasKitInitPromise =
5    CanvasKitInit({locateFile: (file) => 'https://unpkg.com/canvaskit-wasm@0.25.0/bin/full/'+file});
6
7const bigImagePromise =
8    fetch('https://upload.wikimedia.org/wikipedia/commons/3/30/Large_Gautama_Buddha_statue_in_Buddha_Park_of_Ravangla%2C_Sikkim.jpg')
9    .then((response) => response.blob());
10
11Promise.all([
12    canvasKitInitPromise,
13    bigImagePromise
14]).then(([
15    CanvasKit,
16    imageBlob
17]) => {
18    const surface = CanvasKit.MakeWebGLCanvasSurface('main-thread-canvas', null);
19    if (!surface) {
20        throw 'Could not make main thread canvas surface';
21    }
22
23    const paint = new CanvasKit.Paint();
24    paint.setColor(CanvasKit.RED);
25
26    let decodedImage;
27    // This animation draws a red circle oscillating from the center of the canvas.
28    // It is there to show the lag introduced by decoding the image on the main
29    // thread.
30    const drawFrame = (canvas) => {
31        canvas.clear(CanvasKit.WHITE);
32
33        if (decodedImage) {
34            canvas.drawImageRect(decodedImage,
35                CanvasKit.LTRBRect(0, 0, 3764, 5706), // original size of the image
36                CanvasKit.LTRBRect(0, 0, 500, 800), // scaled down
37                null); // no paint needed
38        }
39        canvas.drawCircle(250, 250, 200 * Math.abs(Math.sin(Date.now() / 1000)), paint);
40        surface.requestAnimationFrame(drawFrame);
41    };
42    surface.requestAnimationFrame(drawFrame);
43
44
45    document.getElementById('load-button-main').addEventListener('click', () => {
46        if (decodedImage) {
47            decodedImage.delete();
48            decodedImage = null;
49        }
50        const imgBitmapPromise = createImageBitmap(imageBlob);
51        imgBitmapPromise.then((imgBitmap) => {
52            decodedImage = CanvasKit.MakeImageFromCanvasImageSource(imgBitmap);
53        });
54    });
55
56    document.getElementById('load-button-web').addEventListener('click', () => {
57        if (decodedImage) {
58            decodedImage.delete();
59            decodedImage = null;
60        }
61        worker.postMessage(imageBlob);
62    });
63    worker.addEventListener('message', (e) => {
64        const decodedBuffer = e.data.decodedArrayBuffer;
65        const pixels = new Uint8Array(decodedBuffer);
66        decodedImage = CanvasKit.MakeImage({
67            width: e.data.width,
68            height: e.data.height,
69            alphaType: CanvasKit.AlphaType.Unpremul,
70            colorType: CanvasKit.ColorType.RGBA_8888,
71            colorSpace: CanvasKit.ColorSpace.SRGB
72        }, pixels, 4 * e.data.width);
73    });
74    document.getElementById('clear-button').addEventListener('click', () => {
75        if (decodedImage) {
76            decodedImage.delete();
77            decodedImage = null;
78        }
79    });
80});
81
82
83