Körnung
Eine Körnung aus einer SVG-Turbulenz, die Verläufen und Akzentflächen das Glatte nimmt.
Eine von 6 Components in Backgrounds
Variants
Details
Was Körnung mitbringt, aus Registry und Quellcode gelesen.
- Kategorie
- Backgrounds
- Bereich
- Elements
- Variants
- 3
- Version
- 1.0.0 · seit 1.0.0
- Datei
- components/ui/noise.tsx
- Bringt mit
- utilskit
- npm-Pakete
- Keine
- Sprachen
- Texte kommen über Props
- Studio
- Im Code anpassen
- Mit KI bauen
- Per MCP in Claude, Cursor, Copilot und Codex
Props
Die Schnittstelle NoiseProps aus components/ui/noise.tsx. Beschreibungen stammen aus den Kommentaren im Code und sind auf Englisch.
opacityoptionalnumber0 to 1, default 0.4. The grain itself is already thin, 1 is still subtle.
blendoptionalNoiseBlendnormaloverlaysoft-lightmultiplyscreen
How the grain mixes with what is below, default normal
grainoptionalNoiseGrainfinemediumcoarse
Size of the grain, default fine
toneoptional'foreground' | 'background' | 'contrast'Color of the grain: foreground (dark specks in light mode, light in dark), background (the opposite) or contrast (primary-foreground, for grain on an accent surface)
animatedoptionalbooleanLet the grain flicker like film, off with reduced motion
Barrierefreiheit
Aus dem Quellcode der Component abgeleitet.
- Kommt ohne Client-State aus. Der Server schreibt sie vollständig, sie ist auch ohne JavaScript lesbar.
Bewegung
- Bringt eigene Animationen mit, ruhig getaktet und ohne Wackeln.
- Bei reduzierter Bewegung (prefers-reduced-motion) bleibt sie ruhig.
Quellcode
Die Datei, die aiw add in dein Projekt legt. Sie gehört danach dir.
Datei anzeigen, 79 Zeilen
'use client';
import { cn } from '@/lib/kit';
export type NoiseBlend = 'normal' | 'overlay' | 'soft-light' | 'multiply' | 'screen';
export type NoiseGrain = 'fine' | 'medium' | 'coarse';
export interface NoiseProps {
/** 0 to 1, default 0.4. The grain itself is already thin, 1 is still subtle. */
opacity?: number;
/** How the grain mixes with what is below, default normal */
blend?: NoiseBlend;
/** Size of the grain, default fine */
grain?: NoiseGrain;
/**
* Color of the grain: foreground (dark specks in light mode, light in dark),
* background (the opposite) or contrast (primary-foreground, for grain on an accent surface)
*/
tone?: 'foreground' | 'background' | 'contrast';
/** Let the grain flicker like film, off with reduced motion */
animated?: boolean;
className?: string;
}
const FREQ: Record<NoiseGrain, number> = { fine: 0.9, medium: 0.68, coarse: 0.45 };
const TONE = { foreground: 'var(--foreground)', background: 'var(--background)', contrast: 'var(--primary-foreground)' };
/*
* The grain is an SVG turbulence turned into an alpha map and used as a mask,
* so its color comes from a token and follows light and dark mode.
*/
const grainUrl = (freq: number, alpha: string) =>
`url("data:image/svg+xml;utf8,${encodeURIComponent(
`<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n' x='0' y='0'><feTurbulence type='fractalNoise' baseFrequency='${freq}' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ${alpha}'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>`,
).replace(/%2523/g, '%23')}")`;
const CSS = `
@keyframes kitfx-noise-shift {
0% { transform: translate3d(0, 0, 0); }
25% { transform: translate3d(-37px, 23px, 0); }
50% { transform: translate3d(19px, -41px, 0); }
75% { transform: translate3d(-13px, -17px, 0); }
100% { transform: translate3d(31px, 11px, 0); }
}
@media (prefers-reduced-motion: reduce) { .kitfx-noise > * { animation: none !important; } }
`;
/**
* A grain overlay that takes the edge off flat gradients and photos. Put it
* after the background it should cover, it fills the parent and never takes
* clicks. Pure CSS and SVG, no canvas.
*/
export function Noise({ opacity = 0.4, blend = 'normal', grain = 'fine', tone = 'foreground', animated, className }: NoiseProps) {
// Dark specks where the noise is high, light specks where it is low: the grain adds texture, never a grey veil
const dark = grainUrl(FREQ[grain], '0 0 0 2 -1.06');
const light = grainUrl(FREQ[grain], '0 0 0 -2 0.94');
return (
<div aria-hidden className={cn('kitfx-noise pointer-events-none absolute inset-0 overflow-hidden', className)} style={{ opacity, mixBlendMode: blend }}>
{animated && <style dangerouslySetInnerHTML={{ __html: CSS }} />}
{[
{ mask: dark, color: TONE[tone] },
{ mask: light, color: tone === 'foreground' ? TONE.background : TONE.foreground },
].map((layer, i) => (
<div
key={i}
className={cn('absolute', animated ? '-inset-12' : 'inset-0')}
style={{
background: layer.color,
maskImage: layer.mask,
WebkitMaskImage: layer.mask,
maskSize: '220px 220px',
WebkitMaskSize: '220px 220px',
animation: animated ? 'kitfx-noise-shift 1.6s steps(1, end) infinite' : undefined,
}}
/>
))}
</div>
);
}Häufige Fragen
Wie installiere ich Körnung?
Mit aiw add @ai-website/noise. Der Befehl legt die Datei components/ui/noise.tsx in dein Projekt, der Code gehört danach dir. Weitere npm-Pakete braucht sie nicht.
Welche Varianten hat Körnung?
3 Varianten, Feine Körnung, Filmkorn und Auf einer Akzentkarte.
Kann ein KI-Assistent Körnung einbauen?
Ja. Über den MCP-Server der aiw CLI finden Claude, Cursor, GitHub Copilot, Windsurf, Codex und Gemini Körnung mit aiw_components und installieren sie mit aiw_add @ai-website/noise. Nenn im Prompt die Variante, etwa variant="vivid", dann schreibt der Assistent deine Inhalte direkt in die Props.