<!-- * @Description: 监控图层 * @Author: 王晓颖 * @Date: 2021-09-15 10:04:45 --> <template> <div> <div v-if="videoShow" :class="{'video-dialog': !maxWindow, 'max-window': maxWindow}"> <div style="height:30px;color:white;margin-top:20px;width:100%;text-align:center;font-size: 18px;">实时监控</div> <img :src="require('@/assets/img/map/maximum.png')" width="20" height="20" class="max-btn" @click="maxWindow = !maxWindow"> <img :src="require('@/assets/img/map/close.png')" width="20" height="20" class="close-btn" @click="closeVideo"> <div class="video-div"> <video :src="videoSrc" autoPlay="" width="100%"></video> </div> </div> </div> </template> <script> import Leaflet from 'leaflet' import commonMixin from '@/components/leafletMap/base/mixins/common.js' import { getPathBounds, getCenterByBounds, getZoomByBounds } from '@/utils/maputils' export default { name: 'VideoLayer', mixins: [commonMixin('layer')], props: { show: { type: Boolean, default: true }, // 是否显示 iconSize: { type: Array, default: () => { return [40, 40] } }, // 图标大小 iconAnchor: { type: Array, default: () => { return [20, 40] } }, // 图标位移 popupAnchor: { type: Array, default: () => { return [0, -40] } }, // 弹窗位移 refreshTime: { type: Number, default: 60 } // 定时刷新时间 }, data () { return { maxWindow:false, // 窗口最大化 videoSrc: 'static/video/lukou.mp4', videoShow: false, videoList: [], // 路灯亮列表 videoLayer: null, // 路灯亮图层 layerGroup: [], // 图层组 videoIcon: require('@/assets/img/map/video.png'), timer: null // 定时器 } }, watch: { show (val) { if (val) { this.initLayer() } else { this.clearLayer() } } }, methods: { load () { console.log('load caseLayer') if (this.show) { this.initLayer() } }, // 初始化图层 initLayer () { const {map} = this this.layerGroup = [] // 先清空LayerGroup // 初始化图层组 /* eslint-disable new-cap */ this.videoLayer = new Leaflet.layerGroup().addTo(map) this.layerGroup.push(this.videoLayer) console.log('initLayer') this.loadData() }, // 清除图层 clearLayer () { console.log('clearLayer') const {map, layerGroup} = this layerGroup.forEach(item => map.removeLayer(item)) }, // 加载全部数据 loadData () { const {videoIcon} = this // 获取待核实案卷 this.videoList = [ {latitude:22.292656 , longitude:113.490993} ] this.addPointOnMap(this.videoList, this.videoLayer, videoIcon) this.setZoom(this.videoList) }, // 将点加到地图上 addPointOnMap(dataList, layer, iconType) { const {iconSize, iconAnchor, popupAnchor} = this layer.clearLayers() // 图标 const icon = Leaflet.icon({ iconUrl: iconType, iconSize: iconSize, iconAnchor: iconAnchor, popupAnchor: popupAnchor }) dataList.forEach(item => { let popupStr = '<div class="popup-div">' + '<div class="popup-title">沥东路与105国道路口</div>' + '<div class="dashed-line"></div>' + '<div class="popup-item"><label>状态</label>运行正常</div>' + '<div class="popup-button" id="real-video">查看实时监控</div>' popupStr += '</div>' const popup = Leaflet.popup().setContent(popupStr) if (item.longitude > 0 && item.latitude > 0) { // 添加marker const marker = Leaflet.marker([item.latitude, item.longitude], { icon: icon, id: item.lampId }).addTo(layer).bindPopup(popup) marker.on('click', (e) => { console.log(e) document.getElementById('real-video').onclick = ()=>{ this.openVideo() } }) } }) }, // 播放视频 openVideo(){ this.videoShow = true }, closeVideo(){ this.videoShow = false }, setZoom (points) { if (points.length > 0) { // 计算边界 const { maxLng, minLng, maxLat, minLat } = getPathBounds(points,'longitude','latitude') // 计算中心点 const { cenLat, cenLng } = getCenterByBounds({ maxLng, minLng, maxLat, minLat }) // 计算缩放 const zoom = getZoomByBounds({ maxLng, minLng, maxLat, minLat }) console.log({ lat: cenLat, lng: cenLng }, zoom) this.map.setView({ lat: cenLat, lng: cenLng }, zoom) } } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .video-dialog{ position: absolute; top: 50%; left:50%; transform: translate(-50%,-50%); z-index:1000; width: 600px; height: 400px; background-color: rgba(7,10,23,0.8); border-radius: 10px; .max-btn{ position: absolute; top:20px; right:60px; } .close-btn{ position: absolute; top:20px; right:20px; } .close-btn:hover{ animation:turn 1s linear infinite; } .video-div{ width: 100%; padding: 0px 20px; } } .max-window{ position: fixed; top: 0; left:0; z-index:1000; width: 100%; height: 100%; background-color: rgba(7,10,23,0.8); border-radius: 10px; .max-btn{ position: absolute; top:20px; right:60px; } .close-btn{ position: absolute; top:20px; right:20px; } .close-btn:hover{ animation:turn 1s linear infinite; } .video-div{ width: 100%; padding: 0px 20px; } } @keyframes turn{ 0%{-webkit-transform:rotate(0deg);} 25%{-webkit-transform:rotate(90deg);} 50%{-webkit-transform:rotate(180deg);} 75%{-webkit-transform:rotate(270deg);} 100%{-webkit-transform:rotate(360deg);} } </style> <style rel="stylesheet/scss" lang="scss" > .leaflet-popup-content-wrapper, .leaflet-popup-tip{ color: white; background-color: rgba(10,26,123,0.8); } .leaflet-popup-content { .popup-div { font-size: 14px; padding: 5px; } .popup-title { font-weight: bold; } .dashed-line { border-bottom: 1px dashed #dddddd; margin: 10px -10px; } .popup-item { padding-bottom: 6px; label { font-weight: bold; padding-right: 15px; } } .popup-subitem { padding-bottom: 6px; font-size: 12px; } .popup-button{ color:#67E0E3; text-align: center; margin-top: 5px; text-decoration: underline; } .popup-button:hover{ color: #36b7ff; cursor: pointer; } } </style>