Pastel

Pastel that behaves like a stick in your hand. It catches on the crests of the paper and skips the valleys, builds up when you go over it again, crumbles into what it missed, and smears under a finger. Colours mix like pigment, not like light: yellow over blue goes green.

import { PastelSurface } from "shodo/paint";

const surface = new PastelSurface(canvas, { material: "soft", feel: { cover: 0.7, smear: 0.8 } });
surface.apply([40, 60, 200, 80], { tool: "stick", color: [0.9, 0.3, 0.2], radius: 12, pressure: 0.7, id: 1 });
surface.render();

That is a soft pastel that covers a little more in one pass and smears further than usual.

Two sticks and a finger smear. Draw on it; let go of a dial below to start again with that feel.open in the playground

Start from a material

MaterialWhat it is
softDry soft pastel: chalky, sheer at first, crumbles into the grain. The default.
oilOil pastel: opaque, pushes into the grain under pressure, piles up and barely lifts.
charcoalVine charcoal, since 2026-11-10: hard and thin, so the paper’s grain shows; crumbly; drags far under a finger and lifts almost clean with an eraser. Pick dark sticks for it.

Feel

Seven dials, each from 0 to 1. Before 2026-11-10 (record entry 62) there were five: blend and polish came then. At 0.5 a dial leaves the material you started from exactly as it was. Dials you don’t set stay there too.

  • cover
    sheeropaque

    How much one pass hides what is under it.

  • softness
    hardbuttery

    How far the stick gets into the grain: the crests only, or down into the valleys.

  • body
    thinpiled up

    How thick a stroke builds on the paper.

4 more dials
  • crumble
    cleancrumbly

    How much falls into the valleys a stroke missed when you build up.

  • smear
    stays putsmears far

    How far a finger drags the colour.

  • blend
    keeps apartworks together

    How much pressing hard works the colours under a stroke together. Oil only: soft pastel always covers.

  • polish
    keeps toothpolished

    How much a heavy touch flattens the paper’s grain, so later passes skate over it.

PASTEL_FEEL holds the same words for building a panel. The dials scale what the material already does, so a material that never crumbles (oil) stays clean whatever crumble says.

Tools

A stroke picks its tool: stick lays colour, smudge is a finger, scrape is a blade that cuts recent coats back, erase is a kneaded eraser and fix sprays fixative over the whole sheet so what is there stops moving. apply takes the pointer path since the last call as x, y pairs; one point dabs. pressure runs from 0 to 1.2, and buildUp: true lets repeated passes fill the grain to solid colour.

The eraser

erase (since 2026-11-10) lifts a share of the loose dust from every coat at once, the newest and the ones under it alike, so a few passes take a mark back towards the paper and leave a ghost, as a kneaded eraser does. How much comes up is the material’s erasable: charcoal 1, soft pastel 0.6, oil pastel 0.15. Fixed dust stays. Pressure lifts more; the tooth stays as flat as it was.

surface.apply([320, 90, 330, 400], { tool: "erase", radius: 30, pressure: 1, aspect: 1, color: [0, 0, 0], id: 7 });

From a picture

In the pastel lab, choose a picture or drop one anywhere, and the sheet repaints it stroke by stroke: first broad strokes with the side of the stick to block in each area, then second colours over the first, then edges with the end of the stick. It paints on the room’s paper with the palette you pick: the room’s tray, colours taken from the picture itself (3 to 12 of them, each a colour the picture really has), or a named set: earth, sea and sky, dusk, greys, or shodo’s own five colours. Click any swatch to change it before you paint, so a photo can be pushed warmer, cooler or towards a few colours of your own. detail runs from broad and loose to finer with more strokes. Everyone in the room watches it paint, undo takes strokes back and stop ends it early. The picture itself stays in your tab: only the strokes go to the room.

The planner is playground/lab/paint-plan.ts (lab code, not a library export yet), the same one agents call through paint_image in the playground’s MCP server.

Paper

Pastel lands on laid paper unless you give it another. See paper.md for the papers and their dials.

Underneath

feelMaterial(material, feel) returns a plain PastelMaterial, and you can pass one of those as material with any number set directly. MATERIALS holds the two above.