canvaskit-wasm 0.39 build 2026-04-29

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 for MakeCanvasSurface if available) — GPU-backed via WebGL2 or WebGL1.
  • MakeSWCanvasSurface — pure-software raster. Pixels live in WASM memory; flush blits them to the 2D canvas context.
  • MakeRasterDirectSurface — software raster writing into a MallocObj you control. Skips a copy when you need direct pixel access.

Most code uses MakeCanvasSurface and lets CanvasKit pick.

Common methods

MemberArgsReturnsNotes
deletevoidFree the WASM memory + release the GL context. Call when the surface is no longer needed.
disposevoidSynonym for delete.
drawOncedrawFn: (canvas) => voidvoidConvenience: invokes drawFn, then flushes. Use only if you don't need access to the canvas elsewhere.
flushvoidPush recorded draws to the destination (GPU or 2D context).
getCanvasCanvasThe canvas you draw into. Lifetime tied to the surface.
heightnumberSurface height in pixels.
imageInfoImageInfoWidth / height / color type of the surface.
makeImageFromTexturetex: WebGLTexture, info: ImageInfoImageWrap an existing GL texture as a CanvasKit Image (zero-copy).
makeImageFromTextureSourcesrc: HTMLImageElement | HTMLVideoElement | …, info?: ImageInfo, srcIsPremul?: booleanImageUpload from a DOM source into a fresh GL texture, return as Image.
makeImageSnapshotbounds?: IRectImageSnapshot of current surface pixels. Caller deletes.
makeSurfaceinfo: ImageInfoSurfaceCreate a child surface compatible with this one.
reportBackendTypeIsGPUbooleanTrue if backed by WebGL/WebGPU.
requestAnimationFramedrawFn: (canvas) => voidvoidConvenience that calls drawFn inside rAF and flushes.
sampleCntnumberSample count (1 = no MSAA).
updateTextureFromSourceimg: Image, src: TexImageSource, srcIsPremul?: booleanvoidRefresh an existing Image's GL texture from a new DOM source.
widthnumberSurface width in pixels.

Static factories

(on CanvasKit, not Surface)

FactoryArgsReturnsNotes
CK.MakeCanvasSurfacecanvas: HTMLCanvasElement | stringSurface | nullTries WebGL first, falls back to software. The most common entry point.
CK.MakeWebGLCanvasSurfacecanvas, colorSpace?, opts?: WebGLOptionsSurface | nullForce GPU. Returns null if WebGL unavailable.
CK.MakeSWCanvasSurfacecanvas: HTMLCanvasElement | stringSurface | nullForce software raster. Slower but works everywhere.
CK.MakeRasterDirectSurfaceinfo: ImageInfo, pixels: MallocObj, bytesPerRow: numberSurface | nullSoftware raster writing into a malloc'd buffer you control. Use for pixel readback without copies.
CK.MakeRenderTargetctx: GrDirectContext, w: number, h: numberSurface | nullHeadless GPU surface tied to an existing context.
CK.MakeSurfacew: number, h: numberSurface | nullStandalone software surface (no DOM canvas). Pair with readPixels.

See also

  • Canvas — the draw API; you get one via surface.getCanvas().
  • Image — what makeImageSnapshot returns.
  • ImageInfo — pixel layout passed to most surface factories.
  • Memory management — surface lifetime owns the canvas.