# #117 Animation 操作ガイド

## 1. 役割
#117 Animation は独立した Motion UI です。Target UI 自身へAnimation実装を埋め込まず、Animation UI Number / Target UI Number / Target Part KEY のRelationで対象を指定します。

Relation Key: `animationUiNo::targetUiNo::targetPart`

## 2. HTML Functional Class
`bf-animation` は **Animation対象DOM自身へ付けるClassではありません**。Animation Relationを宣言する非表示の Relation Controller 要素です。Targetは `data-ui-no` と `data-ui-part` で公開します。任意CSS selectorは使いません。

```html
<button data-ui-no="UI-BUTTON-001">
  <span data-ui-part="button-text">保存</span>
</button>
<div class="bf-animation"
  data-animation-ui-no="UI-117-001"
  data-target-ui-no="UI-BUTTON-001"
  data-target-part="button-text"
  data-animation="pulse"
  data-speed="normal"
  data-loop="true"
  data-loop-wait-ms="300"
  data-autoplay="true"></div>
```

## 3. 正式Animation 7種
- `move` — 軸方向へ直線移動して戻る。`distance` をpxで指定する。
- `bounce` — Moveとは別Motion。垂直ジャンプ → 着地Squash → 減衰Reboundで跳ねる。`bounceHeight`(px) / `bounceCount`(1–6)を数値指定する。
- `pulse` — 拡大縮小。
- `spin` — 元の自転Motion。inside / outsideとも同じ `rotate()` Motionで、`spinDegrees`(deg)を数値指定する。insideはTarget UI内でclip、outsideはclipせず表示する。
- `blink` — glyph / surface opacity点滅。
- `slide` — 要素内専用。`slideMode=in|out`、Defaultは `in`。IN / OUTともTarget UI内でclipし、移動量は `distance` pxだけを使用する。
- `zoom` — inside / outsideとも同じ `1.0 → zoomScale → 1.0` の大きいZoom Motion。insideはTarget UI内でclip、outsideはclipせず要素外まで表示する。Defaultは `outside`。

## 4. Flow Preset 4種
- `flow`
- `shimmer`
- `glow-sweep`
- `breathing-glow`

Button内文字 / Text / Label / Icon では Flow / Shimmer / Glow Sweep は四角いOverlayを重ねず、glyph foregroundにgradientを流します。Button全体 / Panel / Box / Fill / Thumbではsurface表示を使用します。

## 5. Property
- `animationUiNo`: `UI-...`
- `targetUiNo`: `UI-...`
- `targetPart`: `whole / button-text / text / label / icon / panel / box / fill / thumb`
- `animation`: 正式7種 + Flow Preset 4種
- `direction`: `forward / reverse`
- `axis`: `horizontal / vertical`
- `speed`: `slow / normal / fast`
- `distance`: 0–10000。Move / Slideの移動量(px)。SlideではTarget実寸を加算しない。
- `bounceHeight`: 1–2000px / Default `48`
- `bounceCount`: 1–6の整数 / Default `2`
- `spinScope`: `inside | outside` / Default `inside`
- `spinDegrees`: 1–3600deg / Default `360`
- `slideMode`: `in | out` / Default `in`
- `zoomScope`: `inside | outside` / Default `outside`
- `zoomScale`: 1.01–5.00 / Default `1.80`
- `loop`: boolean / Default `true`
- `loopWaitMs`: 0–60000ms / Default `300`
- `respectReducedMotion`: boolean / Default `true`
- `autoplay`: boolean / Default `false`

## 6. Target分離
Button wholeは背景・Border・Contentを含むButton全体を動かします。Button textはButton本体を固定して文字DOMだけを動かします。Text/Labelは文字、IconはIcon、Panel/BoxはSurface、FillはProgress Fill、ThumbはSlider Thumbだけを対象にします。

## 7. Lifecycle
`play()` / `pause()` / `resume()` / `stop()` / `restart()` / `destroy()`。`attach()`を別Targetへ再実行した場合は旧Targetの一時styleとFlow layerをcleanupしてからretargetします。Animation種類の`update()`でも旧Flow styleを残しません。

## 8. #117 Loop WAIT
1 cycle終了 → `loop=true` の場合 `state=waiting` → `loopWaitMs` 後に次cycle。WAIT中Pauseは `paused-wait`、Resumeは残りWAIT時間から再開します。Stop / Destroyは予約済みtimerも解除します。

これは #002 Joint WAIT / FIFO / BLOCKED と別です。#117 Loop WAITはAnimation内部cycle待機であり、#002 Delivery Channelへ混ぜません。

## 9. Relation / #002 Joint
接続イメージでは #002 Bone Joint正式APIを使用し、Source → #117 Animation → TargetをIN / OUTで表示します。`targetPart`はTargetのField/Part情報であり、独立Nodeを追加しません。正式5ケースは、正常接続（IN / OUT）、IN Target Field不存在、OUT Target Field不存在、型不一致（IN）、型不一致（OUT）です。正常接続はSource/Target Fieldともtrue、Compatibility=OK、Joint State=CONNECTEDを実評価結果から表示します。

### OUT WAIT / BLOCKED - #002 Joint v1.1.36 Integration
#117 AnimationはAnimation output生成までを担当し、Target Busy / WAIT queue / FIFO / BLOCK判定後の配送停止は#002 Jointへ委譲します。通常Previewおよび#117 Loop WAITとは分離した専用Delivery Channelで確認します。

- WAIT: Target BUSY → outputをQueueへ登録 → 接続線維持 + spinner → Target READY → FIFOで自動配送 → READY。
- BLOCKED: Target READYのままGuardで危険outputをBLOCK → 接続線維持 + fa-ban / beat-fade → Target配送件数は増えない。
- 目視確認: WAITでは線が切れず自動配送されること、BLOCKEDでは線が切れず危険outputがTargetへ届かないことを確認します。

## 10. Security
任意CSS selectorは禁止。Allow-list済みのUI Number / targetPart / animation / direction / axis / speed / distance / bounceHeight / bounceCount / spinScope / spinDegrees / slideMode / zoomScope / zoomScale / loop / loopWaitMs / reduced-motion / autoplayのみ受け取ります。Security Testでは NaN / Infinity / 負値 / Unknown Animation / Unknown Part / Unknown Direction / Unknown Axis / Invalid Target UI / CSS selector-like Target / getter-setter をRejectします。Previewとは独立して検証します。

## 11. Public API
`defaults()` / `normalizeOptions()` / `validateOptions()` / `inspectUntrustedOptions()` / `resolveRelationKey()` / `durationForSpeed()` / `buildPlan()` / `create()` / `isInstance()` / `attach()` / `update()` / `play()` / `pause()` / `resume()` / `stop()` / `restart()` / `getState()` / `getOutput()` / `destroy()` / `getAvailableAnimations()` / `getFormalAnimations()` / `getFlowAnimations()`

## 12. Motion責務分離
- #118 Transition: 状態A→状態BのENTER/EXIT補間。#117 continuous Animationとは別。
- #120 Trigger: start condition。
- #121 Timeline: 複数MotionのDelay / Duration / Repeat / Sequence / Parallel orchestration。
- #122 KeyFrame: 任意keyframe authoring。

## 13. reduced motion
`respectReducedMotion=true` かつOSがreduceの場合、Motionを開始せず `state=reduced-motion` を記録します。

## 14. Completion
Smoke / Validation ALL PASS、Animation目視、Button全体、Button内文字、Flow glyph、Loop WAIT、Joint状態、Guide確認が揃った後だけCompletion可能です。ユーザーlocalhost確認前はDevelopmentです。


## 15. Move / Bounce / Spin / Slide / Zoom 設定

### Move と Bounce
Moveは直線移動です。Bounceはジャンプ、着地Squash、減衰Reboundを持つ別Motionです。`bounceHeight` と `bounceCount` を数値で変更できます。

### Spin
Spinは元の自転Motionへ戻します。inside / outsideとも `rotate(0deg) → rotate(spinDegrees)` の同じ動きです。insideはTarget UI内でclipし、outsideはclipせず元の回転をそのまま表示します。外部Pivotは使用しません。

### Slide
Slideは要素内専用です。`slideMode=in` がDefault。INは `-distance → 0`、OUTは `0 → +distance` の一方向Motionで、Part TargetではTarget UIをcontainment hostとしてclipします。Target幅/高さはDistanceへ加算せず、要素外Scopeも持ちません。

### Zoom
inside / outsideとも動きは同一で、`1.0 → zoomScale → 1.0` と大きくZoomして戻ります。違いは表示範囲だけです。`inside` はTarget UI内にclipし、`outside` は要素外まで表示します。Defaultは `outside / 1.80` です。
