```xml
下面给你升级版:**可视区域固定 5 张卡片,不足 5 张循环补全,超出 5 张只显示 5 张,样式完全不变**。实现方式是卡片池固定 5 张,通过“槽位循环复用”来显示任意数量的图片,而不是之前那样渲染 N 张卡片。
## 一、核心思路
```
5 个槽位:[-2] [-1] [ 0] [+1] [+2]
↑ ↑ ↑ ↑ ↑
图片 图片 当前 图片 图片
槽位 s 显示图片 = (current + s + N) % N
- N < 5:槽位会重复出现同一张图片,视觉上循环补全
- N = 5:正好 5 张
- N > 5:只有 5 张同时可见,其它通过槽位旋转进出
```
**卡片不再按图片数量渲染,而是固定 5 个 DOM 元素。** 切换时:
1. 每张卡片的槽位 `k` 减 `delta`。
2. `k` 超出 `[-2, 2]` 的卡片绕回另一端,并重新绑定图片。
3. 从屏幕外滑入,形成循环。
## 二、完整预览文件
保存为 `.html` 双击打开即可。
```html
叠加灯箱画廊 · 5 槽位循环
```
## 三、行为说明
| 图片数量 | 表现 |
|---|---|
| 1 张 | 5 个槽位全部显示同一张,切换无变化,点击中间可展开 |
| 2~4 张 | 5 个槽位循环排列,切换时循环滚动 |
| 5 张 | 正好 5 张,与上一版一致 |
| 6 张以上 | 可视区域始终 5 张,其余通过左右循环进出 |
## 四、关键实现说明
1. **固定 5 张卡片**:`for (let i = 0; i 5` 时只有 5 张同时可见。
3. **循环进出**:`step(delta)` 里每张卡片的 `k` 减 `delta`,超出 `[-2, 2]` 的卡片绕到另一端,并从 `±3`(屏幕外)滑入,形成无限循环。
4. **图片懒切换**:`setCardContent()` 检查 `card.imgIdx !== idx` 才更新 `src`,避免 `N = 5` 时同一张图被反复重载而闪烁。
5. **大图与扇形同步**:`step()` 改 `current` 并更新扇形;`switchExpanded()` 读同一个 `current` 更新大图,两者天然一致。
6. **关闭对齐**:`collapse()` 用 `getCenterCard()` 找到当前 `k = 0` 的卡片作为缩回目标,保证大图还原后落在扇形正中。
## 五、可调参数
| 想改什么 | 改哪里 |
|---|---|
| 卡片大小 | `:root` 的 `--card-w` / `--card-h` |
| 叠加幅度、旋转 | `POS` 里的 `x / y / rot / scale` |
| 外层透明度 | `POS` 里的 `op` |
| 屏幕外滑入位置 | `POS['-3']` / `POS['3']` |
| 拖拽层次感 | `transformString()` 里的 `0.28` / `0.22` |
| 拖拽切换阈值 | `endDrag()` 里的 `Math.min(60, innerWidth * 0.12)` |
| 拖拽阻尼 | `pointermove` 里的 `dx * 0.9` |
## 六、验收点
- 5 张图:和之前完全一样。
- 3 张图:扇形里能看到重复图片,切换循环滚动。
- 10 张图:始终只显示 5 张,左右切换时新图从屏幕外滑入。
- 拖拽、箭头、圆点、键盘、大图放大、大图切换、关闭对齐:全部正常。
如果你希望**圆点在图片超过 10 张时折叠成滚动条**,或者**少于 5 张时不显示重复、只显示实际数量**,告诉我,我再加一个开关。
```



