https://skia-canvas.org/ Skip to main content Skia Canvas LogoSkia Canvas Logo Skia Canvas Search * About * Getting Started * API Documentation + App + Canvas + CanvasRenderingContext2D + FontLibrary + Image + ImageData + Path2D + Window * Release Notes * * About On this page Skia Canvas Skia Canvas Skia Canvas is a browser-less implementation of the HTML Canvas drawing API for Node.js. It is based on Google's Skia graphics engine and, accordingly, produces very similar results to Chrome's element. The library is well suited for use on desktop machines where you can render hardware-accelerated graphics to a window and on the server where it can output a variety of image formats. While the primary goal of this project is to provide a reliable emulation of the standard API according to the spec, it also extends it in a number of areas to take greater advantage of Skia's advanced graphical features and provide a more expressive coding environment. In particular, Skia Canvas: * is fast and compact since rendering takes place on the GPU and all the heavy lifting is done by native code written in Rust and C++ * can render to windows using an OS-native graphics pipeline and provides a browser-like UI event framework * generates images in both raster (JPEG, PNG, & WEBP) and vector (PDF & SVG) formats * can save images to files, return them as Buffers, or encode dataURL strings * uses native threads in a user-configurable worker pool for asynchronous rendering and file I/O * can create multiple 'pages' on a given canvas and then output them as a single, multi-page PDF or an image-sequence saved to multiple files * can simplify, blunt, combine, excerpt, and atomize bezier paths using efficient boolean operations or point-by-point interpolation * provides 3D perspective transformations in addition to scaling, rotation, and translation * can fill shapes with vector-based Textures in addition to bitmap-based Patterns and supports line-drawing with custom markers * supports the full set of CSS filter image processing operators * offers rich typographic control including: + multi-line, word-wrapped text + line-by-line text metrics + small-caps, ligatures, and other opentype features accessible using standard font-variant syntax + proportional letter-spacing, word-spacing, and leading + support for variable fonts and transparent mapping of weight values + use of non-system fonts loaded from local files Example Usage Generating image files import {Canvas} from 'skia-canvas' let canvas = new Canvas(400, 400), ctx = canvas.getContext("2d"), {width, height} = canvas; let sweep = ctx.createConicGradient(Math.PI * 1.2, width/2, height/2) sweep.addColorStop(0, "red") sweep.addColorStop(0.25, "orange") sweep.addColorStop(0.5, "yellow") sweep.addColorStop(0.75, "green") sweep.addColorStop(1, "red") ctx.strokeStyle = sweep ctx.lineWidth = 100 ctx.strokeRect(100,100, 200,200) // render to multiple destinations using a background thread async function render(){ // save a 'retina' image... await canvas.saveAs("rainbox.png", {density:2}) // ...or use a shorthand for canvas.toBuffer("png") let pngData = await canvas.png // ...or embed it in a string let pngEmbed = `` } render() // ...or save the file synchronously from the main thread canvas.saveAsSync("rainbox.pdf") Multi-page sequences import {Canvas} from 'skia-canvas' let canvas = new Canvas(400, 400), ctx = canvas.getContext("2d"), {width, height} = canvas for (const color of ['orange', 'yellow', 'green', 'skyblue', 'purple']){ ctx = canvas.newPage() ctx.fillStyle = color ctx.fillRect(0,0, width, height) ctx.fillStyle = 'white' ctx.arc(width/2, height/2, 40, 0, 2 * Math.PI) ctx.fill() } async function render(){ // save to a multi-page PDF file await canvas.saveAs("all-pages.pdf") // save to files named `page-01.png`, `page-02.png`, etc. await canvas.saveAs("page-{2}.png") } render() Rendering to a window import {Window} from 'skia-canvas' let win = new Window(300, 300) win.title = "Canvas Window" win.on("draw", e => { let ctx = e.target.canvas.getContext("2d") ctx.lineWidth = 25 + 25 * Math.cos(e.frame / 10) ctx.beginPath() ctx.arc(150, 150, 50, 0, 2 * Math.PI) ctx.stroke() ctx.beginPath() ctx.arc(150, 150, 10, 0, 2 * Math.PI) ctx.stroke() ctx.fill() }) Edit this page Next Getting Started * Example Usage + Generating image files + Multi-page sequences + Rendering to a window Code * GitHub Repository * NPM module Community * Issue tracker * Discussion forum See also * Canvas API reference * The Rust Skia project * The Skia graphics library Copyright (c) 2024 Christian Swinehart / samizdat.co