index.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <template>
  2. <div :class="`theme${theme}`" class="scene-body">
  3. <div class="logo" v-if="!showViewMode">
  4. <img @click="$router.push({ path: '/' })" :src="require(`@/assets/images/proj2022/pc/logo.png`)" alt="" />
  5. </div>
  6. <div class="scene-con">
  7. <scene :tourStatus="tourStatus" />
  8. <div v-if="showViewMode">
  9. <div :class="{ disabled: flying }" class="tab-layer">
  10. <div class="tabs">
  11. <div :class="{ active: mode === 'floorplan' }" @click="changeMode('floorplan', $event)">
  12. <img :src="require('@/assets/images/proj2022/mobile/floor@2x.png')" alt="" />
  13. <span>平面</span>
  14. </div>
  15. <div :class="{ active: mode === 'dollhouse' }" @click="changeMode('dollhouse', $event)">
  16. <img :src="require('@/assets/images/proj2022/mobile/dollhouse@2x.png')" alt="" />
  17. <span>三维</span>
  18. </div>
  19. <div :class="{ active: mode === 'birdview' }" @click="changeMode('birdview', $event)">
  20. <img :src="require('@/assets/images/proj2022/mobile/bird view@2x.png')" alt="" />
  21. <span>鸟瞰</span>
  22. </div>
  23. </div>
  24. </div>
  25. </div>
  26. <template v-else>
  27. <vside :isShow="!tourStatus && showAside" @close="showAside = false" />
  28. <zhanxiang @showSearch="showSearch = true" v-if="isShowZL" @close="isShowZL = false" :tourStatus="tourStatus" />
  29. <rmenu :currentPanoid="currentPanoid" :isShowfunc="isShowfunc" :menuType="menuType" :tourStatus="tourStatus" @opencp="handlecp" />
  30. <vmenu :tourStatus="tourStatus" @opencp="handlecp" />
  31. <vsearch :currentPanoid="currentPanoid" @closeSearch="closeSearch" v-if="showSearch" />
  32. </template>
  33. </div>
  34. <birdview :hideClose="true" @close="mode='',showViewMode=false" v-if="mode=='birdview'"/>
  35. <vhotspot v-if="hotspot" @close="hotspot = ''" :hotspot="hotspot" />
  36. <vpopup v-if="showpopup && cp" v-clickoutside="handleoutside">
  37. <div slot="vcon" class="popcon">
  38. <component :is="cp" :currentPano="currentPano" :currentItem="currentItem"> </component>
  39. <img @click="(showpopup = false), (cp = '')" class="close" :src="require('@/assets/images/project/icon/close.png')" alt="" />
  40. </div>
  41. </vpopup>
  42. <div class="logincon" v-if="loginUrl">
  43. <img class="close" @click="loginUrl = ''" :src="require('@/assets/images/mobile/icon/close_b.png')" alt="" />
  44. <iframe :src="loginUrl" frameborder="0"></iframe>
  45. </div>
  46. </div>
  47. </template>
  48. <script>
  49. import aside from "./aside.vue";
  50. import vbar from "./bar.vue";
  51. import menu from "./menu.vue";
  52. import rmenu from "./raside/menu.vue";
  53. import zhanxiang from "./zhanxiang/index.vue";
  54. import birdview from "./birdview/index.vue";
  55. import popup from "./popup.vue";
  56. import vsearch from "./search";
  57. import vmap from "./map";
  58. import daka from "./components/daka.vue";
  59. import content from "./components/content.vue";
  60. import qrcode from "./components/qrcode.vue";
  61. import scene from "./scene.vue";
  62. import vhotspot from "@/components/hotspot/index.vue";
  63. import { region, Booth } from "@/data/raw.js";
  64. export default {
  65. components: {
  66. vside: aside,
  67. vmenu: menu,
  68. rmenu: rmenu,
  69. zhanxiang,
  70. vpopup: popup,
  71. daka,
  72. qrcode,
  73. vcontent: content,
  74. scene,
  75. vsearch,
  76. vhotspot,
  77. vbar,
  78. vmap,
  79. birdview
  80. },
  81. computed: {
  82. currentItem() {
  83. return this.themes.find((item) => item.id == this.theme);
  84. },
  85. currentPano() {
  86. return Booth.find((item) => item.panoId == this.currentPanoid) || {};
  87. },
  88. },
  89. data() {
  90. return {
  91. menuType: "func",
  92. isShowfunc: false,
  93. showpopup: false,
  94. showAside: false,
  95. showSearch: false,
  96. isShowZL: false,
  97. cp: "",
  98. tourStatus: false,
  99. showAll: false,
  100. currentPanoid: "",
  101. isFull: false,
  102. hotspots: [],
  103. hotspot: "",
  104. loginUrl: "",
  105. currentTheme: "",
  106. booth: Booth,
  107. showViewMode: false,
  108. flying:false,
  109. mode:'floorplan'
  110. };
  111. },
  112. watch: {
  113. currentTheme(newVal) {
  114. if (newVal) {
  115. let tt = this.currentPanoid;
  116. this.currentPanoid = "";
  117. this.$router.push({ params: { type: newVal.id, isjump: "none" } });
  118. setTimeout(() => {
  119. this.currentPanoid = tt;
  120. });
  121. }
  122. },
  123. },
  124. mounted() {
  125. this.$showLoading();
  126. this.$nextTick(() => {
  127. this.$bus.$on("mblogin", (data) => {
  128. this.loginUrl = data;
  129. });
  130. this.$bus.$on("emitShowZX", (data) => {
  131. this.isShowZL = data;
  132. });
  133. this.$bus.$on("changeMenu", (data) => {
  134. this.menuType = data;
  135. });
  136. this.$bus.$on("changeShowfunc", (data) => {
  137. this.isShowfunc = data;
  138. });
  139. this.$bus.$on("opencp", (data) => {
  140. this.handlecp(data);
  141. this.isShowZL = false;
  142. });
  143. window.addEventListener("message", (res) => {
  144. if (Object.prototype.toString.call(res.data) == "[object Object]") {
  145. let data = res.data.data;
  146. if (res.data.source === "showAll") {
  147. setTimeout(() => {
  148. this.$hideLoading();
  149. });
  150. }
  151. if (res.data.source === "onplayStatus") {
  152. console.log("onplayStatus");
  153. this.tourStatus = data.tourIsPlaying;
  154. }
  155. if (res.data.source === "pano.chosen") {
  156. console.log("pano.chosen");
  157. window.g_lock = true;
  158. }
  159. if (res.data.source === "tour.end") {
  160. window.g_lock = false;
  161. }
  162. if (res.data.source === "warp.interrupted") {
  163. console.log("warp.interrupted");
  164. window.g_lock = false;
  165. }
  166. if (res.data.source === "mode.changed") {
  167. console.log("mode.changed", data);
  168. if (data == "floorplan" || data == "dollhouse") {
  169. this.showViewMode = true;
  170. this.flying = false;
  171. this.mode = data
  172. document.querySelector("#ifr").contentWindow.postMessage(
  173. {
  174. source: "toggleClear",
  175. data: this.showViewMode,
  176. },
  177. "*"
  178. );
  179. } else if (data == "panorama") {
  180. this.showViewMode = false;
  181. this.flying = false;
  182. document.querySelector("#ifr").contentWindow.postMessage(
  183. {
  184. source: "toggleClear",
  185. data: this.showViewMode,
  186. },
  187. "*"
  188. );
  189. } else if (data == "transitioning") {
  190. this.flying = true;
  191. }
  192. }
  193. if (res.data.source === "flying.ended") {
  194. console.log("flying.ended");
  195. this.currentPanoid = data;
  196. this.currentTheme = region.find((item) => {
  197. if (item.spread.indexOf(Number(this.currentPanoid)) > -1) {
  198. return item;
  199. }
  200. });
  201. setTimeout(() => {
  202. window.g_lock = false;
  203. });
  204. }
  205. if (res.data.source === "openHotspot") {
  206. this.hotspot = data;
  207. this.$bus.$emit("isShowAside", false);
  208. }
  209. }
  210. });
  211. });
  212. },
  213. methods: {
  214. changeMode(data) {
  215. this.mode = data
  216. document.querySelector('#ifr').contentWindow.player.director.changeMode(data);
  217. },
  218. closeSearch(data) {
  219. if (data == "closeAll") {
  220. this.isShowZL = false;
  221. }
  222. this.showSearch = false;
  223. },
  224. handlecp(data) {
  225. this.cp = data;
  226. this.showpopup = true;
  227. },
  228. handleoutside() {
  229. this.cp = "";
  230. this.showpopup = false;
  231. },
  232. },
  233. };
  234. </script>
  235. <style lang="less" scoped>
  236. .scene-body {
  237. background-repeat: no-repeat;
  238. .tab-layer {
  239. width: 100%;
  240. text-align: center;
  241. display: flex;
  242. justify-content: center;
  243. align-items: center;
  244. z-index: 10;
  245. position: fixed;
  246. left: 50%;
  247. transform: translateX(-50%);
  248. top: 30px;
  249. pointer-events: none;
  250. .tabs {
  251. pointer-events: auto;
  252. position: relative;
  253. display: flex;
  254. background: rgba(0, 0, 0, 0.5);
  255. padding: 2px;
  256. justify-content: center;
  257. align-items: center;
  258. border: 1px solid rgba(255, 255, 255, 0.1);
  259. border-radius: 6px;
  260. padding: 0px 2px;
  261. backdrop-filter: blur(20px);
  262. >div {
  263. color: #fff;
  264. border-radius: 6px;
  265. font-size: 16px;
  266. transition: all 0.3s ease;
  267. display: flex;
  268. align-items: center;
  269. z-index: 1;
  270. margin: 4px;
  271. padding: 2px 6px 2px 0;
  272. img {
  273. width: 30px;
  274. }
  275. >span{
  276. font-size: 14px;
  277. }
  278. &.active {
  279. background: rgba(127, 127, 127, 0.57);
  280. border-radius: 4px;
  281. }
  282. }
  283. }
  284. }
  285. .disabled{
  286. opacity: 0.5;
  287. pointer-events: none;
  288. }
  289. .scene-con {
  290. width: 100%;
  291. height: 100%;
  292. }
  293. .logo {
  294. position: absolute;
  295. left: 10px;
  296. top: 8px;
  297. z-index: 999;
  298. display: flex;
  299. align-items: center;
  300. > img {
  301. width: 48px;
  302. }
  303. }
  304. .popcon {
  305. z-index: 9999;
  306. width: 100%;
  307. height: 100%;
  308. .close {
  309. position: absolute;
  310. top: 40px;
  311. right: 20px;
  312. width: 16px;
  313. cursor: pointer;
  314. z-index: 1000;
  315. }
  316. }
  317. .logincon {
  318. position: fixed;
  319. z-index: 999999;
  320. width: 100%;
  321. height: 100%;
  322. top: 0;
  323. left: 0;
  324. > iframe {
  325. width: 100%;
  326. height: 100%;
  327. }
  328. .close {
  329. display: inline-block;
  330. position: absolute;
  331. right: 16px;
  332. top: 16px;
  333. width: 16px;
  334. }
  335. }
  336. }
  337. </style>