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