Brush
remocn/brushFreeComponent
Variable-width brush ribbons for Remotion. Pressure taper, grain displacement, and spine samplers shared by the ink marks.
Install it
npx shadcn@latest add https://www.remocn.dev/r/brush.jsonSource
1"use client";23import { hash01 } from "@/lib/remocn/stop-motion";45const GRAIN_RATIO = 0.5;6const GRAIN_FREQUENCY = 0.7;7const GRAIN_OCTAVES = 3;89export type BrushPoint = { x: number; y: number };1011export type BrushTaper = {12 strokeWidth: number;13 pressure?: number;14 release?: number;15};1617export function brushHalfWidth(taper: BrushTaper, t: number): number {18 const pressure = taper.pressure ?? 0.2;19 const release = taper.release ?? 1;20 return (taper.strokeWidth / 2) * (pressure + (release - pressure) * t);21}2223export function brushGrainScale(strokeWidth: number, grain: number): number {24 return strokeWidth * GRAIN_RATIO * grain;25}2627export function brushReach(strokeWidth: number, grain: number): number {28 return strokeWidth / 2 + brushGrainScale(strokeWidth, grain) / 2;29}3031export function brushFilterId(32 seed: string,33 strokeWidth: number,34 grain: number,35): string {36 return `remocn-brush-${Math.floor(hash01(`${seed}:${strokeWidth}:${grain}`) * 1e9)}`;37}3839export function sampleCubic(40 from: BrushPoint,41 c1: BrushPoint,42 c2: BrushPoint,43 to: BrushPoint,44 points = 32,45): BrushPoint[] {46 const count = Math.max(2, points);47 return Array.from({ length: count }, (_, i) => {48 const t = i / (count - 1);49 const u = 1 - t;50 const a = u * u * u;51 const b = 3 * u * u * t;52 const c = 3 * u * t * t;53 const d = t * t * t;54 return {55 x: a * from.x + b * c1.x + c * c2.x + d * to.x,56 y: a * from.y + b * c1.y + c * c2.y + d * to.y,57 };58 });59}6061export function sampleLine(62 from: BrushPoint,63 to: BrushPoint,64 points = 8,65): BrushPoint[] {66 const count = Math.max(2, points);67 return Array.from({ length: count }, (_, i) => {68 const t = i / (count - 1);69 return {70 x: from.x + (to.x - from.x) * t,71 y: from.y + (to.y - from.y) * t,72 };73 });74}7576const normalAt = (points: BrushPoint[], i: number): BrushPoint => {77 const before = points[i - 1] ?? points[i];78 const after = points[i + 1] ?? points[i];79 const tx = after.x - before.x;80 const ty = after.y - before.y;81 const length = Math.hypot(tx, ty) || 1;82 return { x: -ty / length, y: tx / length };83};8485const curveSegments = (points: BrushPoint[]): string =>86 points87 .slice(0, -1)88 .map((p1, i) => {89 const p0 = points[i - 1] ?? p1;90 const p2 = points[i + 1];91 const p3 = points[i + 2] ?? p2;92// … truncated
What it pulls in
Other registry items
Files it writes
More from remocn
All 277 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| UI Accordionaccordion | remocn | Components | Free | 1 dep · 2 files | |
| UI AI Prompt Flowai-prompt-flow | remocn | Components | Free | 1 dep | |
| UI Alert Dialogalert-dialog | remocn | Components | Free | 1 dep · 2 files | |
| Animated Bar Chartanimated-bar-chart | remocn | Components | Free | 1 dep | |
| Animated Line Chartanimated-line-chart | remocn | Components | Free | 1 dep | |
| ASCII Dissolveascii-dissolve | remocn | Components | Free | 2 deps | |
| ASCII Renderascii-render | remocn | Components | Free | 1 dep | |
| Backdropbackdrop | remocn | Components | Free | 1 dep |
