index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <template>
  2. <div class="layout" :style="{top:showList?'0':'100%'}" @touchmove.prevent>
  3. <div id="map"></div>
  4. <div class="map-bottom-layout" :class="{mobile: ismobile}">
  5. <div class="map-tabs clear" :class="{mobile: ismobile}">
  6. <template v-if="!isLocal && !ismobile">
  7. <a class="rad list-pc-icon" @click="tapList()"><i class="iconfont icon-suolve"></i></a>
  8. </template>
  9. <template v-if="dmodel && dmodel.link">
  10. <template v-if="ismobile">
  11. <span v-if="mapTab === 1" @click="goto(dmodel)">
  12. <i class="iconfont icon-leixing_hangpai"></i>航拍
  13. </span>
  14. <span v-if="mapTab === 0" @click="mapTab = 1 && goto(dmodel)">
  15. <i class="iconfont icon-tuceng"></i>平面
  16. </span>
  17. </template>
  18. <template v-if="!ismobile">
  19. <a class="rad mar-left" >
  20. 俯视整个{{$route.params.title}}
  21. </a>
  22. <a @click="goto(dmodel)" :class="{active: mapTab === 1}" class="rad mar-rigth">
  23. 航拍视角
  24. </a>
  25. </template>
  26. </template>
  27. <template v-if="!isLocal && ismobile">
  28. <div class="list-icon" @click="tapList()">
  29. <i class="iconfont icon-suolve"></i>列图
  30. </div>
  31. </template>
  32. </div>
  33. <div class="focus-info" v-if="info && ismobile">
  34. <h3>{{info.name}}</h3>
  35. <div class="tags">
  36. <span>{{info.parent}}</span>
  37. </div>
  38. <div class="tags">
  39. <span>{{info.tagType.name}}</span>
  40. </div>
  41. <p>{{info.address}}</p>
  42. <div class="types">
  43. <i v-for="type in info.showType" :key="type" class="iconfont" :class="'icon-'+type"></i>
  44. </div>
  45. <a @click="goto(info)" v-if="info.link || info.data">
  46. <span>点击</span><span>参观</span>
  47. </a>
  48. <a class="nolink" v-else>
  49. <span>正在</span><span>拍摄</span>
  50. </a>
  51. </div>
  52. </div>
  53. <imageQuery :introduce="introduce" :name="name" :showAside="true" :screens="screens" @exitHandle="screens = null"/>
  54. <transition name="fade">
  55. <div class="guodu" v-if="showWl">
  56. <video autoplay ref="wlvideo">
  57. <source :src="`https://culture.4dage.com/demo/videos/${showWl}`">
  58. </video>
  59. <div class="jump" @click="showWl = false">跳过</div>
  60. </div>
  61. </transition>
  62. </div>
  63. </template>
  64. <script>
  65. import imageQuery from '@/pages/imageQuery'
  66. import browser from '@/util/browser'
  67. import data from '@/data'
  68. const AMap = global.AMap
  69. export default {
  70. components: {
  71. imageQuery
  72. },
  73. data () {
  74. return {
  75. showWl: '',
  76. cacheMakers: [],
  77. showDialog: false,
  78. imgIndex: 0,
  79. mapTab: 1,
  80. ismobile: browser.mobile,
  81. info: null,
  82. dmodel: {},
  83. isType: true,
  84. screens: null,
  85. showList: false,
  86. introduce: [],
  87. name: ''
  88. }
  89. },
  90. computed: {
  91. isLocal () {
  92. return this.$isLocal
  93. }
  94. },
  95. methods: {
  96. grentHtml (item, cls) {
  97. var $maker = document.createElement('div')
  98. if (!this.ismobile) {
  99. var types = item.showType.map(type => `<i class="iconfont icon-${type}"></i>`)
  100. if (item.link || item.data) {
  101. $maker.classList.add('link')
  102. } else {
  103. $maker.classList.add('nolink')
  104. }
  105. $maker.classList.add('maker-info')
  106. $maker.classList.add('rad')
  107. cls && $maker.classList.add(cls)
  108. $maker.innerHTML = `
  109. <h3>
  110. <i class="iconfont icon-${item.type}"></i>
  111. <span>${item.name}</span>
  112. </h3>
  113. <div class="content">
  114. <div><span>${item.parent}</span><span>${item.tagType.name}</span></div>
  115. <p>${item.address}</p>
  116. <div class="oper">
  117. <div>${(item.link || item.data) ? types.join('') : ''}</div>
  118. <a class='query-image'>${(item.link || item.data) ? '点击参观' : '正在拍摄'}</a>
  119. </div>
  120. </div>
  121. `
  122. if (item.data) {
  123. $maker.querySelector('.query-image').addEventListener('click', () => {
  124. this.queryImage(item)
  125. })
  126. }
  127. } else {
  128. $maker.classList.add('maker-info-mobile')
  129. $maker.innerHTML = `
  130. <div>
  131. <i class="iconfont icon-dingwei"></i>
  132. <i class="icon-tub iconfont icon-${item.type}"></i>
  133. </div>`
  134. }
  135. return $maker
  136. },
  137. loadding (item, showTitle) {
  138. this.cacheMakers.forEach(marker => {
  139. marker.seftadditional.removeSeft()
  140. })
  141. let showMaker
  142. let markers = item.children.map(c => {
  143. let maker = this.grentMakter([parseFloat(c.lng), parseFloat(c.lat)], c)
  144. c.name === showTitle && (showMaker = maker)
  145. return maker
  146. })
  147. this.cacheMakers = markers
  148. showMaker && showMaker.seftadditional.play()
  149. },
  150. grentMakter (point, item) {
  151. let infoWindow, infoDom
  152. let show = false
  153. let dom = this.grentHtml(item)
  154. let position = new global.AMap.LngLat(Number(point[0]), Number(point[1]))
  155. let marker = new global.AMap.Marker({
  156. position: position,
  157. content: dom,
  158. offset: new global.AMap.Pixel(-80, -30)
  159. })
  160. let clickHandle = () => {
  161. this.goto.bind(this)(item)
  162. }
  163. marker.seftadditional = {
  164. removeSeft: () => {
  165. marker.seftadditional.pause()
  166. this.map.remove(marker)
  167. if (!this.ismobile) {
  168. infoDom.querySelector('h3').removeEventListener('click', marker.seftadditional.pause)
  169. infoDom.querySelector('a').removeEventListener('click', clickHandle)
  170. }
  171. },
  172. play: () => {
  173. this.$bus.$emit('showMaker', dom)
  174. if (this.ismobile) {
  175. dom.classList.add('show')
  176. this.info = item
  177. } else {
  178. infoWindow.open(this.map, position)
  179. }
  180. this.map.setCenter(position)
  181. show = true
  182. },
  183. pause: () => {
  184. if (!this.ismobile) {
  185. infoWindow.close()
  186. } else {
  187. dom.classList.remove('show')
  188. this.info = null
  189. }
  190. show = false
  191. }
  192. }
  193. this.$bus.$on('showMaker', showDom => {
  194. if (dom !== showDom) {
  195. if (show) {
  196. marker.seftadditional.pause()
  197. }
  198. show = false
  199. }
  200. })
  201. global.AMap.event.addListener(marker, 'click', e => {
  202. if (!show) {
  203. this.$router.push({
  204. name: 'info',
  205. params: {
  206. title: this.$route.params.title,
  207. show: item.name
  208. }
  209. })
  210. // marker.seftadditional.play()
  211. } else {
  212. this.$router.push({
  213. name: 'map',
  214. params: {
  215. title: this.$route.params.title
  216. }
  217. })
  218. // marker.seftadditional.pause()
  219. }
  220. })
  221. if (!this.ismobile) {
  222. infoDom = this.grentHtml(item, 'show')
  223. infoWindow = new AMap.InfoWindow({
  224. content: infoDom
  225. })
  226. infoDom.querySelector('h3').addEventListener('click', () => {
  227. this.$router.push({
  228. name: 'map',
  229. params: {
  230. title: this.$route.params.title
  231. }
  232. })
  233. // marker.seftadditional.pause()
  234. })
  235. infoDom.querySelector('a').addEventListener('click', clickHandle)
  236. }
  237. this.map.add(marker)
  238. return marker
  239. },
  240. initial () {
  241. let params = this.$route.params
  242. this.showWl = this.$route.query.isWl ? this.g_showVDRegion[params.title] : ''
  243. this.$nextTick(() => {
  244. this.$refs.wlvideo && this.$refs.wlvideo.addEventListener('ended', () => {
  245. this.showWl = false
  246. })
  247. })
  248. let item = this.dmodel = data.modules.find(item => item.title === params.title)
  249. if (!item) {
  250. item = data.types.find(item => item.title === params.title)
  251. }
  252. this.loadding(item, params.show)
  253. },
  254. tapList () {
  255. let {params} = this.$route
  256. // let items, item
  257. // let tagType
  258. // if (params.show) {
  259. // if (data.types.find(item => item.title === params.title)) {
  260. // items = data.types.find(item => item.title === params.title)
  261. // } else {
  262. // items = data.modules.find(item => item.title === params.title)
  263. // }
  264. // if (name === 'map' || name === 'info' || name === 'home') {
  265. // }
  266. // item = items ? items.children.find(item => item.name === params.show) : ''
  267. // tagType = item.tagType.name
  268. // }
  269. this.$router.push({
  270. name: params.show ? 'item' : 'list',
  271. params: !this.isType ? {
  272. title: params.title,
  273. type: '全部',
  274. show: params.show
  275. } : {
  276. title: '全部',
  277. type: params.title,
  278. show: params.show
  279. }
  280. })
  281. },
  282. goto (info) {
  283. if (info.link) {
  284. let id = null
  285. Object.keys(data.data).forEach(key => {
  286. if (data.data[key] === info) {
  287. id = key
  288. }
  289. })
  290. this.$router.push({
  291. name: 'external',
  292. params: {
  293. url: info.link,
  294. id: id
  295. }
  296. })
  297. } else if (info.data) {
  298. this.screens = info.data
  299. this.introduce = info.introduce
  300. this.name = info.name
  301. }
  302. },
  303. queryImage (item) {
  304. this.screens = item.data
  305. this.introduce = item.introduce
  306. this.name = item.name
  307. }
  308. },
  309. watch: {
  310. mapTab (newVal) {
  311. if (newVal) {
  312. this.map.remove(this.satellite)
  313. } else {
  314. this.map.add(this.satellite)
  315. }
  316. },
  317. showList () {
  318. if (!this.ismobile) {
  319. this.$bus.$emit('showaside', true)
  320. }
  321. },
  322. '$route.params.title': {
  323. handler: function (newVal, oldVal) {
  324. setTimeout(() => {
  325. if (newVal !== oldVal) {
  326. let params = this.$route.params
  327. let item = data.modules.find(item => item.title === params.title)
  328. this.isType = false
  329. if (!item) {
  330. this.isType = true
  331. item = data.types.find(item => item.title === params.title)
  332. }
  333. this.map.setCenter(item.center)
  334. this.map.setZoom(item.zoom)
  335. }
  336. this.initial()
  337. })
  338. },
  339. immediate: true
  340. },
  341. '$route.params.show': function () {
  342. this.initial()
  343. }
  344. },
  345. mounted () {
  346. setTimeout(() => {
  347. this.showList = true
  348. })
  349. this.map = new global.AMap.Map('map', {
  350. mapStyle: 'amap://styles/fresh',
  351. zoom: 18,
  352. center: [113.590951, 22.359473]
  353. })
  354. this.satellite = new AMap.TileLayer.Satellite()
  355. this.initial()
  356. }
  357. }
  358. </script>
  359. <style scoped>
  360. @import url(./style);
  361. </style><style>
  362. @import url(./map_style);
  363. </style>