// Types are monkey-patched in runtime/types/canvaskit-wasm.d.ts import type { CanvasKit as CanvasKitType, CanvasKitInitOptions } from 'canvaskit-wasm'; import { version } from 'canvaskit-wasm/package.json'; type CanvasKitInit = (options: CanvasKitInitOptions) => CanvasKitType; declare global { // eslint-disable-next-line no-var var CanvasKit: CanvasKitType | undefined; // eslint-disable-next-line no-var var CanvasKitInit: CanvasKitInit | undefined; } /** * This loads CanvasKit from jsDelivr instead of a local file. * It's because we can't serve canvaskit.wasm on the expected path when running locally. * Keep this API in sync with: https://github.com/Shopify/react-native-skia/blob/main/package/src/web/WithSkiaWeb.tsx */ export async function loadCanvasKit(options?: CanvasKitInitOptions) { // Don't reinitialize if it's there already if (global.CanvasKit) return; // Initialize the script if it hasn't been loaded yet. if (!global.CanvasKitInit) await loadCanvasKitScript(); // Use default configuration for Snack. // It loads the CanvasKit WASM compatible with the bundled JS. if (!options) { options = { locateFile: (file) => `https://cdn.jsdelivr.net/npm/canvaskit-wasm@${version}/bin/full/${file}`, }; } // Store CanvasKit on the global namespace for Skia to interact with. if (global.CanvasKitInit) { global.CanvasKit = await global.CanvasKitInit(options); } else { console.error( 'CanvasKitInit is not loaded, this is likely an issue with Snack. - Open a new issue at http://github.com/expo/snack.', ); } } export async function loadCanvasKitScript() { return await new Promise((resolve, reject) => { const $script = document.createElement('script'); $script.addEventListener('load', resolve); $script.addEventListener('error', reject); $script.setAttribute('id', `canvaskit@${version}`); $script.setAttribute('type', 'text/javascript'); $script.setAttribute('async', ''); $script.setAttribute( 'src', `https://cdn.jsdelivr.net/npm/canvaskit-wasm@${version}/bin/full/canvaskit.js`, ); document.body.appendChild($script); }); }