跳转至

户型图集成指南

本文档面向接入众趣 zqsdk 的开发者,说明如何在自己的项目中实现「户型图」功能。SDK 提供两种户型图形态:全景模式下的小户型图(迷你图 + 雷达)平面模式下的全屏户型图,需在不同事件中拉取数据并更新你的 UI。


一、功能简介与前置条件

1.1 什么是户型图

  • 全景模式(panorama):在 3D 场景旁展示一张小户型图,图上有一个雷达点表示当前所在房间位置与朝向;随用户漫游,雷达位置与当前房间名/面积需同步更新。
  • 平面模式(floorplan):整个画布为全屏户型图,可显示房间名称、雷达、入户门、宽高标尺、南北朝向等;切换楼层时需更新图片与覆盖层数据。

两种形态共用同一套「户型图数据源」,但触发更新的时机不同:全景依赖 panoChange / flyingEnd / compass / floorChange / modeChange;平面依赖 modeChange / floorChange 及可选的窗口 resize 后重算。

1.2 展示效果

小户型图展示效果(全景模式) 大户型图展示效果(平面模式)

1.3 前置条件

  • 已接入众趣 zqsdk,在 complete 回调中拿到 housePlay 并已调用 housePlay.start()
  • 模型支持户型图(多数 VR 模型均支持);SDK 通过 getFloorPlanParam()getFloorPlanParam2()(若存在)返回户型图相关数据。

二、集成步骤概览

步骤 内容
1 modeChange 中根据新模式(panorama / floorplan)拉取户型图参数并更新「户型图图片、尺寸、全屏定位」等
2 floorChange 中更新当前楼层对应的户型图图片(及平面模式下的房间名、入户门、雷达等)
3 全景模式:在 panoChange / flyingEnd 中更新雷达位置与当前区域名/面积;在 compass 中更新雷达旋转角度
4 平面模式:在进入 floorplan 时拉取雷达在户型图中的像素位置(若有 getCurrentRadarPostionInFloorPlan);窗口 resize 时建议重新拉取参数并重算覆盖层
5 使用你项目中的状态驱动「迷你户型图」「全屏户型图」等 UI 的展示与定位

以下按数据来源与时机展开。


三、第一步:获取户型图参数

核心接口housePlay.getFloorPlanParam() 或(若 SDK 支持)housePlay.getFloorPlanParam2()。建议先判断 housePlay.canUseNewFloorPlan(),为 true 时优先使用 getFloorPlanParam2(),否则使用 getFloorPlanParam()。返回值通常包含:

  • model:当前楼层、户型图开关、户型图图片接口等;常用 model.getCurrentHouseTypeImage() 得到当前楼层户型图图片 URL。
  • project:户型图在画布上的投影信息,如 topleftwidthheight(像素),用于全屏户型图的定位与雷达坐标换算。
  • floorIndex:当前楼层索引。
  • (部分版本)radar:当前雷达信息;平面模式下还可使用 housePlay.getCurrentRadarPostionInFloorPlan() 获取雷达在户型图中的像素位置。

调用时机

  • modeChange:当 newMode === 'panorama'newMode === 'floorplan' 时,拉取一次参数,用于更新户型图图片、投影尺寸、朝向(南北)等;进入 floorplan 时还需更新房间名称、标尺、入户门、雷达像素位置。
  • floorChange:切换楼层后,用新楼层的 params(或再次调用 getFloorPlanParam())更新户型图图片;若当前为 floorplan 模式,需同步更新房间名、入户门、雷达等。
function getParams() {
  let hp = window.housePlay
  if (!hp) return null
  if (hp.canUseNewFloorPlan && hp.canUseNewFloorPlan()) {
    return hp.getFloorPlanParam2 ? hp.getFloorPlanParam2() : null
  }
  return hp.getFloorPlanParam ? hp.getFloorPlanParam() : null
}

housePlay.on('modeChange', function(currentMode, newMode) {
  let params = getParams()
  if (!params) return

  if (newMode === 'panorama') {
    // 更新迷你户型图图片;可选:用缓存的雷达数据恢复雷达位置
    let url = params.model.getCurrentHouseTypeImage()
    if (url) yourApp.setFloorPlanImageUrl(url)
  }

  if (newMode === 'panorama' || newMode === 'floorplan') {
    // 更新全屏户型图定位与朝向(project.top/left/width/height、南北朝向等)
    yourApp.updateFloorPlanProject(params.model, params.project)
    yourApp.updateCompass(params.model)
  }

  if (newMode === 'floorplan') {
    // 全屏户型图模式:更新房间名称、标尺、入户门、雷达像素位置
    yourApp.updateRoomLabels(params.model, params.project, params.floorIndex)
    yourApp.updateDimension(params.model, params.project)
    yourApp.updateEntrance(params.model, params.project, params.floorIndex)
    try {
      let radar = housePlay.getCurrentRadarPostionInFloorPlan()
      if (radar && radar.uv)
        yourApp.updateFullRadar(radar.uv.v, radar.uv.u, radar.angle)
    } catch (e) {}
  }
})

四、第二步:监听楼层变化

事件housePlay.on('floorChange', function(params) { ... })

  • 回调中的 params 通常包含 floorIndeximageUrl 等;切换楼层后,当前楼层的户型图图片会变化。
  • 全景模式:用 params.imageUrl 或再次 getParams()model.getCurrentHouseTypeImage() 更新迷你户型图图片即可。
  • 平面模式:除图片外,需同步更新房间名称、入户门、雷达在户型图中的位置(再次调用 getCurrentRadarPostionInFloorPlan() 或从 params 取)。
housePlay.on('floorChange', function(params) {
  if (params.imageUrl) yourApp.setFloorPlanImageUrl(params.imageUrl)

  let params2 = getParams()
  if (params2 && yourApp.getCurrentMode() === 'floorplan') {
    yourApp.updateRoomLabels(params2.model, params2.project, params.floorIndex)
    yourApp.updateEntrance(params2.model, params2.project, params.floorIndex)
    try {
      let radar = housePlay.getCurrentRadarPostionInFloorPlan()
      if (radar && radar.uv)
        yourApp.updateFullRadar(radar.uv.v, radar.uv.u, radar.angle)
    } catch (e) {}
  }
})

五、第三步:全景模式下更新雷达与区域信息

迷你户型图上的雷达位置当前房间名/面积来自全景点位,需在点位变化时更新。

5.1 雷达位置(uv + 角度)

  • 位置:来自 panoChangeflyingEnd 回调中的 data.pano。若 SDK 支持 housePlay.getRadarData(position, floorIndex),建议用其将 pano 转为雷达 uv 与尺寸,再根据 uv 在迷你图上绘制雷达点(注意:迷你图宽高比需与雷达所在户型图区域一致,否则会偏移)。
  • 角度:来自 housePlay.on('compass', function(angle) { ... }),常用 angle.director 的负值作为雷达旋转角度。
housePlay.on('panoChange', function(data) {
  let pano = data.pano
  if (!pano) return

  yourApp.updateArea(pano.areaName, pano.areaSize)

  if (housePlay.getRadarData) {
    try {
      let pos = clonePosition(pano)  // 深拷贝 pano.position,避免被 SDK 修改
      let radar = housePlay.getRadarData(pos, pano.floorIndex || 0)
      if (radar && radar.uv) {
        yourApp.updateMiniRadarPosition(radar.uv.u, radar.uv.v, data.time)
        if (radar.size) yourApp.updateMiniSizeFromRadar(radar.size.width, radar.size.height)
      }
    } catch (e) {}
  } else if (pano.u != null && pano.v != null) {
    yourApp.updateMiniRadarPosition(pano.u, pano.v, data.time)
  }
})

housePlay.on('flyingEnd', function(data) {
  if (!data.pano) return
  let pano = data.pano
  yourApp.updateArea(pano.areaName, pano.areaSize)
  // 同 panoChange:用 getRadarData 或 pano.u/v 更新雷达位置,time 可传 0
})

housePlay.on('compass', function(angle) {
  yourApp.updateMiniRadarAngle(-angle.director)
})

5.2 区域名称与面积

pano.areaNamepano.areaSizepanoChange / flyingEnd 中提供,用于在迷你图旁或底部展示「当前房间 + 约 X m²」。


六、第四步:平面模式下的补充与窗口 resize

  • 雷达像素位置:进入 floorplan 或切换楼层后,调用 housePlay.getCurrentRadarPostionInFloorPlan()(若存在),将返回的 uvangle 换算到 project 的像素坐标,用于在全屏户型图上绘制雷达。
  • 窗口 resize:SDK 内部会重新计算 project 的 top/left/width/height。在 resize 后、当前模式为 floorplan 时,建议重新调用 getFloorPlanParam()(或 Param2),用新的 project 更新全屏户型图定位与房间名、入户门、雷达等,避免错位。

七、第五步:实现户型图 UI

  • 迷你户型图:仅在全景模式显示;展示户型图图片 + 雷达点(位置由 uv 换算到百分比或像素)+ 可选雷达旋转角;可展示当前区域名与面积。样式与尺寸由你自定义。
  • 全屏户型图:仅在平面模式显示;根据 project 定位图片,在其上叠加房间名、入户门、宽高标尺、南北朝向、雷达等。所有叠加元素需使用 SDK 提供的像素或比例数据,与 project 一致。

八、API 速查表

8.1 方法(housePlay)

方法 说明
getFloorPlanParam() 获取户型图相关数据(旧版)
getFloorPlanParam2() 获取户型图相关数据(新版,若存在)
canUseNewFloorPlan() 是否支持新版户型图 API
getRadarData(position, floorIndex) 根据 pano 位置与楼层获取雷达 uv、size(若存在)
getCurrentRadarPostionInFloorPlan() 平面模式下当前雷达在户型图中的位置(若存在)

8.2 事件

事件 说明
modeChange 模式切换;newMode 为 panorama / floorplan 时更新户型图与雷达
floorChange 楼层切换;更新当前楼层户型图图片及平面模式下的覆盖层
panoChange 全景下点位开始切换;可更新雷达位置与区域信息
flyingEnd 飞行动画结束;可更新雷达位置与区域信息
compass 指北针/朝向;用于雷达旋转角度

8.3 参数结构(简要)

  • params.model:含 getCurrentHouseTypeImage()currentFloorsettings 等。
  • params.projecttopleftwidthheight(像素)。
  • params.floorIndex:当前楼层索引。
  • panoareaNameareaSizeuvfloorIndexposition 等。

九、常见问题与注意事项

  1. getRadarData 可能抛错:在某些状态或旧版 SDK 下可能不存在或抛异常,建议 try/catch,失败时可用 pano.u / pano.v 作为简单百分比位置。
  2. 迷你图宽高比:迷你图宽高比应与雷达所在区域的户型图比例一致(可用 getRadarData 的 size 或 project 的 width/height 计算),否则雷达会偏移。
  3. 平面模式雷达:仅在有 getCurrentRadarPostionInFloorPlan 时可用;返回的 uv 需结合当前 project 换算为像素再绘制。
  4. 入户门:一般仅在实际入户门所在楼层显示,需根据 model.settings.building.house.flooridx 或等价配置判断。

以上完成即可在自己的项目中实现户型图(迷你 + 全屏)与雷达、房间名、入户门等联动。本仓库实现可参考 src/stores/floor-plan.tssrc/stores/vr.ts 中的 modeChange/floorChange/panoChange/compass/flyingEnd 及 src/utils/sdk-helpers.ts 中的 getFloorPlanParams