# Animations API

`u-space` 提供了 `Tween` 类和 `tweenAnimation` 辅助函数，用于对任意数值属性进行动画处理。两者都是对 [`@tweenjs/tween.js`](https://github.com/tweenjs/tween.js) 的轻量封装，并自动与 `Viewer` 渲染循环集成。

## `tweenAnimation`

对任意对象属性执行动画的最简方式，返回一个在动画完成后 resolve 的 `Promise`。

```typescript
import { tweenAnimation } from 'u-space';

const source = { x: 0, y: 0, z: 0 };

await tweenAnimation(
  viewer,
  source,                      // 可变的起始状态（每帧被修改）
  { x: 10, y: 5, z: 10 },    // 目标状态
  {
    duration: 1500,            // 毫秒
    delay: 0,
    mode: 'Cubic.InOut',
    repeat: false,
    yoyo: false,
  },
  (current) => {
    // 每帧以插值结果调用
    myObject.position.set(current.x, current.y, current.z);
  },
);
```

### `AnimationOptions`

| 属性       | 类型                        | 默认值          | 说明                                               |
| :--------- | :-------------------------- | :-------------- | :------------------------------------------------- |
| `duration` | `number`                    | `1000`          | 动画时长（毫秒）。                                 |
| `delay`    | `number`                    | `0`             | 开始延迟（毫秒）。                                 |
| `mode`     | `AnimationModeType`         | `'Linear.None'` | 缓动函数。                                         |
| `repeat`   | `number \| boolean`         | `false`         | 额外重复次数，或 `true` 表示无限循环。             |
| `yoyo`     | `boolean`                   | `false`         | 在每个循环周期反向播放。                           |

### `AnimationModeType`

支持所有标准缓动模式：

`Linear.None` · `Quadratic.In/Out/InOut` · `Cubic.In/Out/InOut` · `Quartic.In/Out/InOut` · `Quintic.In/Out/InOut` · `Sinusoidal.In/Out/InOut` · `Exponential.In/Out/InOut` · `Circular.In/Out/InOut` · `Elastic.In/Out/InOut` · `Back.In/Out/InOut` · `Bounce.In/Out/InOut`

## `Tween`

提供完全控制的底层类。继承自 `tween.js` 的基础 `Tween`，并通过 `addEventListener('afterControlsUpdate', ...)` 挂入 `Viewer` 事件循环。

```typescript
import { Tween } from 'u-space';

const source = { opacity: 1 };

const tween = new Tween(viewer, source)
  .to({ opacity: 0 }, 800)
  .easingByMode('Sinusoidal.Out')
  .onUpdate((s) => {
    myMaterial.opacity = s.opacity;
    viewer.render();
  })
  .onComplete(() => console.log('完成'));

tween.start();
// tween.stop();
```

### 方法

| 方法                      | 说明                                                            |
| :------------------------ | :-------------------------------------------------------------- |
| `easingByMode(mode)`      | 使用 `AnimationModeType` 设置缓动函数的便捷简写。               |
| `start(time?)`            | 启动补间并注册到 viewer 循环中。                                |
| `stop()`                  | 停止补间并从 viewer 循环中注销。                                |

其他方法（`to`、`delay`、`repeat`、`yoyo`、`onUpdate`、`onComplete`、`onStop`、`onStart`）均继承自 `tween.js` 的基础 `Tween` 类。
