# 思考光球

- 页面: https://jiguang132.com/zh/resources/libraries-dev/docs/thinking-orbs
- 资源: Libraries.dev (https://jiguang132.com/zh/resources/libraries-dev.md)
- 全部指南: https://jiguang132.com/zh/resources/libraries-dev/docs.md

Libraries.dev 的独立组件，请不要替换为 JGuang UI/Base UI 的同名 API。

## 安装

```bash
npm install thinking-orbs@0.3.2
```

安装包后使用它自己的导出组件，支持 React 18+。Canvas/WebGL 组件需要浏览器环境；提供静态降级，并尊重减少动画偏好。声音预览使用模拟信号，不会自动申请麦克风。

## 使用与验证

在左侧选择组件，在预览中操作它的状态；使用“查看代码”检查真实源码。安装后执行类型检查和构建，再验证键盘焦点、手机布局与深浅色主题。

## 来源

https://github.com/Jakubantalik/Libraries.dev/tree/b7f44b8744f4e09ff088d824719636a513110e2a
MIT 许可证；不包括付费内容。下方提供上游英文参考内容，中文使用指南已适配；上游详细参考暂保留英文。

---



## 适用场景

为编程或聊天智能体展示紧凑的视觉状态。

## 关键原生参数

| 参数 | 说明 |
|---|---|
| `state` | 九种原生状态值：working、searching、solving、listening、connecting、weaving、composing、breathing、shaping。 |
| `size` | 可用 20、32、64；20 和 64 为调校后的形态，32 为插值。API 不接受任意数值尺寸。 |
| `paused` | 冻结当前帧。speed、dots、dotSize 分别调节速度、密度和点大小。 |
| `theme` | auto 观察祖先主题属性/类，light/dark 固定配色。 |
| `color` | 可选墨色，需要保证与透明画布背后背景有足够对比。 |

## 交互与状态检查

检查每种状态、三种尺寸、暂停/继续与深浅色。为动画补充邻近状态文字，不只依赖画布传达信息。

## 业务接入边界

listening 不采集音频，searching 不调用搜索服务。frame/opts/gravity 是原生高级扩展口，不是通用状态机协议。

## 示例文件与宿主配置

从源码面板复制 examples 下的组件文件和 shared.tsx，保留它们的相对位置；不是只复制原生上游实现。先安装固定版本 npm 包，在浏览器组件中使用它自己的导出。示例不需要 Tailwind 或新的主题 Provider，采用宿主 html 的语言和主题，并提供减少动画与图形不可用降级。原生实现参考仅供阅读，通过 npm 导入，不要求手工复制内部引擎。示例场景名称不是新增的原生组件属性。下方上游详细参考保留英文，不宣称全文中文化。


## 可运行用法

以下代码使用资源原生 API；不是把其他设计系统的同名组件替换进来。

```tsx
"use client";
import { useState } from "react";
import { ThinkingOrb, type OrbState, type OrbSize } from "thinking-orbs";
import { DemoFrame, GraphicsGuard, control, demoTheme, t } from "./shared";
export default function Example({ variant = "Default" }: { variant?: string }) {
  const states: OrbState[] = ["working", "searching", "solving", "listening", "connecting", "weaving", "composing", "breathing", "shaping"];
  const [state, setState] = useState<OrbState>(states.find(s => s === variant.toLowerCase()) ?? "working"), [size, setSize] = useState<OrbSize>(64), [paused, setPaused] = useState(variant === "Paused");
  return <DemoFrame status={`state=${state}, size=${size}, paused=${paused}`} controls={<>
    <label>{t("State", "状态")} <select style={control} aria-label={t("Orb state", "光球状态")} value={state} onChange={e => setState(e.target.value as OrbState)}>{states.map(s => <option key={s}>{s}</option>)}</select></label>
    <label>{t("Size", "尺寸")} <select style={control} aria-label={t("Orb size", "光球尺寸")} value={size} onChange={e => setSize(Number(e.target.value) as OrbSize)}>{[20, 32, 64].map(s => <option key={s}>{s}</option>)}</select></label>
    <button type="button" style={control} aria-pressed={paused} onClick={() => setPaused(!paused)}>{paused ? t("Resume", "继续动画") : t("Pause", "暂停动画")}</button>
  </>}><GraphicsGuard><ThinkingOrb state={state} size={size} theme={demoTheme()} paused={paused} aria-label={t(`Agent visual state: ${state}`, `智能体视觉状态：${state}`)} /></GraphicsGuard></DemoFrame>;
}

```


## 可用状态与示例

工作中、搜索中、求解中、聆听中、连接中、编织中、创作中、呼吸、形状变化、暂停动画

组件中的状态与数据为演示用途，不包含后端接口。接入实际项目时请检查源码中的公开参数，再连接业务数据。
# thinking-orbs

Dotted thought-orb loading indicators for AI & agent UIs. Nine hand-tuned animated states, each shipped at two purpose-tuned sizes, rendered on a plain 2D canvas — no WebGL, no filters, works identically in Chrome, Safari and Firefox.

[Live demo](https://libraries.dev/orbs) · [Repository](https://github.com/Jakubantalik/Libraries.dev) · [Report an issue](https://github.com/Jakubantalik/Libraries.dev/issues)

## Install

```bash
npm install thinking-orbs
```

## Quick start

```tsx
import { ThinkingOrb } from 'thinking-orbs';

function Status() {
  return <ThinkingOrb state="searching" size={64} />;
}
```

## States

Nine verbs an agent can be doing, each a distinct animation:

```tsx
<ThinkingOrb state="working" />     {/* particles on tilted orbits */}
<ThinkingOrb state="searching" />   {/* a scan meridian sweeps a dotted globe */}
<ThinkingOrb state="solving" />     {/* bands scramble, then click back solved */}
<ThinkingOrb state="listening" />   {/* a waveform rolls through the rings */}
<ThinkingOrb state="connecting" />  {/* a constellation wires itself */}
<ThinkingOrb state="weaving" />     {/* three strands plait around the sphere */}
<ThinkingOrb state="composing" />   {/* an undulating multi-band sash */}
<ThinkingOrb state="breathing" />   {/* a ring slowly morphing */}
<ThinkingOrb state="shaping" />     {/* dotted outline: circle → triangle → square */}
```

## Sizes

Two tuned presets — separate designs, not a scale factor. `64` for chat-avatar scale, `20` for inline-text scale. Each carries its own dot count, dot size and speed tuning:

```tsx
<ThinkingOrb state="working" size={64} />
<ThinkingOrb state="working" size={20} />
```

## Theme

Strictly monochrome — light ink for dark backgrounds, dark ink for light backgrounds — with the mode picked automatically from the host project:

```tsx
<ThinkingOrb theme="auto" />   {/* default — detects from the project */}
<ThinkingOrb theme="dark" />   {/* pin: light dots for dark backgrounds */}
<ThinkingOrb theme="light" />  {/* pin: dark dots for light backgrounds */}
```

`auto` resolves in three layers and updates live when any of them change:

1. an ancestor `data-theme="dark|light"` attribute or `dark`/`light` class (the Tailwind / shadcn convention), watched via `MutationObserver`;
2. otherwise `prefers-color-scheme`, subscribed for live OS theme switches;
3. SSR-safe — the canvas paints only on the client, after the theme has resolved.

## Other props

```tsx
<ThinkingOrb
  state="solving"
  size={20}
  speed={1.5}          // multiplier on the preset's baked speed
  paused={false}       // freeze on the current frame
  aria-label="Analysing repository…"  // overrides the per-state default
/>
```

All other `<canvas>` props (`className`, `style`, `data-*`, …) pass through.

## Accessibility & performance

- `role="img"` with a sensible per-state `aria-label` out of the box.
- `prefers-reduced-motion: reduce` renders a static representative frame — no animation — and still follows the live theme.
- Every instance pauses automatically when scrolled offscreen (`IntersectionObserver`) or when the tab is hidden, and resumes in phase — all instances share one clock.
- Plain 2D canvas arcs only: no `ctx.filter`, no SVG filters, no WebGL — the same pixels everywhere, cheap on low-end devices. Device-pixel-ratio capped at 2.

## License

MIT © Jakub Antalik


## 源码参数参考

以下实现签名和类型从本地固定版本源码生成。保留可选属性、原生继承类型、联合分支和 never 限制；不会将其他设计系统的 API 混入。forwardRef 实现中的 ref 属于 React 引用，不是新增业务属性。此区域是原始类型参考，不是上游说明的全文翻译。


```ts
ThinkingOrb({
  state = 'working',
  size = 64,
  theme = 'auto',
  speed = 1,
  paused = false,
  color,
  dots = 1,
  dotSize = 1,
  opts: optsOverride,
  frame: customFrame,
  gravity,
  style,
  'aria-label': ariaLabel,
  ...rest
}: ThinkingOrbProps)
```



```ts
export type OrbState =
  | 'working'
  | 'searching'
  | 'solving'
  | 'listening'
  | 'connecting'
  | 'weaving'
  | 'composing'
  | 'breathing'
  | 'shaping';

export type OrbSize = 64 | 32 | 20;

export type OrbTheme = 'auto' | 'dark' | 'light';

export interface ThinkingOrbProps extends Omit<CanvasHTMLAttributes<HTMLCanvasElement>, 'style'> {
  /** Which animation to show. @default 'working' */
  state?: OrbState;

  /** Tuned size preset — 64 or 20 CSS px. @default 64 */
  size?: OrbSize;

  /** Theme mode; `auto` detects from the host project. @default 'auto' */
  theme?: OrbTheme;

  /**
   * Animation speed multiplier on top of the preset's baked speed.
   * @default 1
   */
  speed?: number;

  /** Freeze the animation on the current frame. @default false */
  paused?: boolean;

  /**
   * Optional ink tint — any `#rgb`, `#rrggbb` or `rgb()` color. The orb's
   * depth-shading ramp is preserved on the tint (fading toward black on
   * dark substrates, toward white on light ones), so colored orbs read
   * with the same 3D language as the grayscale default. Omit for the
   * stock grayscale ink.
   */
  color?: string;

  /**
   * Density multiplier for the mode's dot/strand/node counts, applied with
   * the same paired-count scaler the size presets use so the mode keeps
   * its balance. `1` (default) is the tuned look; `0.5` halves density,
   * `2` doubles it. Clamped to a 0.1 floor.
   */
  dots?: number;

  /**
   * Radius multiplier for every dot, applied with the same scaler the size
   * presets use so near/far falloff keeps its proportion. `1` (default) is
   * the tuned mark; `0.7` reads finer, `1.5` bolder.
   */
  dotSize?: number;

  /**
   * Advanced: raw draw options merged over the resolved preset, last. These
   * are the engine's own knobs, so they reach past the tuned surface — the
   * orbit paths' `ghostA` and `particles` (working), the globe's `scanMul`
   * and `dimBase` (searching), the constellation's `thr`, `signals`, `lineW`
   * and `spread` (connecting), the plait's `turns` (weaving), the sash's
   * `wobMul`, `bandMul` and `spin` (composing, breathing), and the outline's
   * `spread` and `shape` (shaping — `shape` 0 / 1 / 2 holds the circle,
   * triangle or square instead of cycling). Unknown keys are ignored; a key
   * the current state does not read does nothing.
   */
  opts?: ModeOpts;

  /**
   * Escape hatch below `opts`: replace the state's geometry outright. The
   * function gets `(size, t, opts)` and returns the frame to paint — the
   * same contract every built-in mode implements (see `MODE_FRAMES` and the
   * helpers exported alongside it). The painter, theme, tint, pause and
   * offscreen handling all stay the library's.
   */
  frame?: ModeFrame;

  /**
   * Gravity: the orb pulls at the pointer. As the pointer nears, a raster
   * of the platform's cursor is drawn in its place with its body warped
   * toward the orb — the tip stays put, nothing rotates or scales. Needs the
   * platform's real pointer raster (`gravity.sprite`, or
   * `setGravitySprite`) or it stays off; off automatically under reduced
   * motion, forced colours, coarse pointers, zoom, and over anything but
   * the plain arrow. `true` takes the defaults. See gravity.ts.
   */
  gravity?: boolean | GravityOptions;

  style?: CSSProperties;
}
```


### 源码中的解构默认值

只列出直接写在参数或 props 解构中的默认表达式。条件表达式、运行时主题和其他计算值请结合源码；这里不是全部行为的默认值清单。


```ts
// ThinkingOrb
state = 'working'

// ThinkingOrb
size = 64

// ThinkingOrb
theme = 'auto'

// ThinkingOrb
speed = 1

// ThinkingOrb
paused = false

// ThinkingOrb
dots = 1

// ThinkingOrb
dotSize = 1
```


### 原生与外部类型

以下外部类型仍由 React 或资源自身依赖定义，没有手工展开为虚构属性。实际可用类型以安装版本的 TypeScript 检查为准。


```ts
Omit<CanvasHTMLAttributes<HTMLCanvasElement>, 'style'>
CanvasHTMLAttributes<HTMLCanvasElement>
HTMLCanvasElement
ModeOpts
ModeFrame
GravityOptions
CSSProperties
```

---

JGuang 全部资源索引: https://jiguang132.com/llms.txt
