index.vue 11 KB

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