The graphic design API: quickstart#
API hub · Reference · Quickstart · Cheatsheet
The graphic design API builds a graphic in code - shapes, text, images, masks and gradients on a page - and renders the one document to SVG and PNG; this is the path from an install to both files.
The whole thing in three steps#
- Install the API in a folder of your own:
npm install @isocialpractice/napkin-sketch
From a clone, npm install and npm run build build it, and the files
below go in the clone.
- Save this as
card.mjsin that folder:
import { writeFile } from 'node:fs/promises';
import { createComposition } from '@isocialpractice/napkin-sketch';
const design = createComposition({ width: 360, height: 360, background: '#f6f7f9' });
design.rect({ x: 24, y: 24, width: 312, height: 96, rx: 12, fill: '#326478' });
design.text({ x: 180, y: 78, text: 'Acme Corp', align: 'center', fontSize: 28, fill: '#ffffff' });
design.circle({ cx: 180, cy: 220, r: 64, fill: '#4cae50' });
await writeFile('card.svg', design.toSVG(), 'utf-8');
await writeFile('card.png', design.toPNG());
- Run it. It writes
card.svgandcard.png:
node card.mjs
Both files come off the one composition, so they are the same graphic in two
formats. A page defaults to 360 by 360 pixels, and coordinates are pixels
unless the page names in, mm or pt. In a clone the same imports work,
since a package can import itself by its name.
A worked example#
A badge: a radial gradient under a ring with a hole in it, and a name under
both, written to out/badge.svg and out/badge.png in one call. Save it as
badge.mjs beside card.mjs and run node badge.mjs:
import { createComposition } from '@isocialpractice/napkin-sketch';
import { writeComposition } from '@isocialpractice/napkin-sketch/node';
const design = createComposition({ width: 240, height: 240, background: '#ffffff' });
design.circle({
cx: 120, cy: 120, r: 96,
fill: { type: 'radial', stops: [{ offset: 0, color: '#ffe08a' }, { offset: 1, color: '#ff8a65' }] },
});
design.group({ erase: [{ type: 'circle', cx: 120, cy: 120, r: 40, fill: '#000000' }] }, (ring) => {
ring.circle({ cx: 120, cy: 120, r: 70, fill: '#326478' });
});
design.text({ x: 120, y: 228, text: 'Acme Corp', align: 'center', fontSize: 16, fill: '#1f2328' });
const { svg, png, warnings } = await writeComposition(design, 'out', 'badge');
console.log(svg, png, warnings);
The ring's erase shape clears the middle of its own group and nothing else,
so the gradient shows through the hole. writeComposition writes the SVG and
the PNG from one document, so the two cannot come from different revisions,
and warnings lists anything the PNG could not draw.
Where to go next#
- The page and Elements: every element and every property.
- Clipping masks, Gradients and Transforms.
- Rendering: the options, and
renderPng's warnings. - Brand resources: placing a brand's own logo and footer.
- Writing a drawing out: a napkin script's drawing, lowered into a composition.
- The cheatsheet: every method on one line.