|
| 1 | +// Inspired by https://gist.github.com/ahem/d19ee198565e20c6f5e1bcd8f87b3408 |
| 2 | +const worker = new Worker('worker.js'); |
| 3 | + |
| 4 | +const canvasKitInitPromise = |
| 5 | + CanvasKitInit({locateFile: (file) => 'https://particles.skia.org/static/'+file}); |
| 6 | + |
| 7 | +const 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 | + |
| 11 | +Promise.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.SkPaint(); |
| 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(pixels, e.data.width, e.data.height, |
| 67 | + CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_8888, CanvasKit.SkColorSpace.SRGB); |
| 68 | + }); |
| 69 | + document.getElementById('clear-button').addEventListener('click', () => { |
| 70 | + if (decodedImage) { |
| 71 | + decodedImage.delete(); |
| 72 | + decodedImage = null; |
| 73 | + } |
| 74 | + }); |
| 75 | +}); |
| 76 | + |
| 77 | + |
0 commit comments