index.tsx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { defineComponent, ref, watch } from 'vue';
  2. import className from 'classname';
  3. import useBaseStore from '@/store/module/base';
  4. import { storeToRefs } from 'pinia';
  5. import { useRoute } from 'vue-router';
  6. import Guide from '../guide';
  7. import { useFullscreen } from '@vueuse/core';
  8. import { CAMERA_TYPE_ENUM } from '@/types/home';
  9. import Rules from '../rules/index.vue';
  10. import type { IRulesMethods } from '@/types';
  11. import './index.scss';
  12. export default defineComponent({
  13. name: 'HomeMenu',
  14. props: {
  15. mode: {
  16. type: Number,
  17. default: CAMERA_TYPE_ENUM.PANORAMA,
  18. },
  19. },
  20. setup() {
  21. const baseStore = useBaseStore();
  22. const route = useRoute();
  23. const { isFullscreen, isSupported, toggle } = useFullscreen();
  24. const { kankanInited, guidePlaying, hotList, hotListVisible, bgMusicDom, bgMusicPlaying } =
  25. storeToRefs(baseStore);
  26. const guideVisible = ref(false);
  27. const rulesRef = ref<IRulesMethods>();
  28. const handlePlayGuide = async () => {
  29. const player = await window.kankan.TourManager.player;
  30. const playing = guidePlaying.value;
  31. if (playing) {
  32. player.pause();
  33. } else {
  34. player.play();
  35. guideVisible.value = true;
  36. }
  37. baseStore.setState('guidePlaying', !playing);
  38. };
  39. const handleDollhouse = () => {
  40. window.kankan.Camera.dollhouse();
  41. };
  42. const handleFloorplan = () => {
  43. window.kankan.Camera.floorplan();
  44. };
  45. const handlePanorama = () => {
  46. window.kankan.Camera.panorama();
  47. };
  48. const openHotList = () => {
  49. baseStore.setState('hotListVisible', !hotListVisible.value);
  50. };
  51. const startMeasure = () => {
  52. rulesRef.value?.startMeasure();
  53. };
  54. const handleBgMusic = () => {
  55. if (bgMusicPlaying.value) {
  56. bgMusicDom?.value?.pause();
  57. } else {
  58. bgMusicDom?.value?.play();
  59. }
  60. baseStore.setState('bgMusicPlaying', !bgMusicPlaying.value);
  61. };
  62. watch(kankanInited, async (v) => {
  63. if (!v) return;
  64. const detail = await window.kankan.store.get('metadata');
  65. if (detail.musicFile) {
  66. // 存在背景音乐
  67. const dom = document.createElement('audio');
  68. dom.src = `${import.meta.env.VITE_APP_BACKEND_URL}/scene_view_data/${
  69. route.query.m
  70. }/user/music-user.mp3`;
  71. dom.loop = true;
  72. document.body.appendChild(dom);
  73. baseStore.setState('bgMusicDom', dom);
  74. }
  75. });
  76. return {
  77. hotList,
  78. hotListVisible,
  79. isSupported,
  80. isFullscreen,
  81. guideVisible,
  82. guidePlaying,
  83. bgMusicDom,
  84. bgMusicPlaying,
  85. rulesRef,
  86. toggle,
  87. openHotList,
  88. startMeasure,
  89. handlePlayGuide,
  90. handleFloorplan,
  91. handleDollhouse,
  92. handlePanorama,
  93. handleBgMusic,
  94. };
  95. },
  96. render() {
  97. return (
  98. <>
  99. {!this.rulesRef?.showRuleBox && (
  100. <>
  101. <div
  102. class={className('pinBottom-container', {
  103. open: this.guideVisible,
  104. playing: this.guidePlaying,
  105. noScroll: !this.guidePlaying,
  106. })}
  107. >
  108. <div class="pinBottom left">
  109. <div id="play" class="ui-icon" onClick={this.handlePlayGuide}>
  110. <a>
  111. {!this.guidePlaying ? (
  112. <img src="images/play.png" />
  113. ) : (
  114. <img title="暂停" src="images/pause.png" />
  115. )}
  116. </a>
  117. </div>
  118. <div
  119. id="pullTab"
  120. class={className({ opened: this.guideVisible })}
  121. onClick={() => (this.guideVisible = !this.guideVisible)}
  122. >
  123. <img class="icon icon-inside" src="images/auto.png" title="导览" />
  124. </div>
  125. {Boolean(this.hotList.length) && (
  126. <div id="hotList" onClick={this.openHotList}>
  127. <img class="icon icon-inside" src="images/hotlist.png" title="热点列表" />
  128. </div>
  129. )}
  130. <div
  131. id="gui-modes-inside"
  132. class={className({ active: this.mode === CAMERA_TYPE_ENUM.PANORAMA })}
  133. onClick={this.handlePanorama}
  134. >
  135. <img class="icon icon-inside" src="images/inside.png" title="全景漫游" />
  136. </div>
  137. <div
  138. id="gui-modes-dollhouse"
  139. class={className({ active: this.mode === CAMERA_TYPE_ENUM.DOLLHOUSE })}
  140. onClick={this.handleDollhouse}
  141. >
  142. <img class="icon icon-inside" src="images/dollhouse.png" title="迷你模型" />
  143. </div>
  144. <div
  145. id="gui-modes-floorplan"
  146. class={className({ active: this.mode === CAMERA_TYPE_ENUM.FLOORPLAN })}
  147. onClick={this.handleFloorplan}
  148. >
  149. <img class="icon icon-inside" src="images/floor.png" title="俯视图" />
  150. </div>
  151. </div>
  152. <div class="pinBottom right">
  153. {Boolean(this.bgMusicDom) && (
  154. <div id="volume" class="ui-icon wide" onClick={this.handleBgMusic}>
  155. {this.bgMusicPlaying ? (
  156. <img src="images/Volume btn_on.png" width="24" height="24" />
  157. ) : (
  158. <img src="images/Volume btn_off.png" width="24" height="24" />
  159. )}
  160. </div>
  161. )}
  162. <div id="rules" class="ui-icon wide" onClick={this.startMeasure}>
  163. <img src="images/rules.png" width="24" height="24" />
  164. </div>
  165. {this.isSupported && (
  166. <div id="gui-fullscreen" class="ui-icon wide" onClick={this.toggle}>
  167. {this.isFullscreen ? (
  168. <img class="icon icon-fullscreen-exit" src="images/narrow_off.png" />
  169. ) : (
  170. <img class="icon icon-fullscreen" src="images/enlarge_on.png" />
  171. )}
  172. </div>
  173. )}
  174. </div>
  175. </div>
  176. </>
  177. )}
  178. <Guide open={this.guideVisible} playing={this.guidePlaying} />
  179. <Rules ref="rulesRef" />
  180. </>
  181. );
  182. },
  183. });