Zum Inhalt springen
UI Kit
Accent

Leuchtende Kugel als Animation

Eine weiche, atmende Lichtkugel, wie eine Kugel schattiert, mit Wirbel im Inneren und weitem Schein, mit WebGL gezeichnet. Neigt sich zum Zeiger.

4 VariantsEine von 6 Components in 3D-Hintergründe

Ein ruhiges Licht, das zu atmen scheint

Eine Lichtkugel ist eine weiche Kugel aus Licht, die langsam atmet, schattiert wie eine echte Kugel und umgeben von weitem Schein, mit WebGL gezeichnet. Sie gibt einer Seite eine ruhige, lebendige Mitte und passt gut zu Assistenten, Sprachfunktionen und leisen Marken.

„Hero mit Kugel daneben“ setzt den Text links, rechts atmet die Kugel, am Telefon liegt sie unter dem Text. Die „Aufgehende Kugel“ steigt halb über die Unterkante wie eine Sonne, der Text steht darüber. Die „Hervorgehobene Karte“ zeigt eine kleine Kugel, die leuchtet wie eine Stimme, die zuhört. „Hinter einem Call to Action“ lässt eine große Kugel weich hinter der abschließenden Überschrift leuchten.

Lass die Kugel allein stehen, sie braucht Raum, um zu leuchten. Die Karte eignet sich als leises Zeichen, dass etwas zuhört oder nachdenkt, etwa neben einer Assistenzfunktion.

Variants

Hero mit Kugel danebenNeu in 1.2

Text links, rechts atmet die Kugel. Am Telefon liegt sie unter dem Text.

Aufgehende KugelNeu in 1.2

Die Kugel steigt halb über die Unterkante wie eine Sonne, der Text steht darüber.

Hervorgehobene KarteNeu in 1.2

Eine kleine Kugel leuchtet in der hervorgehobenen Karte, wie eine Stimme, die zuhört.

Hinter einem Call to ActionNeu in 1.2

Eine große Kugel leuchtet weich hinter der abschließenden Überschrift.

Details

Was Lichtkugel mitbringt, aus Registry und Quellcode gelesen.

Bereich
Visuals
Variants
4
Version
1.0.0 · seit 1.2.0
Datei
components/ui/glow-orb.tsx
Bringt mit
utilskitwebgl
npm-Pakete
Keine
Sprachen
Texte kommen über Props
Studio
Im Code anpassen
In Sammlungen
3D und Bewegung

Props

Die Schnittstelle GlowOrbProps aus components/ui/glow-orb.tsx. Beschreibungen stammen aus den Kommentaren im Code und sind auf Englisch. Nimmt außerdem alle Props von ShaderLayerProps an.

  • placementoptional
    GlowOrbPlacement

    centerrightbottomcorner

    center behind the copy, right next to it (from 900 px box width, below the copy on narrower boxes), bottom half sunk below the edge, or corner at the top right (for cards)

  • sizeoptional
    number

    Size, 1 is the designed size

  • wobbleoptional
    number

    How much the outline moves, 0 is a calm circle, default 1

  • glowoptional
    number

    Width of the glow around the orb, default 1

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

  • Ohne Animationen, sie steht sofort ruhig da.

Quellcode

Die Datei, die aiw add in dein Projekt legt. Sie gehört danach dir.

Datei anzeigen, 115 Zeilen
components/ui/glow-orb.tsx
'use client';

import { cn } from '@/lib/kit';
import { GLSL_NOISE, ACCENT_PALETTE, ShaderBackdrop, ShaderCanvas, type ShaderLayerProps } from '@/components/ui/webgl';

/*
 * A soft orb of light that breathes. Its outline is a circle bent by slow
 * noise, its body is shaded like a sphere lit from the upper left, with a
 * swirl of the neighbour colors inside, a bright rim and a wide glow around
 * it. It leans toward the pointer and swells a little while the page scrolls
 * past. Soft by nature, rendered at reduced resolution.
 */

export type GlowOrbPlacement = 'center' | 'right' | 'bottom' | 'corner';

export interface GlowOrbProps extends ShaderLayerProps {
  /** center behind the copy, right next to it (from 900 px box width, below the copy on narrower boxes), bottom half sunk below the edge, or corner at the top right (for cards) */
  placement?: GlowOrbPlacement;
  /** Size, 1 is the designed size */
  size?: number;
  /** How much the outline moves, 0 is a calm circle, default 1 */
  wobble?: number;
  /** Width of the glow around the orb, default 1 */
  glow?: number;
}

const PLACE: Record<GlowOrbPlacement, number> = { center: 0, right: 1, bottom: 2, corner: 3 };

const FRAG = `${GLSL_NOISE}
uniform float u_place;uniform float u_size;uniform float u_wobble;uniform float u_glow;
void main(){
float m=min(u_res.x,u_res.y);
vec2 p=(gl_FragCoord.xy-.5*u_res)/m;
float hw=.5*u_res.x/m,hh=.5*u_res.y/m;
vec2 c=vec2(0.);float R=.27;
if(u_place>.5&&u_place<1.5){if(u_res.x/u_dpr>=900.){c=vec2(hw*.5,0.);R=.3;}else{R=min(.3,130.*u_dpr/m);c=vec2(0.,-hh+R*1.45+.04);}}
if(u_place>1.5&&u_place<2.5){R=min(.55,hw*.6);c=vec2(0.,-hh-R*.15);}
if(u_place>2.5){R=min(min(.3,hh*.42),80.*u_dpr/m);c=vec2(hw-R*1.05,hh-R*1.05);}
float t=u_time;
R*=u_size*(1.+.045*sin(t*.85)+(u_scroll-.5)*.08);
c+=(u_mouse-.5)*vec2(.12,.08)*u_hover;
vec2 d=p-c;float len=length(d);
vec2 dir=d/max(len,1e-4);
float w=(noise(dir*1.3+vec2(t*.22,-t*.17))-.5)*.22+(noise(dir*2.7-vec2(t*.31,t*.13))-.5)*.1;
float rr=R*(1.+w*u_wobble);
float sdf=len-rr;
vec2 q=d/rr;
float z=sqrt(max(0.,1.-dot(q,q)));
vec3 n=vec3(q,z);
float lit=clamp(dot(n,normalize(vec3(-.45,.55,.7))),0.,1.);
float sw=fbm(q*1.8+vec2(t*.09,-t*.07)+n.xy*.6);
vec3 hi=mix(vec3(1.),u_c3,u_dark);
vec3 body=mix(u_c0,hi,smoothstep(.25,1.,lit)*.62);
body=mix(body,u_c1,smoothstep(.45,.85,sw)*.32);
body=mix(body,u_c2,smoothstep(.55,.9,1.-sw)*.28*(1.-lit));
float rim=pow(1.-z,2.5);
body+=u_c0*rim*.3*u_dark;
float inside=smoothstep(.035,-.035,sdf);
float glow=exp(-max(sdf,0.)*mix(5.5,3.5,u_dark)/max(u_glow,.1))*mix(.32,.55,u_dark);
float ab=inside*mix(.74,.92,u_dark)*(.78+.22*z);
vec3 col=body*ab+u_c0*glow*(1.-inside);
float a=ab+glow*(1.-inside);
float k=u_intensity;
a=clamp(a*k,0.,1.);
gl_FragColor=vec4(min(col*k,vec3(1.)),a);
}`;

const SPOT: Record<GlowOrbPlacement, string> = {
  center: 'left-1/2 top-1/2 aspect-square w-[min(54%,54vh)] -translate-x-1/2 -translate-y-1/2',
  right: 'max-lg:left-1/2 max-lg:top-[64%] max-lg:aspect-square max-lg:w-[min(60%,40vh)] max-lg:-translate-x-1/2 lg:right-[10%] lg:top-1/2 lg:aspect-square lg:w-[min(32%,60vh)] lg:-translate-y-1/2',
  bottom: 'left-1/2 top-[78%] aspect-square w-[min(66%,40rem)] -translate-x-1/2',
  corner: 'right-[6%] top-[6%] aspect-square h-[44%]',
};

/**
 * A breathing orb of light behind or beside any content. With children it
 * renders a box, without children only the layer for a `relative` parent.
 */
export function GlowOrb({ intensity = 1, speed = 1, colors, interactive = true, placement = 'center', size = 1, wobble = 1, glow = 1, fallback, scrim = 'none', scrimStrength, scrimColor, children, className, contentClassName, layerClassName }: GlowOrbProps) {
  return (
    <ShaderBackdrop
      scrim={scrim}
      scrimStrength={scrimStrength}
      scrimColor={scrimColor}
      className={className}
      contentClassName={contentClassName}
      layer={
        <ShaderCanvas
          fragment={FRAG}
          colors={colors ?? ACCENT_PALETTE}
          uniforms={{ u_place: PLACE[placement], u_size: size, u_wobble: wobble, u_glow: glow }}
          speed={speed}
          intensity={intensity}
          scale={0.6}
          pointer={interactive}
          fallback={
            fallback ?? (
              <div
                className={cn('absolute rounded-full', SPOT[placement])}
                style={{
                  background: 'radial-gradient(circle at 38% 34%, color-mix(in oklab, var(--primary) 40%, var(--foreground) 25%), var(--primary) 45%, oklch(from var(--primary) calc(l * 0.8) c calc(h - 52)) 100%)',
                  boxShadow: '0 0 120px 30px color-mix(in oklab, var(--primary) 35%, transparent)',
                  opacity: 0.9,
                }}
              />
            )
          }
          className={layerClassName}
        />
      }
    >
      {children}
    </ShaderBackdrop>
  );
}

Häufige Fragen

Wie installiere ich Lichtkugel?

Mit aiw add @ai-website/glow-orb. Der Befehl legt die Datei components/ui/glow-orb.tsx in dein Projekt, der Code gehört danach dir. Mit dabei sind webgl. Weitere npm-Pakete braucht sie nicht.

Welche Varianten hat Lichtkugel?

4 Varianten, Hero mit Kugel daneben, Aufgehende Kugel, Hervorgehobene Karte und Hinter einem Call to Action.

Kann ein KI-Assistent Lichtkugel einbauen?

Ja. Über den MCP-Server der aiw CLI finden Claude, Cursor, GitHub Copilot, Windsurf, Codex und Gemini Lichtkugel mit aiw_components und installieren sie mit aiw_add @ai-website/glow-orb.

Oft gesucht

Direkt zu

In die Zwischenablage kopiert