Skip to content

wcandillon/canvaskit-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

canvaskit-js

A polyfill for CanvasKit that uses browser APIs. This project a technical preview and is highly experimental.

Feature Support

The goal of canvaskit-js is to be indistinguishable from canvaskit-wasm. However, there are three main differences between the two projects:

Browser Support

Browser Notes
Chrome
Edge
Firefox Shaders support in progress
Safari 17 ⚠️ No shaders nor image filters available
Safari 17.4 No image filters available

Installation

The URL of each package version is available on the Github Releases.

npm install canvaskit-js

Getting Started

Once installed, the CanvasKit instance is available via the asynchronous CanvasKitInit method. However, it is also accessible synchronously via CanvasKitJS.getInstance().

import {CanvasKitInit, CanvasKitJS} from "canvaskit-js";

// The asynchronous method still works
CanvasKitInit({}).then((CanvasKit) => {
    global.CanvasKit = CanvasKit;
});

// But you can also access this synchronously now
global.CanvasKit = CanvasKitJS.getInstance();

To create a surface, you can pass an HTML canvas element directly via MakeCanvasSurface. However, we also polyfill other surface creation methods such as MakeWebGLCanvasSurface or MakeSWCanvasSurface. Please note that when using MakeWebGLCanvasSurface, we still create a Canvas2D context behind the scenes, not a WebGL one.

// MakeWebGLCanvasSurface actually creates a Canvas2D behind the scenes
const surface = CanvasKit.MakeWebGLCanvasSurface(document.getElementById("myCanvas"));
const canvas = surface.getCanvas();

From there, the APIs are identical, except for these differences.

const width = 252;
const height = 252;
const r = 92;

const paint = new CanvasKit.Paint();
paint.setBlendMode(CanvasKit.BlendMode.Multiply);

// Cyan Circle
const cyan = paint.copy();
cyan.setColor(CanvasKit.CYAN);
canvas.drawCircle(r, r, r, cyan);
      
// Magenta Circle
const magenta = paint.copy();
magenta.setColor(CanvasKit.MAGENTA);
canvas.drawCircle(width - r, r, r, magenta);

// Yellow Circle
const yellow = paint.copy();
yellow.setColor(CanvasKit.YELLOW);
canvas.drawCircle(width / 2, height - r, r, yellow);

React Native Skia

CanvasKitJS works seamlessly with React Native Skia. However, you need to modify the way CanvasKit is loaded. We simply need to add the CanvasKit instance to the global namespace.

Consider the following React Native Skia loading code:

import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/module/web";

LoadSkiaWeb().then(async () => {
  const App = (await import("./src/App")).default;
  AppRegistry.registerComponent("Example", () => App);
});

It becomes:

import {CanvasKitJS} from "canvaskit-js";

(async () => {
  global.CanvasKit = CanvasKitJS.getInstance();
  const App = (await import("./src/App")).default;
  AppRegistry.registerComponent("Example", () => App);
})();

The useImage hook from React Native Skia won't work; see image support.

Library development

This repository contains three folders:

  • package/ for the main library
  • example/ for demos and examples
  • docs/ for documentation

Here's a list of useful commands for contributing to the project. We use yarn, but these should also work with npm.

In the package folder, you can run the following commands:

cd package
yarn install # installs dependencies
yarn build # builds the library
yarn watch # builds the library on every change
yarn test # runs e2e tests

In the example app, you can run the following commands. If you have the yarn watch command running in the package folder, you will be able to see the changes in real time in the example app.

cd example
yarn install
yarn start