Surface
Surface is the bridge between CanvasKit and the browser's pixels. You give it an HTML <canvas> element (or a raw pixel buffer); it gives you back a Canvas object you draw into. surface.flush() pushes the recorded draw operations to the GPU (or, on a software-backed surface, to the 2D canvas context).
A Surface is a WASM object. Don't delete it between draws — the surface owns the GL context, the offscreen buffer, the canvas you're drawing into. Allocate once per <canvas> element, reuse for the lifetime of the demo.
canvas.clear(CK.WHITE);
const paint = new CK.Paint();
paint.setColor(CK.Color(40, 90, 180, 1));
paint.setAntiAlias(true);
canvas.drawCircle(210, 128, 80, paint);
surface.flush();
paint.delete();
surface and canvas are pre-injected into every doc-page demo on this site. In a from-scratch project you'd write:
const surface = CanvasKit.MakeCanvasSurface('my-canvas-id');
const canvas = surface.getCanvas();
// ... draws ...
surface.flush();
flush
flush() is the GPU push. Without it, your draws stay in the surface's command buffer and never reach the screen. In an animation loop, call it once per frame at the very end.
const paint = new CK.Paint();
paint.setColor(CK.Color(220, 60, 60, 1));
paint.setAntiAlias(true);
let t = 0;
loop(() => {
t += 0.02;
canvas.clear(CK.WHITE);
canvas.drawCircle(
210 + cos(t) * 80,
128 + sin(t) * 40,
30,
paint
);
surface.flush();
});
Snapshots
makeImageSnapshot(bounds?) returns an Image of the surface's current pixels. Useful for comparing against a baseline, exporting to PNG, or feeding back into a shader. The image is a separate WASM object — caller deletes it.
makeImageSnapshot() with no args snapshots the full surface. Pass a [l, t, r, b] rect to snapshot only a region.
Backing types
CanvasKit picks the best backend at surface creation:
MakeWebGLCanvasSurface(default forMakeCanvasSurfaceif available) — GPU-backed via WebGL2 or WebGL1.MakeSWCanvasSurface— pure-software raster. Pixels live in WASM memory;flushblits them to the 2D canvas context.MakeRasterDirectSurface— software raster writing into aMallocObjyou control. Skips a copy when you need direct pixel access.
Most code uses MakeCanvasSurface and lets CanvasKit pick.
Common methods
| Member | Args | Returns | Notes |
|---|---|---|---|
delete | — | void | Free the WASM memory + release the GL context. Call when the surface is no longer needed. |
dispose | — | void | Synonym for delete. |
drawOnce | drawFn: (canvas) => void | void | Convenience: invokes drawFn, then flushes. Use only if you don't need access to the canvas elsewhere. |
flush | — | void | Push recorded draws to the destination (GPU or 2D context). |
getCanvas | — | Canvas | The canvas you draw into. Lifetime tied to the surface. |
height | — | number | Surface height in pixels. |
imageInfo | — | ImageInfo | Width / height / color type of the surface. |
makeImageFromTexture | tex: WebGLTexture, info: ImageInfo | Image | Wrap an existing GL texture as a CanvasKit Image (zero-copy). |
makeImageFromTextureSource | src: HTMLImageElement | HTMLVideoElement | …, info?: ImageInfo, srcIsPremul?: boolean | Image | Upload from a DOM source into a fresh GL texture, return as Image. |
makeImageSnapshot | bounds?: IRect | Image | Snapshot of current surface pixels. Caller deletes. |
makeSurface | info: ImageInfo | Surface | Create a child surface compatible with this one. |
reportBackendTypeIsGPU | — | boolean | True if backed by WebGL/WebGPU. |
requestAnimationFrame | drawFn: (canvas) => void | void | Convenience that calls drawFn inside rAF and flushes. |
sampleCnt | — | number | Sample count (1 = no MSAA). |
updateTextureFromSource | img: Image, src: TexImageSource, srcIsPremul?: boolean | void | Refresh an existing Image's GL texture from a new DOM source. |
width | — | number | Surface width in pixels. |
Static factories
(on CanvasKit, not Surface)
| Factory | Args | Returns | Notes |
|---|---|---|---|
CK.MakeCanvasSurface | canvas: HTMLCanvasElement | string | Surface | null | Tries WebGL first, falls back to software. The most common entry point. |
CK.MakeWebGLCanvasSurface | canvas, colorSpace?, opts?: WebGLOptions | Surface | null | Force GPU. Returns null if WebGL unavailable. |
CK.MakeSWCanvasSurface | canvas: HTMLCanvasElement | string | Surface | null | Force software raster. Slower but works everywhere. |
CK.MakeRasterDirectSurface | info: ImageInfo, pixels: MallocObj, bytesPerRow: number | Surface | null | Software raster writing into a malloc'd buffer you control. Use for pixel readback without copies. |
CK.MakeRenderTarget | ctx: GrDirectContext, w: number, h: number | Surface | null | Headless GPU surface tied to an existing context. |
CK.MakeSurface | w: number, h: number | Surface | null | Standalone software surface (no DOM canvas). Pair with readPixels. |
See also
Canvas— the draw API; you get one viasurface.getCanvas().Image— whatmakeImageSnapshotreturns.ImageInfo— pixel layout passed to most surface factories.- Memory management — surface lifetime owns the canvas.