# housePlay使用说明文档（全）

## 概述

`housePlay` 是当zqsdk初始化完成后，挂在到window上的一个实例对象。此对象用于控制VR场景相关功能，如点位跳转，场景跳转，模式切换，导览播放， AI讲房等等。


## 预先完成
要使用housePlay对象，需要先完成zqsdk的初始化步骤，请参考文档：[VR 初始化展示指南](../功能模块指南/VR初始化展示指南.md)

代码示例
```javascript
// 初始化zqsdk
window.zqsdk.init({
    modelId: id,
    // (可选) 资源请求配置
    // 当众趣模型的静态资源需要在客户自己的服务器维护时使用
    // 需要设置资源请求的域名
    resourceRequestConf: {
        resourceType: 'custom_host',
        customDomain: 'https://your_domain.com/',
    },
    complete: () => {
        // 此处可在window上获取到housePlay实例
        const housePlay = window.housePlay

        housePlay.start() // 执行渲染
    },
})
```

---

## 核心方法

### start()

开始场景渲染。

#### 参数

无

#### 示例

```javascript
housePlay.start();
```



---

## 模式切换

### changeMode(mode)

切换场景显示模式。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| mode | string | 是 | 目标模式：`'panorama'`（全景）、`'dollhouse'`（3D模型）、`'floorplan'`（平面图） |

#### 返回值

- `false`：如果场景不支持3D模式切换

#### 示例

```javascript
housePlay.changeMode('panorama');
housePlay.changeMode('dollhouse');
housePlay.changeMode('floorplan');
```

---

### changeShowMode(mode)

切换装修显示模式。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| mode | string | 是 | 显示模式: normal(实景模式)，leftmain（全屏换装模式），split（分屏换装模式） |

#### 返回值

- `false`：如果场景不支持装修模式

#### 示例

```javascript
housePlay.changeShowMode('split'); // 显示模式: normal(实景模式)，leftmain（全屏换装模式），split（分屏换装模式）
```

---

## 导航与漫游

### goToPanoById(locationId, quaternion, time, callback)

跳转到指定全景点位。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| locationId | string | 是 | 目标点位ID |
| quaternion | Object | 否 | 目标视角四元数 `{x, y, z, w}` |
| time | number | 否 | 过渡时间（毫秒） |
| callback | Function | 否 | 完成回调函数 |

#### 示例

```javascript
housePlay.goToPanoById('location_01', { x: 0, y: 0, z: 0, w: 1 }, 1000, function() {
    console.log('跳转完成');
});
```

---

### gotoRoam(rid)

跳转到指定漫游点。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| rid | string | 是 | 漫游点ID |

#### 示例

```javascript
housePlay.gotoRoam('roam_001');
```

---

### gotoScenebyId(id)

跳转到指定场景。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | number | 是 | 场景列表索引 |

#### 示例

```javascript
housePlay.gotoScenebyId(1);
```



---

### gotoFloor(floor)

切换到指定楼层。此方法只能在floorplan模式或dollhouse模式下调用

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| floor | string/number | 是 | 楼层ID或 `'all'` 显示所有楼层 |

#### 示例

```javascript
housePlay.gotoFloor(0);      // 跳转到第一层
housePlay.gotoFloor('all');  // 显示所有楼层
```

---



## 播放控制

### play(sceneIndex)

播放讲房或导览。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| sceneIndex | string | 否 | scene列表索引 |

#### 示例

```javascript
housePlay.play();           // 从头播放
housePlay.play(2); // 从指定场景开始播放
```

---

### pause()

暂停讲房或导览。

#### 示例

```javascript
housePlay.pause();
```

---

### startLecture(preonline, info)

开始或继续智能讲房。

#### 参数

无

#### 示例

```javascript
housePlay.startLecture();
```

---

### pauseLecture()

暂停智能讲房。

#### 示例

```javascript
housePlay.pauseLecture();
```

---

### goToLectureByName(name)

跳转到指定名称的讲房节点。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| name | string | 是 | 讲房节点名称取值: <br />uptown_inside（小区内部）<br />uptown_outside（周边配套）<br />house_parse（户型解析）<br />house_info（房源信息） |

#### 示例

```javascript
housePlay.goToLectureByName('uptown_inside'); // 取值 uptown_inside（小区内部） | uptown_outside（周边配套） | house_parse（户型解析） | house_info（房源信息） 
```

---



## VR 模式

### enterVR()

进入手机VR模式（配合VR眼镜使用）。

#### 返回值

- `true`：成功进入VR模式
- `false`：不支持VR模式（非全景模式或非移动端）

#### 示例

```javascript
if (housePlay.enterVR()) {
    console.log('已进入VR模式');
}
```

---

### exitVR()

退出VR模式。

#### 示例

```javascript
housePlay.exitVR();
```

---



## 标签管理

### enableTag()

显示所有标签。

#### 示例

```javascript
housePlay.enableTag();
```

---

### disableTag()

隐藏所有标签。

#### 示例

```javascript
housePlay.disableTag();
```

---

### showFakeTag(type, style, url, modal)

显示临时标签（编辑模式使用）。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| type | string | 是 | 热点类型 |
| style | string | 是 | 样式 |
| url | string | 是 | 图片地址 |
| modal | number | 是 | 模式：0=新增，1=编辑，2=室外热点 |

#### 示例

```javascript
housePlay.showFakeTag('info', 'default', 'https://example.com/icon.png', 0);
```

---

### hideFakeTag(type)

隐藏临时标签。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| type | string | 是 | 标签类型（`'-1'` 或 `'-2'`） |

#### 示例

```javascript
housePlay.hideFakeTag('-1');
```

---



## 全景标尺

### enablePanramaSize()

显示全景标尺。

#### 示例

```javascript
housePlay.enablePanramaSize();
```

---

### disablePanramaSize()

隐藏全景标尺。

#### 示例

```javascript
housePlay.disablePanramaSize();
```

---



## 自动旋转

### autoRotateStartAnimation()

开始自动旋转动画。

#### 示例

```javascript
housePlay.autoRotateStartAnimation();
```

---

### autoRotateStopAnimation()

停止自动旋转动画。

#### 示例

```javascript
housePlay.autoRotateStopAnimation();
```



## 状态获取

### getCurrentState()

获取当前状态信息。

#### 返回值

```javascript
{
    panoSize: boolean  // 全景标尺是否启用
}
```

#### 示例

```javascript
var state = housePlay.getCurrentState();
console.log('全景标尺状态:', state.panoSize);
```

---

### getCurrentView()

获取当前视角信息。

#### 返回值

```javascript
{
    location_id: string,  // 当前点位ID
    rotation: {           // 相机旋转四元数
        x: number,
        y: number,
        z: number,
        w: number
    }
}
```

#### 示例

```javascript
var view = housePlay.getCurrentView();
if (view) {
    console.log('当前点位:', view.location_id, view.rotation);
}
```

---

### getWorldDirection()

获取当前世界方向。

#### 返回值

- 当前状态对象

#### 示例

```javascript
var direction = housePlay.getWorldDirection();
```

---

### getcurrentPanoid()

获取当前全景点位ID。

#### 返回值

- `string`：当前点位ID

#### 示例

```javascript
var panoId = housePlay.getcurrentPanoid();
console.log('当前点位ID:', panoId);
```

---

## 坐标转换

### getModelScreenSize()

获取模型在屏幕上的投影尺寸。

#### 返回值

```javascript
{
    width: number,   // 宽度（像素）
    height: number,  // 高度（像素）
    top: number,     // 顶部位置
    left: number     // 左侧位置
}
```

#### 示例

```javascript
var size = housePlay.getModelScreenSize();
console.log('模型尺寸:', size.width, 'x', size.height);
```

---

### getCurrentFloorScreenSize()

获取当前楼层在屏幕上的投影尺寸。

#### 返回值

```javascript
{
    width: number,
    height: number,
    top: number,
    left: number,
    size: {
        x: number,  // 实际宽度
        z: number   // 实际深度
    },
    points: {
        ltPoint: Vector3,  // 左上角
        rtPoint: Vector3,  // 右上角
        rbPoint: Vector3,  // 右下角
        lbPoint: Vector3   // 左下角
    }
}
```

---

### getFloorPlanParam()

获取户型图参数。

#### 返回值

```javascript
{
    model: Object,
    project: Object,
    floorIndex: number,
    radar: {
        uv: { u: number, v: number },
        angle: number
    }
}
```

---

### getFloorPlanParam2()

获取户型图参数（新版本）。

#### 返回值

同 `getFloorPlanParam()`，增加了更精确的UV计算。

---

### getScreenPositionInFloorPlan(vectorPosition)

将3D坐标转换为屏幕坐标（透视相机）。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| vectorPosition | THREE.Vector3 | 是 | 3D向量坐标 |

#### 返回值

```javascript
{
    screenX: number,
    screenY: number
}
```

---

### getScreenPositionInFloorPlan2(vectorPosition)

将3D坐标转换为屏幕坐标（正交相机）。

#### 参数

同 `getScreenPositionInFloorPlan()`

#### 返回值

同 `getScreenPositionInFloorPlan()`

---

### getCurrentFloorAllPanosScreenPosition()

获取当前楼层所有全景点的屏幕坐标。

#### 返回值

```javascript
[
    {
        position: { screenX: number, screenY: number },
        id: string
    },
    // ...
]
```

#### 示例

```javascript
var positions = housePlay.getCurrentFloorAllPanosScreenPosition();
positions.forEach(function(item) {
    console.log('点位', item.id, '屏幕位置:', item.position);
});
```

---

### getCurrentRadarPostionInFloorPlan()

获取当前雷达在户型图中的位置。

#### 返回值

```javascript
{
    uv: { u: number, v: number },
    angle: number
}
```

---

### getRadarData(currentPosition, floorIndex)

获取指定位置的雷达数据。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| currentPosition | THREE.Vector3 | 是 | 当前位置 |
| floorIndex | number | 否 | 楼层索引 |

#### 返回值

```javascript
{
    uv: { u: number, v: number },
    angle: number,
    size: { width: number, height: number }
}
```

---

## 其他方法

### getScreenShot(startX, startY, width, height)

获取屏幕截图。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| startX | number | 否 | 起始X坐标 |
| startY | number | 否 | 起始Y坐标 |
| width | number | 否 | 截图宽度 |
| height | number | 否 | 截图高度 |

截图完成后会触发 `screenshot` 事件，返回 base64 编码的图片数据。

#### 示例

```javascript
housePlay.on('screenshot', function(base64Code) {
    // 处理截图
    var img = new Image();
    img.src = base64Code;
});

housePlay.getScreenShot(); // 全屏截图
housePlay.getScreenShot(0, 0, 800, 600); // 指定区域截图
```

---

### compassAdjust(value, type)

调整指南针角度。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| value | number | 是 | 调整值 |
| type | number | 是 | 类型：0=重置，其他=增加 |

#### 示例

```javascript
housePlay.compassAdjust(0, 0);   // 重置指南针
housePlay.compassAdjust(10, 1); // 增加10度
```

---

### compassAdjustSetVisible(flag)

设置指南针可见性。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| flag | boolean | 是 | 是否可见 |

#### 示例

```javascript
housePlay.compassAdjustSetVisible(true);
```

---

### adjustAngle(axis, direction)

调整当前全景的角度。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| axis | string | 是 | 轴向 |
| direction | number | 是 | 方向 |

---

### removeScene(location)

移除场景。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| location | string | 是 | 场景位置ID |

---

### getCurrentHouseTypeImage()

获取当前户型图图片URL。

#### 返回值

- `string`：图片URL

---

### canUseNewFloorPlan()

检查是否可以使用新版户型图。

#### 返回值

- `boolean`

---



### disableSwitchPano()

禁用全景切换。

---

### enableSwitchPano()

启用全景切换。

---



## 同步相关（带看功能）

### syncRemoteActions(actionMsg)

同步远程操作。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| actionMsg | Object | 是 | 操作消息 |

---

### firstSyncRemoteActions(actionMsg)

首次同步远程操作。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| actionMsg | Object | 是 | 操作消息 |

---

### setConnectionStatus(actionMsg)

设置连接状态。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| actionMsg | Object | 是 | 状态消息 |

---

### setValidOperator(operator)

设置有效操作者。

#### 参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| operator | Object | 是 | 操作者信息 |

---



## 事件系统

HousePlay 继承自 EventEmitter，支持事件监听。

### 监听事件

```javascript
housePlay.on('eventName', function(data) {
    // 处理事件
});
```

### 移除监听

```javascript
housePlay.off('eventName', handler);
```

### 可用事件列表

| 事件名 | 触发时机 | 回调参数 |
|--------|----------|----------|
| `initLoading` | 初始化加载开始 | - |
| `startLoading` | 开始加载 | model, flag, qFlag, settings |
| `endLoading` | 加载完成 | mode |
| `load_progress` | 加载进度更新 | progress (0-100) |
| `afterRender` | 首次渲染完成 | - |
| `modeChange` | 模式切换 | currentMode, newMode |
| `panoChange` | 全景点位变化 | { pano, time, showArea } |
| `panoChosen` | 选择全景点位 | player |
| `floorChange` | 楼层变化 | { mode, model, project, floorIndex, imageUrl } |
| `flyingEnd` | 飞行动画结束 | result |
| `compass` | 指南针角度变化 | { angle, director } |
| `move` | 移动状态 | player |
| `spinner` | 加载圈状态 | state |
| `stopTour` | 停止导览 | - |
| `updateTour` | 更新导览状态 | describe, is360view |
| `highLightsBarChange` | 场景条变化 | id, settings |
| `updatePanoSize` | 全景尺寸更新 | style, isShow, data |
| `enterPoint` | 进入点位 | panoId |
| `screenshot` | 截图完成 | base64Code |
| `lectureUpdate` | 讲房进度更新 | index/playStyle, percent |
| `lectureEnd` | 讲房结束 | 'lectureEnd' |
| `lecturePause` | 讲房暂停 | 'lecturePause'/'stop' |
| `lectureError` | 讲房错误 | errorType |
| `lectureLoadaudio` | 讲房音频加载 | state |
| `lecutreUI` | 讲房UI状态 | UI, state |
| `connect_ui_operation` | UI操作连接 | mapAction |
| `lectureNextPlayStyle` | 下一个播放样式 | lectureNextPlayStyle |
| `decorateMode` | 装修模式变化 | mode |
| `validOperatorChanged` | 有效操作者变化 | operator |
| `LocalProgramLoadingCompleted` | 本地程序加载完成 | - |
| `uploadLocalActions` | 上传本地操作 | action |
| `firstSyncActionsCompleted` | 首次同步完成 | - |
| `firstSyncActionsFail` | 首次同步失败 | - |
| `bumpStart` | 碰撞开始 | - |
| `init_UI` | UI初始化 | model |
| `addTagData` | 添加标签数据 | data |
| `intoTypedPano` | 进入类型化全景 | type |
| `updateAngleValue` | 角度值更新 | { id, adjustAngleX, adjustAngleY, adjustAngleZ } |

### 标签事件

| 事件名 | 触发时机 | 回调参数 |
|--------|----------|----------|
| `tag.active` | 标签激活 | tagData |
| `tag.dismiss` | 标签关闭 | tagData |

### 事件使用示例

```javascript
// 监听加载进度
housePlay.on('load_progress', function(progress) {
    console.log('加载进度:', progress + '%');
});

// 监听模式切换
housePlay.on('modeChange', function(currentMode, newMode) {
    console.log('模式从', currentMode, '切换到', newMode);
});

// 监听全景点位变化
housePlay.on('panoChange', function(data) {
    console.log('当前点位:', data.pano.id);
});

// 监听指南针角度
housePlay.on('compass', function(result) {
    console.log('指南针角度:', result.angle);
});

// 监听加载完成
housePlay.on('afterRender', function() {
    console.log('场景渲染完成');
});
```

---

## 完整使用示例

```javascript
// 注册事件
function registerEvents(housePlay) {
  	housePlay.on('load_progress', function(progress) {
    	console.log('加载进度:', progress + '%');
	});

    // 监听模式切换
    housePlay.on('modeChange', function(currentMode, newMode) {
        console.log('模式从', currentMode, '切换到', newMode);
    });

    // 监听全景点位变化
    housePlay.on('panoChange', function(data) {
        console.log('当前点位:', data.pano.id);
    });

    // 监听指南针角度
    housePlay.on('compass', function(result) {
        console.log('指南针角度:', result.angle);
    });

    // 监听加载完成
    housePlay.on('afterRender', function() {
        console.log('场景渲染完成');
    }); 
}

// 初始化zqsdk
window.zqsdk.init({
    modelId: id,

    // (可选) 资源请求配置
    // 当众趣模型的静态资源需要在客户自己的服务器维护时使用
    // 需要设置资源请求的域名
    resourceRequestConf: {
        resourceType: 'custom_host',
        customDomain: 'https://your_domain.com/',
    },
    complete: () => {
        // SDK 初始化完成后，housePlay 已挂载到 window
        housePlayInstance = window.housePlay

        if (!housePlayInstance) {
            throw new Error('housePlay 实例未创建')
        }

        // 检查是否存在换装数据
        if (housePlayInstance?.version?.has_decoration) {
            hasPanoDressData.value = true
            panoDressData.value = housePlayInstance?.settings?.panoDress
            currentShowMode.value = VR_SHOW_MODE.NORMAL
        }

        // 先注册加载进度等基础事件
        registerEvents(housePlayInstance)

        // 存储模型数据
        const settings = housePlayInstance.settings;
        console.log('settings', settings)

        // 启动 VR 展示
        // 可在调用start方法之前，修改settings中的配置数据来调整播放行为
        housePlayInstance.start()
        resolve(housePlayInstance)
    },
})
```

---



## 注意事项

1. **初始化顺序**：必须先初始化zqsdk拿到housePlay实例，再调用 `housePlay.start()` 方法开始渲染。

2. **事件监听**：建议在调用 `housePlay.start()` 之前注册事件监听，以确保不会错过任何事件。

3. **模式切换**：某些场景可能不支持3D模式（`show3d: false`），此时 `changeMode()` 会返回 `false`。



