Skip to content

Gradients & Shaders ​

Gradient and image shaders are declarative children of a shape (or of a <Paint>): a shader placed directly under a shape targets its fill, while a shader inside <Paint style="stroke"> targets its stroke — the native renderer draws fill + stroke as two passes.

Rendered gradients — linear, radial, sweep and two-point conical swatches
tsx
import {
  LinearGradient,
  RadialGradient,
  SweepGradient,
  TwoPointConicalGradient,
  ImageShader,
  vec,
} from "@scumble/react";

All gradient geometry is in absolute user-space pixels (not 0–1 normalized) — the same coordinate space the painted shape uses. Point props (start, end, c) accept a {x, y} object (e.g. from vec) or a [x, y] tuple.

<LinearGradient> ​

A linear gradient between two points.

tsx
<Rect x={0} y={0} width={100} height={100}>
  <LinearGradient start={vec(0, 0)} end={vec(100, 0)} colors={["#f00", "#00f"]} />
</Rect>

Props ​

PropTypeDefaultDescription
startPoint—Gradient start point (absolute user-space px). Required.
endPoint—Gradient end point (absolute user-space px). Required.
colorsColor[]—Gradient stop colors. Required.
positionsnumber[]—Stop offsets.
mode"clamp" | "repeat" | "mirror"—Spread behavior outside the gradient extent.

<RadialGradient> ​

A radial gradient from a center + radius circle. (A focal/two-circle gradient is a separate <TwoPointConicalGradient>.)

tsx
<Circle cx={50} cy={50} radius={50}>
  <RadialGradient c={vec(50, 50)} r={50} colors={["#fff", "#000"]} />
</Circle>

Props ​

PropTypeDefaultDescription
cPoint—Center of the circle (absolute user-space px). Required.
rnumber—Circle radius in px; must be positive. Required.
colorsColor[]—Gradient stop colors. Required.
positionsnumber[]—Stop offsets.
mode"clamp" | "repeat" | "mirror"—Spread behavior outside the gradient extent.

<SweepGradient> ​

An angular sweep around a center. start/end are degrees (this repo standardizes on degrees, matching rotate) mapping to stop offsets 0/1.

tsx
<Rect x={0} y={0} width={100} height={100}>
  <SweepGradient c={vec(50, 50)} colors={["#f00", "#0f0", "#00f"]} />
</Rect>

Props ​

PropTypeDefaultDescription
cPoint—Center of the sweep (absolute user-space px). Required.
startnumber0Start angle in degrees.
endnumber360End angle in degrees.
colorsColor[]—Gradient stop colors. Required.
positionsnumber[]—Stop offsets.
mode"clamp" | "repeat" | "mirror"—Spread behavior outside the gradient extent.

<TwoPointConicalGradient> ​

A two-circle (focal) conical gradient: stop offset 0 sits on the start circle, offset 1 on the end circle.

tsx
<Rect x={0} y={0} width={100} height={100}>
  <TwoPointConicalGradient
    start={vec(30, 30)}
    startR={0}
    end={vec(70, 70)}
    endR={60}
    colors={["#fff", "#000"]}
  />
</Rect>

Props ​

PropTypeDefaultDescription
startPoint—Center of the start (focal) circle (absolute user-space px). Required.
startRnumber—Start circle radius in px; must be ≥ 0. Required.
endPoint—Center of the end circle (absolute user-space px). Required.
endRnumber—End circle radius in px; must be positive. Required.
colorsColor[]—Gradient stop colors. Required.
positionsnumber[]—Stop offsets.
mode"clamp" | "repeat" | "mirror"—Spread behavior outside the gradient extent.

<ImageShader> ​

Fill (or stroke) a shape with a bitmap texture — the same declarative-child pattern as the gradients.

rect places the bitmap in user space: with it, fit crops the bitmap into the rect (the same semantics as <Image fit>, resolved at render time against the intrinsic size) and tiling outside the fitted area follows tx/ty. Without rect, the bitmap tiles 1:1 at its intrinsic size. An empty image clears the slot (the shape draws nothing for that paint).

tsx
const texture = useImage("https://picsum.photos/seed/tile/64/64");

<Rect x={0} y={0} width={200} height={100}>
  <ImageShader image={texture} rect={{ width: 200, height: 100 }} fit="cover" />
</Rect>;

Props ​

PropTypeDefaultDescription
imageImageHandle | string | null—The bitmap: a useImage() handle or a bare uri string. null/empty clears the slot (that paint draws nothing). Required.
fitFit"contain"How the bitmap is inscribed into rect (the CSS object-fit family). Ignored when rect is omitted.
rect{ x?: number; y?: number; width: number; height: number }—Destination rect in user space. Omit for 1:1 tiling at the bitmap's intrinsic size.
txTileMode"clamp"Horizontal tiling outside the fitted area.
tyTileMode"clamp"Vertical tiling outside the fitted area.

vec ​

Construct a 2D point {x, y} — accepted anywhere a shader point prop (start/end/c) is expected, alongside a [x, y] tuple.

tsx
<LinearGradient start={vec(0, 0)} end={vec(100, 100)} colors={["#f00", "#00f"]} />

The return type is Vec = { x: number; y: number }, which is also the vertex format for points arrays.

Released under the Apache License 2.0.