Orb — Animated SwiftUI Visualizer Skill
Decision Tree
What are you building?
|
|-- Modify existing OCMiniOrb?
| |-- Add/change state? -> See: Existing Implementation
| |-- Tune layers? -> See: references/existing-impl.md
| \-- Add audio reactivity? -> Bind audioLevel to scaleEffect
|
|-- New orb variant?
| |-- Siri iOS 18 style (edge glow)? -> T1: MeshGradient + T2: AnimatedRectangle mask
| |-- Classic Siri (layered rotation)? -> T3: Layer rotation with Figma assets
| |-- Particle sphere (Jarvis)? -> T6: 3D particle system in Canvas
| |-- Kaaba/Diamond? -> See: references/variants.md
| \-- Glow button shadow? -> T7: Angular gradient + blur
|
|-- Performance issue?
| |-- Dropped frames? -> Check: fractal conditional removal, Canvas vs SwiftUI shapes
| |-- High CPU idle? -> Ensure TimelineView pauses when not visible
| \-- Memory growth? -> Check particle pool / recycle bin pattern
|
\-- Accessibility?
\-- .accessibilityReduceMotion -> guard !reduceMotion else { return }
Quick Reference: 7 Techniques
| # |
Technique |
API |
Best For |
Ref |
| T1 |
MeshGradient |
MeshGradient(width:height:points:colors:) |
Siri iOS 18 edge glow |
references/techniques.md#t1 |
| T2 |
AnimatedRectangle |
Custom Shape + animatableData |
Breathing border mask |
references/techniques.md#t2 |
| T3 |
Layer Rotation |
ZStack + .rotationEffect + .hueRotation |
Classic Siri icon |
references/techniques.md#t3 |
| T4 |
Hue-Shift Gradient |
TimelineView + shiftHue() |
Color cycling backgrounds |
references/techniques.md#t4 |
| T5 |
Metal Ripple |
ShaderLibrary.Ripple + .layerEffect |
Tap/activation ripple |
references/techniques.md#t5 |
| T6 |
3D Particle Sphere |
Canvas + sphere projection math |
Jarvis orb, particle clouds |
references/techniques.md#t6 |
| T7 |
Angular Glow |
AngularGradient + .blur |
Button glow shadows |
references/techniques.md#t7 |
Existing Implementation (OCMiniOrb)
Path: packages/uikit/Sources/OCDesignKit/Components/OCMiniOrb.swift
Storybook: apps/storybook/Sources/Shared/MiniOrbPage.swift
Spec: docs/ux/orb/mini-clawd-spec.md
6-layer stack in ZStack:
| Layer |
What |
How |
| 1. Ambient Glow |
RadialGradient + .blur(size*0.25) |
Opacity pulse 0.2-0.35, 2s |
| 2. Base Orb |
RadialGradient circle |
Breathe 0.98-1.02, 3s; audio in speaking |
| 3. Fractal |
Canvas + TimelineView(1/30fps) |
6 Fibonacci rings, conditional on state |
| 4. Glass |
RadialGradient + .ultraThinMaterial |
Static 0.85x |
| 5. Smoke |
4 orbiting blobs in Canvas |
3-6s rotation per blob |
| 6. Eyes |
2 white circles |
Dim to 0.4 in thinking |
States: OrbDisplayState — .idle, .thinking, .speaking, .listening
Colors: OCColors.voiceOrb{State}Start/End, .voiceHighlight, .voiceParticle
Performance Rules (NON-NEGOTIABLE)
- Canvas over shapes — Use
Canvas for particle systems (single draw call per layer)
- Conditional hierarchy — Remove fractal/smoke from view tree when idle:
if state == .thinking { ... }
- 30fps cap —
TimelineView(.animation(minimumInterval: 1.0 / 30.0))
- Reduce motion —
@Environment(\.accessibilityReduceMotion) guards ALL animation starts
- Pool particles — Recycle bin pattern (linked list, not array append/remove)
- No SpriteKit — Pure SwiftUI + Canvas + optional Metal
- Target — 60fps at 48pt on iPhone 12 / M1 Mac
Compositing Recipe: New Orb
// Minimal orb skeleton
struct MyOrb: View {
let state: OrbDisplayState
var size: CGFloat = 48
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View {
ZStack {
// 1. Glow (always)
Circle().fill(RadialGradient(...)).blur(radius: size * 0.25)
// 2. Base (always)
Circle().fill(RadialGradient(...)).scaleEffect(breatheScale)
// 3. Active layers (conditional)
if state != .idle {
activeLayer(size) // Canvas-based
}
// 4. Glass (always)
Circle().fill(...).background(.ultraThinMaterial.opacity(0.15))
// 5. Highlights (always)
eyeDots(size)
}
.frame(width: size * 1.3, height: size * 1.3)
.accessibilityLabel("Assistant \(state.label)")
}
}
Key Helper: sinInRange
func sinInRange(_ range: ClosedRange<Float>, offset: Float, timeScale: Float, t: Float) -> Float {
let amplitude = (range.upperBound - range.lowerBound) / 2
let midPoint = (range.upperBound + range.lowerBound) / 2
return midPoint + amplitude * sin(timeScale * t + offset)
}
Used by MeshGradient (T1) and AnimatedRectangle (T2) for organic motion.
References
| File |
Content |
references/techniques.md |
Full code for all 7 techniques with copy-paste patterns |
references/existing-impl.md |
OCMiniOrb layer-by-layer analysis, modification guide |
references/variants.md |
Kaaba/Diamond, particle sphere, mesh orb variant specs |
External Sources
Related Skills
- pencil — Visual design prompts and character art for orb avatars (concept → prompt)
- swiftui-animation — General SwiftUI animation patterns (broader scope)
- swiftui-performance-audit — Runtime perf diagnostics (when orb causes frame drops)
Technique Map
- 6-layer ZStack compositing — Ambient glow, base orb, fractal (conditional), glass, smoke, eyes; because layering order determines visual hierarchy and performance.
- Canvas over shapes for particles — Single draw call per layer; because SwiftUI shapes = many draw calls; Canvas = one.
- Conditional hierarchy — Remove fractal/smoke when idle; because redundant layers drain GPU when not visible.
- 30fps cap for TimelineView — minimumInterval: 1.0/30.0; because 60fps for decorative layers wastes budget.
- Reduce motion guard — @Environment(.accessibilityReduceMotion) on ALL animation; because accessibility compliance is non-negotiable.
- sinInRange helper — Organic motion for MeshGradient and AnimatedRectangle; because procedural variation feels more natural than linear.
- Pool particles — Recycle bin pattern, not array append/remove; because mid-frame allocation causes frame drops.
Technique Notes
7 techniques: T1 MeshGradient, T2 AnimatedRectangle, T3 layer rotation, T4 hue-shift, T5 Metal ripple, T6 particle sphere, T7 angular glow. OCMiniOrb path: OCDesignKit/Components/OCMiniOrb.swift. Target: 60fps at 48pt on iPhone 12.
Prompt Architect Overlay
Role Definition: Animated SwiftUI orb builder. Siri-style mesh gradients, particle spheres, AI assistant visualizers. Encodes 7 compositing techniques with performance rules and accessibility compliance.
Input Contract: Accepts orb variant (Siri iOS 18, classic Siri, particle sphere, Kaaba/Diamond), modification target (existing OCMiniOrb or new), or performance issue. State (idle/thinking/speaking/listening) if modifying existing.
Output Contract: Layer-by-layer compositing recipe, technique references, performance rules checklist. SwiftUI code snippets. Accessibility labels. References to techniques.md, existing-impl.md, variants.md.
Edge Cases & Fallbacks: If frame drops→check conditional hierarchy, Canvas vs shapes, particle count. If modify OCMiniOrb→reference existing-impl.md. If audio reactive→bind audioLevel to scaleEffect. If Metal needed→orb skill T5; metal-shaders for MSL.
1---2name: orb3description: [WHAT] Build animated SwiftUI orbs — Siri-style mesh gradients, particle spheres, and AI assistant visualizers. [HOW] 7 compositing techniques (MeshGradient, Canvas particles, Metal shaders, layer rotation, angular glow, hue-shift, animated masks) with code patterns and performance rules. [WHEN] Use when building or modifying animated orb UIs, voice chat visualizers, AI thinking indicators, Siri-style glows, particle effects, or the Kingly Clawd avatar. [WHY] Animated orbs require precise layering, 60fps budgets, accessibility compliance, and cross-platform (iOS/macOS) consistency. This skill encodes battle-tested patterns. Triggers: "orb", "siri animation", "mesh gradient", "voice visualizer", "particle sphere", "glow effect", "animated gradient", "MeshGradient", "Canvas animation", "TimelineView", "OCMiniOrb", "Clawd orb", "kaaba", "diamond orb", "ripple effect", "audio reactive"4---56# Orb — Animated SwiftUI Visualizer Skill78## Decision Tree910```11What are you building?12|13|-- Modify existing OCMiniOrb?14| |-- Add/change state? -> See: Existing Implementation15| |-- Tune layers? -> See: references/existing-impl.md16| \-- Add audio reactivity? -> Bind audioLevel to scaleEffect17|18|-- New orb variant?19| |-- Siri iOS 18 style (edge glow)? -> T1: MeshGradient + T2: AnimatedRectangle mask20| |-- Classic Siri (layered rotation)? -> T3: Layer rotation with Figma assets21| |-- Particle sphere (Jarvis)? -> T6: 3D particle system in Canvas22| |-- Kaaba/Diamond? -> See: references/variants.md23| \-- Glow button shadow? -> T7: Angular gradient + blur24|25|-- Performance issue?26| |-- Dropped frames? -> Check: fractal conditional removal, Canvas vs SwiftUI shapes27| |-- High CPU idle? -> Ensure TimelineView pauses when not visible28| \-- Memory growth? -> Check particle pool / recycle bin pattern29|30\-- Accessibility?31 \-- .accessibilityReduceMotion -> guard !reduceMotion else { return }32```3334## Quick Reference: 7 Techniques3536| # | Technique | API | Best For | Ref |37|---|-----------|-----|----------|-----|38| T1 | MeshGradient | `MeshGradient(width:height:points:colors:)` | Siri iOS 18 edge glow | `references/techniques.md#t1` |39| T2 | AnimatedRectangle | Custom `Shape` + `animatableData` | Breathing border mask | `references/techniques.md#t2` |40| T3 | Layer Rotation | `ZStack` + `.rotationEffect` + `.hueRotation` | Classic Siri icon | `references/techniques.md#t3` |41| T4 | Hue-Shift Gradient | `TimelineView` + `shiftHue()` | Color cycling backgrounds | `references/techniques.md#t4` |42| T5 | Metal Ripple | `ShaderLibrary.Ripple` + `.layerEffect` | Tap/activation ripple | `references/techniques.md#t5` |43| T6 | 3D Particle Sphere | `Canvas` + sphere projection math | Jarvis orb, particle clouds | `references/techniques.md#t6` |44| T7 | Angular Glow | `AngularGradient` + `.blur` | Button glow shadows | `references/techniques.md#t7` |4546## Existing Implementation (OCMiniOrb)4748**Path:** `packages/uikit/Sources/OCDesignKit/Components/OCMiniOrb.swift`49**Storybook:** `apps/storybook/Sources/Shared/MiniOrbPage.swift`50**Spec:** `docs/ux/orb/mini-clawd-spec.md`51526-layer stack in ZStack:5354| Layer | What | How |55|-------|------|-----|56| 1. Ambient Glow | `RadialGradient` + `.blur(size*0.25)` | Opacity pulse 0.2-0.35, 2s |57| 2. Base Orb | `RadialGradient` circle | Breathe 0.98-1.02, 3s; audio in speaking |58| 3. Fractal | `Canvas` + `TimelineView(1/30fps)` | 6 Fibonacci rings, conditional on state |59| 4. Glass | `RadialGradient` + `.ultraThinMaterial` | Static 0.85x |60| 5. Smoke | 4 orbiting blobs in `Canvas` | 3-6s rotation per blob |61| 6. Eyes | 2 white circles | Dim to 0.4 in thinking |6263**States:** `OrbDisplayState` — `.idle`, `.thinking`, `.speaking`, `.listening`64**Colors:** `OCColors.voiceOrb{State}Start/End`, `.voiceHighlight`, `.voiceParticle`6566## Performance Rules (NON-NEGOTIABLE)67681. **Canvas over shapes** — Use `Canvas` for particle systems (single draw call per layer)692. **Conditional hierarchy** — Remove fractal/smoke from view tree when idle: `if state == .thinking { ... }`703. **30fps cap** — `TimelineView(.animation(minimumInterval: 1.0 / 30.0))`714. **Reduce motion** — `@Environment(\.accessibilityReduceMotion)` guards ALL animation starts725. **Pool particles** — Recycle bin pattern (linked list, not array append/remove)736. **No SpriteKit** — Pure SwiftUI + Canvas + optional Metal747. **Target** — 60fps at 48pt on iPhone 12 / M1 Mac7576## Compositing Recipe: New Orb7778```swift79// Minimal orb skeleton80struct MyOrb: View {81 let state: OrbDisplayState82 var size: CGFloat = 4883 @Environment(\.accessibilityReduceMotion) private var reduceMotion8485 var body: some View {86 ZStack {87 // 1. Glow (always)88 Circle().fill(RadialGradient(...)).blur(radius: size * 0.25)89 // 2. Base (always)90 Circle().fill(RadialGradient(...)).scaleEffect(breatheScale)91 // 3. Active layers (conditional)92 if state != .idle {93 activeLayer(size) // Canvas-based94 }95 // 4. Glass (always)96 Circle().fill(...).background(.ultraThinMaterial.opacity(0.15))97 // 5. Highlights (always)98 eyeDots(size)99 }100 .frame(width: size * 1.3, height: size * 1.3)101 .accessibilityLabel("Assistant \(state.label)")102 }103}104```105106## Key Helper: sinInRange107108```swift109func sinInRange(_ range: ClosedRange<Float>, offset: Float, timeScale: Float, t: Float) -> Float {110 let amplitude = (range.upperBound - range.lowerBound) / 2111 let midPoint = (range.upperBound + range.lowerBound) / 2112 return midPoint + amplitude * sin(timeScale * t + offset)113}114```115116Used by MeshGradient (T1) and AnimatedRectangle (T2) for organic motion.117118## References119120| File | Content |121|------|---------|122| `references/techniques.md` | Full code for all 7 techniques with copy-paste patterns |123| `references/existing-impl.md` | OCMiniOrb layer-by-layer analysis, modification guide |124| `references/variants.md` | Kaaba/Diamond, particle sphere, mesh orb variant specs |125126## External Sources127128- [metasidd/PrototypeSiriAnimation](https://github.com/metasidd/PrototypeSiriAnimation) — iOS 18 Siri mesh gradient prototype129- [Rudrank Riyam — Siri Animation](https://rudrank.com/exploring-swiftui-creating-new-siri-animation) — MeshingAIProgressView deep dive130- [Hacking with Swift — MeshGradient](https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-a-mesh-gradient) — API reference131- [Amos Gyamfi — Siri Clone Gist](https://gist.github.com/amosgyamfi/b611c216604fd40a5aad2673fc5cf0b4) — Layer rotation approach132- [insidegui/MeshBuddy](https://github.com/insidegui/MeshBuddy) — Visual MeshGradient editor133134## Related Skills135136- **pencil** — Visual design prompts and character art for orb avatars (concept → prompt)137- **swiftui-animation** — General SwiftUI animation patterns (broader scope)138- **swiftui-performance-audit** — Runtime perf diagnostics (when orb causes frame drops)139## Technique Map140141- **6-layer ZStack compositing** — Ambient glow, base orb, fractal (conditional), glass, smoke, eyes; because layering order determines visual hierarchy and performance.142- **Canvas over shapes for particles** — Single draw call per layer; because SwiftUI shapes = many draw calls; Canvas = one.143- **Conditional hierarchy** — Remove fractal/smoke when idle; because redundant layers drain GPU when not visible.144- **30fps cap for TimelineView** — minimumInterval: 1.0/30.0; because 60fps for decorative layers wastes budget.145- **Reduce motion guard** — @Environment(\.accessibilityReduceMotion) on ALL animation; because accessibility compliance is non-negotiable.146- **sinInRange helper** — Organic motion for MeshGradient and AnimatedRectangle; because procedural variation feels more natural than linear.147- **Pool particles** — Recycle bin pattern, not array append/remove; because mid-frame allocation causes frame drops.148149## Technique Notes1501517 techniques: T1 MeshGradient, T2 AnimatedRectangle, T3 layer rotation, T4 hue-shift, T5 Metal ripple, T6 particle sphere, T7 angular glow. OCMiniOrb path: OCDesignKit/Components/OCMiniOrb.swift. Target: 60fps at 48pt on iPhone 12.152153---154155## Prompt Architect Overlay156157**Role Definition:** Animated SwiftUI orb builder. Siri-style mesh gradients, particle spheres, AI assistant visualizers. Encodes 7 compositing techniques with performance rules and accessibility compliance.158159**Input Contract:** Accepts orb variant (Siri iOS 18, classic Siri, particle sphere, Kaaba/Diamond), modification target (existing OCMiniOrb or new), or performance issue. State (idle/thinking/speaking/listening) if modifying existing.160161**Output Contract:** Layer-by-layer compositing recipe, technique references, performance rules checklist. SwiftUI code snippets. Accessibility labels. References to techniques.md, existing-impl.md, variants.md.162163**Edge Cases & Fallbacks:** If frame drops→check conditional hierarchy, Canvas vs shapes, particle count. If modify OCMiniOrb→reference existing-impl.md. If audio reactive→bind audioLevel to scaleEffect. If Metal needed→orb skill T5; metal-shaders for MSL.