npm package: @felix-yang/frame-panorama-viewer
Description: A framework-free 360 frame panorama viewer for browser pages, CDNs, and object storage image sequences.
Author: felix-yang
Latest version: 0.1.0

# Frame Panorama Viewer Plugin

这是一个不依赖框架的 360 逐帧图片插件。

它有两种接入方式：

1. 直接写自定义标签 `<frame-panorama-viewer>`
2. 用全局 JS API `new FramePanoramaViewer(...)`

这意味着任何后端语言都能直接用，只要页面能输出 HTML 并引用 `frame-panorama-viewer.js` 即可。

## npm 初始化

项目已经补好了 npm 发布基础文件：

- `package.json`
- `.npmignore`
- `LICENSE`

发布前你只需要检查并修改 `package.json` 里的这些字段：

- `name`
- `version`
- `author`
- `repository`
- `homepage`
- `bugs`

当前已经按 npm 用户名先默认填成了 scoped 包名：

```json
"name": "@felix-yang/frame-panorama-viewer"
```

如果这个仓库地址和你真实的 GitHub 地址不一致，再改成你自己的即可。

## 发布命令

```bash
npm login
npm run check
npm run pack:dry
npm run release:public
```

如果只是本地打包预览：

```bash
npm pack
```

## 启动 Demo

1. 运行 `start-server.cmd`
2. 打开 `http://localhost:8000`

## 用法一：HTML 标签

```html
<script src="/frame-panorama-viewer.js"></script>

<frame-panorama-viewer
  frame-base-path="/assets/frames/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="36"
  fit="contain"
  aspect-mode="auto"
  show-controls="true"
  show-indicator="true">
</frame-panorama-viewer>
```

## 用法二：JS API

```html
<script src="/frame-panorama-viewer.js"></script>
<div id="viewer"></div>
<script>
  new FramePanoramaViewer(document.getElementById("viewer"), {
    frameBasePath: "/assets/frames/",
    filePrefix: "frame_",
    fileExtension: "jpg",
    zeroPadding: 4,
    frameSequence: [1, 2, 3, 4, 5, 6],
    fit: "contain",
    aspectMode: "auto"
  });
</script>
```

## 直接传完整图片数组

```html
<frame-panorama-viewer
  frames='["/uploads/1.jpg","/uploads/2.jpg","/uploads/3.jpg"]'
  fit="cover"
  aspect-mode="auto">
</frame-panorama-viewer>
```

这适合用户上传后，由你的后端直接把图片 URL 数组输出到页面里。

## 配置项

- `frames`: 完整图片 URL 数组，JSON 字符串
- `frame-base-path`: 图片目录，支持相对路径和完整链接，比如 `/assets/frames/` 或 `https://example.com/images/`
- `file-prefix`: 文件名前缀
- `file-extension`: 文件后缀
- `zero-padding`: 补零位数
- `frame-sequence`: 支持两种写法

`frame-sequence="28"` 表示自动生成 `1...28`
`frame-sequence="1,2,3,4,6,7"` 表示手动指定不连续编号

如果你的图片是连续编号，比如 `frame_0001.jpg` 到 `frame_0028.jpg`，直接写 `frame-sequence="28"` 就行。
如果中间缺号，比如缺了 `frame_0005.jpg`，就写成 `frame-sequence="1,2,3,4,6,7..."`。

例如：

```html
<frame-panorama-viewer
  frame-base-path="https://example.com/pano/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="28">
</frame-panorama-viewer>
```

插件会自动拼成：

```text
https://example.com/pano/frame_0001.jpg
https://example.com/pano/frame_0002.jpg
...
https://example.com/pano/frame_0028.jpg
```

## CDN 和对象存储

`frame-base-path` 可以直接传 CDN 或对象存储目录地址，插件会自动继续拼接 `file-prefix + 序号 + 后缀`。

阿里云 OSS：

```html
<frame-panorama-viewer
  frame-base-path="https://your-bucket.oss-cn-shanghai.aliyuncs.com/pano/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="28">
</frame-panorama-viewer>
```

腾讯云 COS：

```html
<frame-panorama-viewer
  frame-base-path="https://your-bucket.cos.ap-shanghai.myqcloud.com/pano/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="28">
</frame-panorama-viewer>
```

七牛云：

```html
<frame-panorama-viewer
  frame-base-path="https://cdn.yourdomain.com/pano/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="28">
</frame-panorama-viewer>
```

Amazon S3：

```html
<frame-panorama-viewer
  frame-base-path="https://your-bucket.s3.ap-east-1.amazonaws.com/pano/"
  file-prefix="frame_"
  file-extension="jpg"
  zero-padding="4"
  frame-sequence="28">
</frame-panorama-viewer>
```

如果你已经拿到了每一张图的完整 URL，也可以不用 `frame-base-path`，直接传 `frames`：

```html
<frame-panorama-viewer
  frames='[
    "https://cdn.example.com/pano/frame_0001.jpg",
    "https://cdn.example.com/pano/frame_0002.jpg",
    "https://cdn.example.com/pano/frame_0003.jpg"
  ]'>
</frame-panorama-viewer>
```
- `drag-step`: 拖拽多少像素切一帧
- `autoplay-interval`: 自动播放间隔，毫秒
- `fit`: `contain` 或 `cover`
- `aspect-mode`: `auto`、`square`、`portrait`、`landscape`、`custom`
- `aspect-ratio`: 自定义比例，比如 `16 / 9`
- `show-controls`: 是否显示按钮
- `show-indicator`: 是否显示帧数

## 横图和竖图适配

- 默认 `aspect-mode="auto"`，会根据第一张图自动计算容器比例
- `fit="contain"` 适合尽量完整显示图片
- `fit="cover"` 适合铺满容器，可能会裁切
- 用户上传横图、竖图、方图都可以直接用

## 适合什么场景

- 电商 360 商品展示
- 门店或展厅逐帧全景
- 用户上传一组图片后生成交互查看器
- 任何能输出 HTML 的服务端项目