vue專案中實現maptalks地圖上彈框使用videojs播放實時視訊rtmp流
不限制於vue專案,區別只是相關檔案的引入
最終實現效果如下:
1、首先引入需要的資源:vue-video-player、maptalks相關
npm install vue-video-player --save
npm install maptalks --save
2、在地圖頁面引入
import * as maptalks from 'maptalks' import videojs from 'video.js' import 'video.js/dist/video-js.css' import 'vue-video-player/src/custom-theme.css' import 'videojs-flash' import SWF_URL from 'videojs-swf/dist/video-js.swf' videojs.options.flash.swf = SWF_URL // 設定flash路徑,Video.js會在不支援html5的瀏覽中使用flash播放視訊檔案
3、在地圖上打點標註點位並給點位新增彈框
markerInMap() { const that = this for (var m = 0; m < that.monitor.length; m++) { var markerm = new maptalks.Marker( that.monitor[m].position, // lon and lat in here { // 圖形樣式 'symbol': { 'markerFile': require('./../../assets/baseImg/monitor_map.png'), 'markerWidth': 28, 'markerHeight': 36, 'markerDx': 0, 'markerDy': 0, 'markerOpacity': 1 } } ).addTo(that.layer_monitor) markerm.setInfoWindow({ 'autoPan': true, 'width': 485, 'minHeight': 330, 'dy': 4, 'custom': false, // 只使用定製自定義true 'autoOpenOn': 'click', // set to null if not to open when clicking on marker 'autoCloseOn': 'click', // 支援自定義html內容 'content': '<div class="content equip-content">' + '<div class="pop-video"><video id="video_' + that.monitor[m].id + '" class="video-js vjs-default-skin vjs-big-play-centered" controls fluid="true" width="485" height="275">' + ' <source src="rtmp://212.64.34.125:10935/hls/stream_27" type="rtmp/flv">' + '</video></div>' + '<div class="pop-bottom">' + that.monitor[m].name + '<a id="moreMonitor" style="cursor:pointer;" data-id="' + that.monitor[m].id + '">檢視更多<i class="el-icon-arrow-right"></i></a></div>' + '</div>' }).on('mousedown', onClick) function onClick(e) { setTimeout(function() { const moreMonitor = document.getElementById('moreMonitor') moreMonitor.onclick = function() { that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }}) } that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() { this.play() }) }, 1000) } }
4、下面這段程式碼就實現了點選播放視訊
function onClick(e) { setTimeout(function() { const moreMonitor = document.getElementById('moreMonitor') moreMonitor.onclick = function() { that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }}) } that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() { this.play() }) }, 1000) }
5、但其實這時候是有一個bug的,就是當我不論以什麼方式關閉了這個彈框都會開始大量報錯
要解決這個問題需要在彈框關閉的時候銷燬之前建立的video物件,解決方案為監聽地圖點選事件,只要地圖有點選操作我們就判斷是否有video物件並對其銷燬置null
我們在mounted里加上下面的程式碼
// 監聽地圖點選事件
this.map.on('click', function(e) {
if (that.videoPlayer) {
that.videoPlayer.dispose()
that.videoPlayer = null
}
})
- 整個頁面程式碼如下
<template>
<div id="map" class="base-map" />
</template>
<script>
import * as maptalks from 'maptalks'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
import 'videojs-flash'
import SWF_URL from 'videojs-swf/dist/video-js.swf'
import { getBuild, getCustom, getMapMarks } from './../../api/park'
videojs.options.flash.swf = SWF_URL // 設定flash路徑,Video.js會在不支援html5的瀏覽中使用flash播放視訊檔案
export default {
name: 'BaseMap',
data() {
return {
videoPlayer: null,
map: null,
clusterLayer: [],
addressPoints: [],
drawTool: null,
layer_build: null,
layer_monitor: null,
layer_face: null,
layer_car: null,
layer_fire: null,
layer_polygon: null,
monitor: [],
face: [],
car: [],
fire: [],
building: [],
custom: []
}
},
mounted() {
const that = this
// --0--//地圖物件的初始化
this.map = new maptalks.Map('map', {
center: [121.6050804009, 31.2015354151],
// 中心點標記紅十字
centerCross: true,
// limit max pitch to 60 as mapbox-gl-js required,just for mapbox
maxPitch: 60,
zoom: 18,
zoomControl: true, // add zoom control
scaleControl: true, // add scale control
overviewControl: false, // add overview control
spatialReference: {
projection: 'EPSG:4326'
// 與map一樣,支援更詳細的設定resolutions,fullExtent等
},
baseLayer: new maptalks.WMSTileLayer('wms', {
'urlTemplate': 'http://xxx.xx.xx.xx:xxxx/geoserver/bcmp_puruan/wms',
'crs': 'EPSG:4326',
'tiled': true,
'layers': 'bcmp_puruan:new3d_puruan',
'styles': '',
'version': '1.1.1',
'format': 'image/png',
'transparent': true,
'uppercase': true
// 以上為wms服務基本配置項(服務相關)
// ----------------------------------------
// 以下可以加配maptalk相關屬性配置項,如css
// css filter 濾鏡配置,濾鏡配置比較豐富
// cssFilter : 'sepia(5%) invert(95%)'
}),
layers: [// 配置相關的layers
new maptalks.VectorLayer('v')
],
minZoom: 12,
maxZoom: 19,
attribution: {// 左下角info
content: '&maptalk for qmap'
}
})
// -1-//中心點增加標註,並點選彈框
// var center = this.map.getCenter()
// 宣告放置樓宇和自定義區域的圖層
this.layer_build = new maptalks.VectorLayer('build').addTo(this.map)
// 宣告放置監控裝置的圖層
this.layer_monitor = new maptalks.VectorLayer('monitor').addTo(this.map)
// 宣告放置人臉門禁的圖層
this.layer_face = new maptalks.VectorLayer('face').addTo(this.map)
// 宣告放置車輛卡口的圖層
this.layer_car = new maptalks.VectorLayer('car').addTo(this.map)
// 宣告放置消防設施的圖層
this.layer_fire = new maptalks.VectorLayer('fire').addTo(this.map)
// 宣告放置畫多邊形的圖層
this.layer_polygon = new maptalks.VectorLayer('polygon').addTo(this.map)
// -2-// 拖動範圍限制,黑框,矩形框可以自定義
const extent = this.map.getExtent()
// set map's max extent to map's extent at zoom 18
this.map.setMaxExtent(extent)
this.map.setZoom(this.map.getZoom(), { animation: true })
this.map.getLayer('build')
.addGeometry(
new maptalks.Polygon(extent.toArray(), {
symbol: { 'polygonOpacity': 0, 'lineWidth': 0 }
})
)
// 監聽地圖點選事件
this.map.on('click', function(e) {
if (that.videoPlayer) {
that.videoPlayer.dispose()
that.videoPlayer = null
}
})
// 監控裝置上圖
this.getMarks()
this.getBuildCustom()
},
methods: {
// 獲取裝置
getMarks() {
const that = this
/* getMapMarks().then((res) => {
if (res.code === 0) {
// 處理資料
} else {
this.$message.error(res.msg)
return
}
}) */
const res = [
{
id: 11,
type: 'monitor',
name: '奧克斯廣場5樓H座',
position: [121.60183757543565, 31.200640797615055]
},
{
id: 12,
type: 'fire',
name: '奧克斯廣場4樓H座',
position: [121.60308748483658, 31.201885342597965]
},
{
id: 13,
type: 'car',
name: '奧克斯廣場3樓H座',
position: [121.60235390067102, 31.19988441467285]
},
{
id: 14,
type: 'monitor',
name: '奧克斯廣場2樓H座',
position: [121.60212725400926, 31.199884414672855]
},
{
id: 15,
type: 'monitor',
name: '奧克斯廣場1樓H座',
position: [121.6019180417061, 31.200351119041446]
}
]
const monitor = []
const face = []
const car = []
const fire = []
res.forEach((item, index) => {
if (item.type === 'monitor') {
monitor.push(item)
}
if (item.type === 'face') {
face.push(item)
}
if (item.type === 'car') {
car.push(item)
}
if (item.type === 'fire') {
fire.push(item)
}
})
that.monitor = monitor
that.face = face
that.car = car
that.fire = fire
that.markerInMap()
},
// 樓宇和自定義區域搜尋
getBuildCustom() {
const that = this
// 自定義區域搜尋
that.custom = [
{
id: 31,
name: '中心湖',
position: [
[121.60619238941621, 31.20185829162874],
[121.60590807526063, 31.20207823276796],
[121.6057578715558, 31.20204604625978],
[121.60483519165467, 31.202249894144913],
[121.60468498794984, 31.202190885546585],
[121.60442749588441, 31.202228436472794],
[121.6042290124173, 31.20208896160402],
[121.60413245289277, 31.201949486735245],
[121.60370329945039, 31.201933393481156],
[121.60349945156526, 31.20180464744844],
[121.60347799389314, 31.20157397747316],
[121.60360673992585, 31.201166281702896],
[121.60361746876191, 31.20109654426851],
[121.60358528225373, 31.200951704981705],
[121.60363892643403, 31.200726399424454],
[121.60397152035188, 31.200495729449173],
[121.60436312286805, 31.20029724598207],
[121.6047493609662, 31.20029724598207],
[121.60501758186768, 31.200377712252518],
[121.60535017578553, 31.200624475481888],
[121.60538236229371, 31.200876603129288],
[121.60536626903962, 31.201160917284867],
[121.60594562618684, 31.20131648540773],
[121.60619238941621, 31.201219925883194],
[121.6067127379651, 31.201219925883194],
[121.60728673069428, 31.20136476517],
[121.60738865463685, 31.20130039215364],
[121.60745302765321, 31.20131648540773],
[121.60745839207124, 31.201472053530594],
[121.60720626442384, 31.201477417948624],
[121.60681466190766, 31.201413044932266],
[121.60641769497346, 31.201461324694534],
[121.60622457592439, 31.20158470630922],
[121.60617093174409, 31.201734910014054],
[121.60619775383424, 31.20186365604677]
]
}
]
/* getCustom().then((res) => {
if (res.code === 0) {
that.custom = res.data
} else {
this.$message.error(res.msg)
return
}
})*/
// 樓宇搜尋
that.building = [
{
id: 21,
name: '海航萬邦中心',
position: [
[121.60635445018207, 31.200443756030936],
[121.60635445018207, 31.199907314227957],
[121.60639200110828, 31.19983757679357],
[121.60646173854266, 31.19981075470342],
[121.60678896804248, 31.1998429412116],
[121.60681579013263, 31.199885856555838],
[121.60682115455066, 31.200411569522757],
[121.60680506129657, 31.200486671375174],
[121.60679433246051, 31.200534951137442],
[121.60671386619006, 31.200524222301382],
[121.60670850177203, 31.200502764629263],
[121.60663876433765, 31.200497400211233],
[121.60662267108356, 31.200513493465323],
[121.6065046538869, 31.200486671375174],
[121.60649392505084, 31.200459849285025],
[121.60641882319842, 31.200449120448965],
[121.6063598146001, 31.200454484866995],
[121.60635445018207, 31.200438391612906]
]
}
]
/* getBuild().then((res) => {
if (res.code === 0) {
that.building = res.data
} else {
this.$message.error(res.msg)
return
}
})*/
that.markBuilding()
that.markCustom()
},
doDraw() {
this.drawTool.setMode('Polygon').enable()
document.getElementById('map').setAttribute('title', '單擊左鍵開始繪製,雙擊左鍵結束繪製')
},
// 裝置資源上圖
markerInMap() {
const that = this
for (var m = 0; m < that.monitor.length; m++) {
var markerm = new maptalks.Marker(
that.monitor[m].position, // lon and lat in here
{ // 圖形樣式
'symbol': {
'markerFile': require('./../../assets/baseImg/monitor_map.png'),
'markerWidth': 28,
'markerHeight': 36,
'markerDx': 0,
'markerDy': 0,
'markerOpacity': 1
}
}
).addTo(that.layer_monitor)
markerm.setInfoWindow({
'autoPan': true,
'width': 485,
'minHeight': 330,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content equip-content">' +
'<div class="pop-video"><video id="video_' + that.monitor[m].id + '" class="video-js vjs-default-skin vjs-big-play-centered" controls fluid="true" width="485" height="275">' +
' <source src="rtmp://212.64.34.125:10935/hls/stream_27" type="rtmp/flv">' +
'</video></div>' +
'<div class="pop-bottom">' + that.monitor[m].name + '<a id="moreMonitor" style="cursor:pointer;" data-id="' + that.monitor[m].id + '">檢視更多<i class="el-icon-arrow-right"></i></a></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const moreMonitor = document.getElementById('moreMonitor')
moreMonitor.onclick = function() {
that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }})
}
that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() {
this.play()
})
}, 1000)
}
}
for (var f = 0; f < that.face.length; f++) {
var markerf = new maptalks.Marker(
that.face[f].position, // lon and lat in here
{ // 圖形樣式
'symbol': {
'markerFile': require('./../../assets/baseImg/monitor_map.png'),
'markerWidth': 28,
'markerHeight': 36,
'markerDx': 0,
'markerDy': 0,
'markerOpacity': 1
}
}
).addTo(that.layer_face)
markerf.setInfoWindow({
'autoPan': true,
'width': 485,
'minHeight': 330,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content equip-content">' +
'<div class="pop-video"><video id="video_' + that.face[f].id + '" class="video-js vjs-default-skin vjs-big-play-centered" controls fluid="true" width="485" height="275">' +
' <source src="rtmp://212.64.34.125:10935/hls/stream_27" type="rtmp/flv">' +
'</video></div>' +
'<div class="pop-bottom">' + that.face[f].name + '<a id="moreMonitor" style="cursor:pointer;" data-id="' + that.face[f].id + '">檢視更多<i class="el-icon-arrow-right"></i></a></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const moreMonitor = document.getElementById('moreMonitor')
moreMonitor.onclick = function() {
that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }})
}
that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() {
this.play()
})
}, 500)
}
}
for (var c = 0; c < that.car.length; c++) {
var markerc = new maptalks.Marker(
that.car[c].position, // lon and lat in here
{ // 圖形樣式
'symbol': {
'markerFile': require('./../../assets/baseImg/car_map.png'),
'markerWidth': 28,
'markerHeight': 36,
'markerDx': 0,
'markerDy': 0,
'markerOpacity': 1
}
}
).addTo(that.layer_car)
markerc.setInfoWindow({
'autoPan': true,
'width': 485,
'minHeight': 330,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content equip-content">' +
'<div class="pop-video"><video id="video_' + that.car[c].id + '" class="video-js vjs-default-skin vjs-big-play-centered" controls fluid="true" width="485" height="275">' +
' <source src="rtmp://212.64.34.125:10935/hls/stream_27" type="rtmp/flv">' +
'</video></div>' +
'<div class="pop-bottom">' + that.car[c].name + '<a id="moreMonitor" style="cursor:pointer;" data-id="' + that.car[c].id + '">檢視更多<i class="el-icon-arrow-right"></i></a></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const moreMonitor = document.getElementById('moreMonitor')
moreMonitor.onclick = function() {
that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }})
}
that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() {
this.play()
})
}, 500)
}
}
for (var i = 0; i < that.fire.length; i++) {
var markeri = new maptalks.Marker(
that.fire[i].position, // lon and lat in here
{ // 圖形樣式
'symbol': {
'markerFile': require('./../../assets/baseImg/fire_map.png'),
'markerWidth': 28,
'markerHeight': 36,
'markerDx': 0,
'markerDy': 0,
'markerOpacity': 1
}
}
).addTo(that.layer_fire)
markeri.setInfoWindow({
'autoPan': true,
'width': 485,
'minHeight': 330,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content equip-content">' +
'<div class="pop-video"><video id="video_' + that.fire[i].id + '" class="video-js vjs-default-skin vjs-big-play-centered" controls fluid="true" width="485" height="275">' +
' <source src="rtmp://212.64.34.125:10935/hls/stream_27" type="rtmp/flv">' +
'</video></div>' +
'<div class="pop-bottom">' + that.fire[i].name + '<a id="moreMonitor" style="cursor:pointer;" data-id="' + that.fire[i].id + '">檢視更多<i class="el-icon-arrow-right"></i></a></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const moreMonitor = document.getElementById('moreMonitor')
moreMonitor.onclick = function() {
that.$router.push({ path: '/video/realMonitor', query: { id: moreMonitor.dataset.id }})
}
that.videoPlayer = videojs(document.getElementById('video_' + moreMonitor.dataset.id), {}, function() {
this.play()
})
}, 500)
}
}
},
// 樓宇上圖
markBuilding() {
// -5-//多邊形懸停,點選事件,同樣支援marker
const that = this
for (var i = 0; i < that.building.length; i++) {
var building = new maptalks.Polygon(
that.building[i].position, // lon and lat in here
{ // 圖形樣式
visible: true,
editable: true,
cursor: 'pointer',
shadowBlur: 0,
shadowColor: 'black',
draggable: false,
dragShadow: false, // display a shadow during dragging
drawOnAxis: null, // force dragging stick on a axis, can be: x, y
symbol: {
'lineColor': 'rgba(0,208,223,0.5)',
'lineWidth': 0,
'polygonFill': 'rgba(0,208,223,0.5)',
'polygonOpacity': 0.6
}
}
).addTo(that.layer_build)
building.setInfoWindow({
'autoPan': true,
'width': 410,
'minHeight': 190,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content build-content">' +
'<div class="pop-img"><img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542365932900&di=615c41113e473f04a66bafe71fd39d6e&imgtype=0&src=http%3A%2F%2Fpic.ynshangji.com%2F00user%2Fproduct0_13%2F2014-2-11%2F354395-16103365.jpg"/><p class="pop-name"><span class="text-ellipsis" title="' + that.building[i].name + '">' + that.building[i].name + '</span><a id="viewDetial" data-id="' + that.building[i].id + '">詳情<i class="el-icon-arrow-right"></i></a></p></div>' +
'<div class="pop-txt"><ul><li>入駐企業:87 家 </li><li>登記人員:56 家 </li><li>今日訪客:30 人 </li><li>登記車輛:67 輛 </li><li>實時人數:392 人 </li><li>監控點位:87 個 </li><li>人臉門禁:16 個 </li><li>消防設施:188 個</li></ul></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const viewDetial = document.getElementById('viewDetial')
viewDetial.onclick = function() {
that.$router.push({ path: '/building/index', query: { id: viewDetial.dataset.id }})
}
}, 500)
}
}
// 滑鼠懸移,支援多種事件。。。
building.on('mouseenter', function(e) {
// update markerFill to highlight
e.target.updateSymbol({
'polygonFill': 'rgb(135,196,240)'
})
}).on('mouseout', function(e) {
// reset color
e.target.updateSymbol({
'polygonFill': 'rgba(0,208,223,0.5)'
})
})
},
// 自定義區域上圖
markCustom() {
// -5-//多邊形懸停,點選事件,同樣支援marker
const that = this
for (var i = 0; i < that.custom.length; i++) {
var custom = new maptalks.Polygon(
that.custom[i].position, // lon and lat in here
{ // 圖形樣式
visible: true,
editable: true,
cursor: 'pointer',
shadowBlur: 0,
shadowColor: 'black',
draggable: false,
dragShadow: false, // display a shadow during dragging
drawOnAxis: null, // force dragging stick on a axis, can be: x, y
symbol: {
'lineColor': 'rgba(0,208,223,0.5)',
'lineWidth': 0,
'polygonFill': 'rgba(0,208,223,0.5)',
'polygonOpacity': 0.6
}
}
).addTo(that.layer_build)
custom.setInfoWindow({
'autoPan': true,
'width': 330,
'minHeight': 220,
'dy': 4,
'custom': false, // 只使用定製自定義true
'autoOpenOn': 'click', // set to null if not to open when clicking on marker
'autoCloseOn': 'click',
// 支援自定義html內容
'content': '<div class="content custom-content">' +
'<div class="pop-img"><img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542365932900&di=615c41113e473f04a66bafe71fd39d6e&imgtype=0&src=http%3A%2F%2Fpic.ynshangji.com%2F00user%2Fproduct0_13%2F2014-2-11%2F354395-16103365.jpg"/><p class="pop-name"><span class="text-ellipsis" title="' + that.custom[i].name + '">' + that.custom[i].name + '</span><a id="viewDetial" data-id="' + that.custom[i].id + '">詳情<i class="el-icon-arrow-right"></i></a></p></div>' +
'<div class="pop-txt"><ul><li>值班人員:劉佳慧 </li><li>值班電話:17778098789 </li></ul></div>' +
'</div>'
}).on('mousedown', onClick)
function onClick(e) {
setTimeout(function() {
const viewDetial = document.getElementById('viewDetial')
viewDetial.onclick = function() {
that.$router.push({ path: '/building/index', query: { id: viewDetial.dataset.id }})
}
}, 500)
}
}
// 滑鼠懸移,支援多種事件。。。
custom.on('mouseenter', function(e) {
// update markerFill to highlight
e.target.updateSymbol({
'polygonFill': 'rgb(135,196,240)'
})
}).on('mouseout', function(e) {
// reset color
e.target.updateSymbol({
'polygonFill': 'rgba(0,208,223,0.5)'
})
})
},
// 飛行視角定位到某地點
changeView(center) {
this.map.animateTo({
zoom: 18,
center: center
}, {
duration: 1000
})
}
}
}
</script>
<style scoped>
</style>
<style lang="less">
.base-map {
.container {
width: 100%;
height: 100%;
}
.content {
color: #666;
width: 410px;
height: 300px;
overflow:hidden;
background-color: #fff;
border-radius:8px;
-webkit-box-shadow: 0 0 8px 5px rgba(0,0,0,0.2);
-moz-box-shadow: 0 0 8px 5px rgba(0,0,0,0.2);
box-shadow: 0 0 8px 5px rgba(0,0,0,0.2);
&:after{
display:inline-block;
content:'';
border-width:0 0 25px 30px;
border-color:transparent transparent #fff transparent;
border-style:solid dashed dashed dashed;
position: absolute;
bottom: -11px;
left: 50%;
margin-left: -15px;
-webkit-transform: rotate(-36deg);
-moz-transform: rotate(-36deg);
-ms-transform: rotate(-36deg);
-o-transform: rotate(-36deg);
transform: rotate(-36deg);
z-index:0;
}
.pop-img{
position:relative;
width:100%;
height:190px;
overflow:hidden;
}
img{
width:100%;
}
ul li{
line-height:24px;
float:left;
width:33%;
text-align:left;
}
.pop-name{
position: absolute;
left:50%;
top:8px;
width:236px;
height:40px;
margin-left:-118px;
line-height:40px;
border-radius:30px;
background:url('./../../assets/baseImg/pop_img.png') no-repeat 100%;
color:#fff;
font-size: 16px;
}
a{
float:right;
margin-right:10px;
font-size: 14px;
color: rgba(255,255,255,0.8);
}
a:hover{
color:#fff;
}
span{
display:inline-block;
width:160px;
text-align:center;
}
.pop-txt{
padding:15px;
font-size: 14px;
color: #646464;
}
&.custom-content{
width:350px;
height:220px;
.pop-img{
height:170px;
}
ul li{
width:50%;
}
.pop-name{
width:160px;
margin-left:-80px;
background:url('./../../assets/baseImg/pop_img.png') no-repeat 100%;
color:#fff;
font-size: 16px;
}
span{
width:100px;
}
}
&.equip-content{
height:330px;
.pop-bottom{
height:54px;
line-height:54px;
font-size:14px;
color:#323232;
padding:0 18px;
}
a{
float:right;
font-size:14px;
color:#323232;
}
a:hover{
color:#347eff;
}
}
}
.pop-title {
padding-left:10px;
font-size: 14px;
height:36px;
line-height:36px;
}
.pop-video{
width:100%;
height:275px;
}
.video-js{
width:100%;
height:100%;
}
}
</style>
相關推薦
vue專案中實現maptalks地圖上彈框使用videojs播放實時視訊rtmp流
不限制於vue專案,區別只是相關檔案的引入 最終實現效果如下: 1、首先引入需要的資源:vue-video-player、maptalks相關 npm install vue-video-player --save npm install maptalks -
在vue專案中實現註冊時改變頭像,同時實現將圖片上傳的伺服器端
一.如何實現在註冊時點選頭像時實現更改圖片的操作 1.將img和input[type="file"]放在同一個div中,利用絕對定位,讓兩者擁有相同的大小,將input的預設樣式變為透明,讓img覆蓋的input之上;img中有一個屬性,acc
vue專案中實現新增收藏的功能,以及利用vue-resource傳送請求
1.新增收藏功能 建立一張表,儲存歌手id,使用者id,利用外來鍵將歌手錶與使用者表關聯起來。如果新增收藏之後,為該使用者新增一條資料,取消收藏後,將該條資料刪除。 當用戶登入之後才能顯示歌手列表中該使用者已經收藏過的歌手,然後將這些收
vue專案中,實現遮罩
問題: 1.vue中的元件會自動生成虛擬DOM,無法設定高度的百分比 2.選擇vue例項的鉤子函式 實現: 選擇mounted鉤子函式(此函式是在DOM渲染完成之後呼叫),在此函式值中動態設定目標div的高度,高度的單位為px.用另一個元素的clientHeight為目標idv賦值 程式碼
vue專案中實現懶載入
Vue-lazyload外掛實現懶載入 一. 外掛的下載: 利用npm下載安裝到專案中 npm install vue-lazyload --save-dev 二.外掛的註冊,及屬性的配置。 接下來只需要,在專案的入口檔案 main.js 中進行相關的屬性配置和註冊即可。
vue專案中如何利用base64上傳圖片與檔案
前端在進行資原始檔上傳的時候,可以藉助HTML5中,fileReader物件進行圖片和檔案的上傳。利用該物件提供的一些屬性方法更加方便的獲取所上傳的檔案資訊。在vue專案中操作方法如下: 1)繫結input[type=‘file’]的change事件 <inpu
Vue專案中實現圖片懶載入
---對於圖片過多的頁面,為了加速頁面載入速度,所以很多時候我們需要將頁面內未出現在可視區域內的圖片先不做載入, 等到滾動到可視區域後再去載入。這樣子對於頁面載入效能上會有很大的提升,也提高了使用者體驗
vue專案中的 多圖上傳。涉及壓縮
<html> <head> <link rel="stylesheet" href="./Multi-upload.css"> <script src="./vue.min.js"></script> <script s
如何在Vue專案中實現吸頂元素
我的思路就是判斷合適的時候將這個元素的position設為fixed,那麼這個合適的時機如何判斷呢?我們可以計算頁面滾動的距離。 監聽頁面滾動狀態 在mounted鉤子中加入以下程式碼: mounted() { // handleScroll為頁面滾動的監聽回撥 wind
Vue專案中實現錨點定位
背景 今天在開發限時練-提分加專案的時候,有一個需要錨點定位的需求,而在Vue專案中,使用傳統的在a標籤的href屬性中寫id的方法無效,會導致瀏覽器的地址改變從而跳轉到其他頁面。 解決
百度地圖使用之-----vue專案中百度地圖的應用以及遇到的一些問題
我們在專案開發時對於地圖應用也是比較常見的,因為百度地圖的開發文件都是基於HTML檔案的,並沒有介紹在Vue專案中的應用,而且網上關於在vue中的應用也比較少,官網的文件還是很容易看的懂,但是應用到vue中還是會遇到很多問題的,下面我就分享一些我在vue專案使用百度地圖的體會
vue專案中vue-scroller實現上拉載入和下拉重新整理
vue目前是眾所周知的流行框架大家都知道的,vue全家桶的成員是:vue-cli,vuex,vue-router,vue-axios(vue2.0)。然後它的第三方外掛也有很多,比如:vue-scroller,vue-lazyload,vue-awesome-swiper等等的。之前我已經給大家介紹過vue-
vue專案中jsonp抓取資料實現方式
先安裝依賴:cnpm install --save jsonp 程式碼如下: 1. 然後建立一個jsonp.js import originJSONP from 'jsonp' //引用jsonp export default function jsonp(url,data,opt
Vue專案中使用better-scroll實現一個輪播圖
前言 better-scroll是一個非常非常強大的第三方庫 在移動端利用這個庫 不僅可以實現一個非常類似原生ScrollView的效果 也可以實現一個輪播圖的效果 這裡就先記錄一下自己實現這個效果的一些過程吧 思路 1.首先要確定自己的HTML結構 基本結構就是一個wrapper包含一個content
前端框架Vue——vue-i18n ,vue專案中如何實現國際化,$t的用法
一、demo 場景需求分析 需求很簡單,左上角 ‘’網易雲音樂‘’就是一箇中英文切換的按鈕,點選彈出提示框,確認切換語言後,實現英文版本。 切換成英文版本: 二、實現國際化 首先,我開發是以 vue 為技術棧,所以如題用的國際化外掛是 vue
在vue專案中引入高德地圖
1 在index.html檔案中引入js檔案<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.0&key="></script> 2 334 3
在vue專案中,關於 vue-scroller ,上拉一直載入的問題
關鍵:上拉載入方法方法,都會有一個回撥函式 done,回撥函式的傳引數很關鍵, done(true) 停止載入,會顯示“已無更多資料” done(false) 允許下次繼續 看截圖: 1
vue專案中要實現展示markdown檔案
網上有很多用vuepress的方法,我試了下,另外起一個vue程式的話,很容易實現該方法,但是如果是要嵌入到已有的vue專案中,我沒有嘗試成功,於是用了以下方法來實現。 1)安裝npm install
vue-baidu-map vue專案中使用百度地圖(搜尋,資訊視窗,獲取地點詳細資訊)
最近做了一個垃圾分類的專案,要求使用百度地圖。主要實現以下幾個功能: 1、點選地圖獲取到經緯度和地點資訊 2、點選地圖實時顯示資訊視窗 3、區域搜尋功能,具體功能就是如下圖 ↓ 兩個api網址,一個vue-baidu-map的api,一個JavaScript的百度
vue中實現檔案的上傳讀取及下載
檔案的上傳利用input標籤的type="file"屬性,讀取用FileReader物件,下載通過建立a標籤實現 <template> <div class="filediv"> <el-button @click="downloadFile">下