Canvas-style API
Paths, bezier and arc segments, fill and stroke, linear, box and radial gradients, scissor clipping and transform stacks, all as methods on one context.
NanoVG's Canvas-style API (paths, gradients, text, images) as a loadable QuickJS module. Point it at a GLFW window and draw.
import * as glfw from 'glfw';
import { CreateGL3, ANTIALIAS, RGBA } from 'nanovg';
const win = new glfw.Window(800, 600, 'NanoVG');
glfw.context.current = win;
const nvg = CreateGL3(ANTIALIAS);
while(!win.shouldClose) {
nvg.BeginFrame(800, 600, 1);
nvg.BeginPath();
nvg.RoundedRect(100, 100, 200, 150, 12);
nvg.FillColor(RGBA(255, 128, 0, 255));
nvg.Fill();
nvg.EndFrame();
win.swapBuffers();
glfw.poll();
}Canvas-like drawing without a browser: the whole binding is one C file on top of NanoVG.
Paths, bezier and arc segments, fill and stroke, linear, box and radial gradients, scissor clipping and transform stacks, all as methods on one context.
Load fonts and images by id, lay out and align text, render into offscreen framebuffers and read pixels back with ReadPixels.
A single nvgjs-module.c (about 2,300 lines) plus NanoVG itself, built to nanovg.so. It needs QuickJS, GLEW and OpenGL; the window comes from the glfw module.
qjsm has no DOM, but canvas2d.js gives you a canvas and a requestAnimationFrame that draw through NanoVG in a GLFW window, so Canvas 2D code runs under qjsm.
import { canvas, requestAnimationFrame } from 'canvas2d.js';
const ctx = canvas.getContext('2d');
requestAnimationFrame(function loop() {
ctx.fillRect(10, 10, 100, 100);
requestAnimationFrame(loop);
});The same API runs on a web page: NanoVG compiled to WebAssembly with Emscripten, drawing on WebGL2. web/nanovg.js mirrors the native module name for name, so the demo scripts run there unchanged.
The planets, curve editor and polyline editor examples load as they are. A small loader makes their blocking glfw.poll() loops yield to the browser.
A compatibility script diffs every export, function length, property flag and error message of the browser module against nanovg.so; the pure-math results agree.
A normal CMake build also produces the wasm when emcc is found (BUILD_WEB).
git clone --recursive https://github.com/rsenn/qjs-nanovg.git
cd qjs-nanovg
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
sudo cmake --install build # installs nanovg.so for qjsm
qjsm examples/planets.js