8 changed files with 2411 additions and 1232 deletions
			
			
		| After Width: | Height: | Size: 54 KiB | 
| After Width: | Height: | Size: 65 KiB | 
| @ -1,6 +1,6 @@ | |||||
| export const apiUrl = { | export const apiUrl = { | ||||
|     CisApiUrl: 'http://192.168.1.119:800/api', |     CisApiUrl: 'http://192.168.1.119:800/api', | ||||
|     WebRtcUrl: 'http://192.168.1.119:8000', |     WebRtcUrl: 'http://192.168.1.119:8000', | ||||
|     OnvifApiUrl: '' |     OnvifApiUrl: 'http://192.168.1.119:800/api' | ||||
|     // CisApiUrl: 'https://192.168.1.119:5001/api'
 |     // CisApiUrl: 'https://192.168.1.119:5001/api'
 | ||||
| } | } | ||||
|  | |||||
| @ -0,0 +1,559 @@ | |||||
|  | <template> | ||||
|  |   <div> | ||||
|  |     <div class="camera-control"> | ||||
|  |       <div class="camera-control-title"> | ||||
|  |         云台 | ||||
|  |       </div> | ||||
|  |       <hr style="background-color: #e2e2e2; height: 1px; border: 0;" /> | ||||
|  |       <div class="camera-operate"> | ||||
|  |         <div class="camera-direct"> | ||||
|  |           <!--左上--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:0 0" | ||||
|  |                @mousedown="leftUpStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--上--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-30px 0" | ||||
|  |                @mousedown="upStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--右上--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-60px 0" | ||||
|  |                @mousedown="rightUpStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--左--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:0 -30px" | ||||
|  |                @mousedown="leftStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--自动--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-30px -30px" | ||||
|  |                @click="autoStart()"> | ||||
|  |           </div> | ||||
|  |           <!--右--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-60px -30px" | ||||
|  |                @mousedown="rightStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--左下--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:0 -60px" | ||||
|  |                @mousedown="leftDownStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--下--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-30px -60px" | ||||
|  |                @mousedown="downStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--右下--> | ||||
|  |           <div class="direct-item" | ||||
|  |                style="background-position:-60px -60px" | ||||
|  |                @mousedown="rightDownStart()" | ||||
|  |                @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |         <div class="camera-function"> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-128px 0;border-right: 1px rgba(179, 177, 177, 0.97) dotted;" | ||||
|  |                  @mousedown="zoomIn()" | ||||
|  |                  @mouseup="stopMove()" | ||||
|  |                  title="变倍+"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-92px 0;" | ||||
|  |                  @mousedown="zoomOut()" | ||||
|  |                  @mouseup="stopMove()" | ||||
|  |                  title="变倍-"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-128px -30px;border-right:1px rgba(179, 177, 177, 0.97) dotted; " | ||||
|  |                  @mousedown="focusIn()" | ||||
|  |                  @mouseup="focusStop()" | ||||
|  |                  title="变焦+"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-92px -30px;" | ||||
|  |                  @mousedown="focusOut()" | ||||
|  |                  @mouseup="focusStop()" | ||||
|  |                  title="变焦-"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-202px 0; border-right:1px rgba(179, 177, 177, 0.97) dotted;" | ||||
|  |                  @mousedown="handleScreenSnap()" | ||||
|  |                  title="抓拍"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" | ||||
|  |                  style="background-position:-162px -89px;" | ||||
|  |                  @mousedown="openImgListDialog()" | ||||
|  |                  title="抓拍列表"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |       <a-row> | ||||
|  |         <a-col span="1"></a-col> | ||||
|  |         <a-col span="19"> | ||||
|  |           <label class="demonstration">云台速度:{{ currentStep }}</label> | ||||
|  |         </a-col> | ||||
|  |       </a-row> | ||||
|  |       <a-row type="flex"> | ||||
|  |         <a-col span="2"></a-col> | ||||
|  |         <a-col span="19"> | ||||
|  |           <input type="range" | ||||
|  |                  min="1" | ||||
|  |                  max="10" | ||||
|  |                  step="1" | ||||
|  |                  v-model="currentStep" /> | ||||
|  |         </a-col> | ||||
|  |       </a-row> | ||||
|  |     </div> | ||||
|  |     <!-- 图片列表弹窗 --> | ||||
|  |     <!-- <img-list-dialog :visible.sync="screenSnapList.visible" | ||||
|  |                      :camera-id="videoInfo.cameraId" | ||||
|  |                      :title="screenSnapList.title" /> --> | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script> | ||||
|  | // import callUtil from '@/utils/callUtil' | ||||
|  | // import ImgListDialog from '@/components/earthMap/ImgListDialog' | ||||
|  | // import { axios } from '@/utils/request' | ||||
|  | // import axios from "axios"; | ||||
|  | import {axios} from '@/utils/axios'; | ||||
|  | import Qs from 'qs' | ||||
|  | import * as onvifApi from '@/axios/onvif/onvifApi'; | ||||
|  | import {apiUrl} from "@/axios"; | ||||
|  | // import { postAction } from '@api/manage' | ||||
|  | 
 | ||||
|  | export default { | ||||
|  |   name: 'VideoControl', | ||||
|  |   props: ['id', 'name', 'width', 'height',  | ||||
|  |   // 'ip',  | ||||
|  |   'user',  | ||||
|  |   'password'], | ||||
|  |   components: { | ||||
|  |     // ImgListDialog | ||||
|  |   }, | ||||
|  |   data() { | ||||
|  |     return { | ||||
|  |       // onvifUrl: window._CONFIG['onvifURL'], | ||||
|  |       // onvifUrl: "http://192.168.1.119:800/api", | ||||
|  |       ip: '337342439297349',//测试球机 | ||||
|  |       onvifUrl: apiUrl.OnvifApiUrl, | ||||
|  |       currentStep: 5, | ||||
|  |       autoFlag: false, | ||||
|  |       screenSnapList: { | ||||
|  |         title: '抓拍列表', | ||||
|  |         visible: false | ||||
|  |       }, | ||||
|  |       videoInfo: { | ||||
|  |         cameraId: this.id, | ||||
|  |         cameraName: this.name, | ||||
|  |         cameraIP: this.ip, | ||||
|  |         cameraUser: this.user, | ||||
|  |         cameraPassword: this.password, | ||||
|  |         instruct: this.instruct, | ||||
|  |         step: 0 | ||||
|  |       }, | ||||
|  |       url: { | ||||
|  |         isExist: '/onvif/isExists', | ||||
|  |         add: '/onvif/register', | ||||
|  |         ptzMove: '/onvif/continuousMove', | ||||
|  |         ptzStopMove: '/onvif/stopMove', | ||||
|  |         focusMove: '/onvif/focusContinuousMove', | ||||
|  |         focusStopMove: '/onvif/focusStopMove', | ||||
|  |         getSnapshot: '/onvif/getSnapshotUrl', | ||||
|  |         // screenSnap: 'camera/setting/screenSnap', | ||||
|  |         delete: '/onvif/delete' | ||||
|  |       }, | ||||
|  |       visible: false | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   mounted() { | ||||
|  |     this.checkExistOnvif() | ||||
|  |   }, | ||||
|  |   beforeUnmount(){ | ||||
|  |     //注销 | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       this.onvifOperateHandler(this.url.delete, 'post', params) | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     onvifOperateHandler(url, method, params, callback) { | ||||
|  |       url = this.onvifUrl + url | ||||
|  |       let reqParams = { url: url, method: method } | ||||
|  |       let dataParam = (method === 'get') ? { params: params } : { data: Qs.stringify(params) } | ||||
|  |       Object.assign(reqParams, dataParam); | ||||
|  |       // console.log("reqParams",reqParams); | ||||
|  |       axios(reqParams).then((res) => { | ||||
|  |         // console.log(res); | ||||
|  |         if (res.status == 200) { | ||||
|  |           if (!res.Errors) { | ||||
|  |             // console.log("成功"); | ||||
|  |             if (callback && typeof callback === 'function') { | ||||
|  |               callback(res) | ||||
|  |             } | ||||
|  |           } else { | ||||
|  |             // callUtil.$emit('openNotification', res.Errors, 2, 'warning', '50px') | ||||
|  |           } | ||||
|  |         } else { | ||||
|  |           // callUtil.$emit('openNotification', '云台控制异常', 2, 'error', '50px') | ||||
|  |         } | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     checkExistOnvif() { | ||||
|  |       // Check onvif server is exists, if not exists , add it | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       this.onvifOperateHandler(this.url.isExist, 'get', params, (res) => { | ||||
|  |         console.log(res); | ||||
|  |         if (!res.isSuccess || res.data !== true) { | ||||
|  |           console.log("不存在,请先注册"); | ||||
|  |           Object.assign(params, { username: this.videoInfo.cameraUser, password: this.videoInfo.cameraPassword }) | ||||
|  |           this.onvifOperateHandler(this.url.add, 'post', params, (res) => { | ||||
|  |             console.log("注册信息",res); | ||||
|  |             console.log("注册成功");  | ||||
|  |           }) | ||||
|  |         } | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     createPtzParam(instruct, step) { | ||||
|  |       let ptzParam | ||||
|  |       let speed = 0.1 * step | ||||
|  |       switch (instruct) { | ||||
|  |         case 'up': | ||||
|  |           ptzParam = new Float32Array([0, 1, 0]) | ||||
|  |           break | ||||
|  |         case 'leftUp': | ||||
|  |           ptzParam = new Float32Array([-1, 1, 0]) | ||||
|  |           break | ||||
|  |         case 'rightUp': | ||||
|  |           ptzParam = new Float32Array([1, 1, 0]) | ||||
|  |           break | ||||
|  |         case 'down': | ||||
|  |           ptzParam = new Float32Array([0, -1, 0]) | ||||
|  |           break | ||||
|  |         case 'leftDown': | ||||
|  |           ptzParam = new Float32Array([-1, -1, 0]) | ||||
|  |           break | ||||
|  |         case 'rightDown': | ||||
|  |           ptzParam = new Float32Array([1, -1, 0]) | ||||
|  |           break | ||||
|  |         case 'left': | ||||
|  |           ptzParam = new Float32Array([-1, 0, 0]) | ||||
|  |           break | ||||
|  |         case 'right': | ||||
|  |           ptzParam = new Float32Array([1, 0, 0]) | ||||
|  |           break | ||||
|  |         case 'zoomIn': | ||||
|  |           ptzParam = new Float32Array([0, 0, 1]) | ||||
|  |           break | ||||
|  |         case 'zoomOut': | ||||
|  |           ptzParam = new Float32Array([0, 0, -1]) | ||||
|  |           break | ||||
|  |         default: | ||||
|  |           ptzParam = new Float32Array([0, 0, 0]) | ||||
|  |       } | ||||
|  |       return { pan: ptzParam[0] * speed, tilt: ptzParam[1] * speed, zoom: ptzParam[2] * speed } | ||||
|  |     }, | ||||
|  |     upStart() { | ||||
|  |        | ||||
|  |       let instruct = 'up' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |       console.log("上",params); | ||||
|  |     }, | ||||
|  |     leftUpStart() { | ||||
|  |       let instruct = 'leftUp' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     rightUpStart() { | ||||
|  |       let instruct = 'rightUp' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     downStart() { | ||||
|  |       let instruct = 'down' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |       console.log("下",params); | ||||
|  |     }, | ||||
|  |     leftDownStart() { | ||||
|  |       let instruct = 'leftDown' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     rightDownStart() { | ||||
|  |       let instruct = 'rightDown' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     leftStart() { | ||||
|  |       let instruct = 'left' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     rightStart() { | ||||
|  |       let instruct = 'right' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     zoomIn() { | ||||
|  |       let instruct = 'zoomIn' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     zoomOut() { | ||||
|  |       let instruct = 'zoomOut' | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       let ptzParams = this.createPtzParam(instruct, step) | ||||
|  |       Object.assign(params, ptzParams) | ||||
|  |       this.onvifOperateHandler(this.url.ptzMove, 'post', params) | ||||
|  |     }, | ||||
|  |     autoStart() { | ||||
|  |       if (this.autoFlag) { | ||||
|  |         this.stopMove() | ||||
|  |         this.autoFlag = false | ||||
|  |       } else { | ||||
|  |         this.leftStart() | ||||
|  |         this.autoFlag = true | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     stopMove() { | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       this.onvifOperateHandler(this.url.ptzStopMove, 'post', params) | ||||
|  |     }, | ||||
|  |     focusIn() { | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       Object.assign(params, { speed: (0.1 * step) }) | ||||
|  |       this.onvifOperateHandler(this.url.focusMove, 'post', params) | ||||
|  |     }, | ||||
|  |     focusOut() { | ||||
|  |       let step = this.currentStep | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       Object.assign(params, { speed: (-0.1 * step) }) | ||||
|  |       this.onvifOperateHandler(this.url.focusMove, 'post', params) | ||||
|  |     }, | ||||
|  |     focusStop() { | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       this.onvifOperateHandler(this.url.focusStopMove, 'post', params) | ||||
|  |     }, | ||||
|  |     handleScreenSnap() { | ||||
|  |       let params = { cameraId: this.ip } | ||||
|  |       this.onvifOperateHandler(this.url.getSnapshot, 'get', params, (res) => { | ||||
|  |         let snapshotUrl = res.data | ||||
|  |         let newInfo = { snapshotUrl: snapshotUrl } | ||||
|  |         Object.assign(newInfo, this.videoInfo) | ||||
|  |         postAction(this.url.screenSnap, newInfo).then(() => { | ||||
|  |         }) | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     openImgListDialog() { | ||||
|  |       this.screenSnapList.visible = true | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style scoped> | ||||
|  | .camera-control { | ||||
|  |   color: #080000; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__bar { | ||||
|  |   background-color: #b00303; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__button { | ||||
|  |   border: 2px solid #848486; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__runway { | ||||
|  |   width: 92%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-operate { | ||||
|  |   display: -webkit-flex; /* Safari */ | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   justify-content: center; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-speed { | ||||
|  |   padding-top: 20px; | ||||
|  |   margin-left: auto; | ||||
|  |   margin-right: auto; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-speed input { | ||||
|  |   width: 40px; | ||||
|  |   color: black; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-title { | ||||
|  |   padding-top: 7px; | ||||
|  |   text-align: center; | ||||
|  |   height: 35px; | ||||
|  |   line-height: 28px; | ||||
|  |   font-size: 16px; | ||||
|  |   font-weight: bold; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct { | ||||
|  |   display: -webkit-flex; /* Safari */ | ||||
|  |   width: 110px; | ||||
|  |   height: 100px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   flex-wrap: wrap; | ||||
|  |   padding: 10px 10px 0 0; | ||||
|  |   /*margin: auto;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item { | ||||
|  |   width: 30px; | ||||
|  |   height: 30px; | ||||
|  |   background-repeat: no-repeat; | ||||
|  |   background-size: 400px 300px; | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons.png'); | ||||
|  |   margin: 1px 1px 1px 1px; | ||||
|  |   border: 1px rgba(190, 188, 188, 0.97) solid; | ||||
|  |   border-radius: 1px; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item:hover { | ||||
|  |   background-color: rgba(208, 212, 208, 0.3); | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons-on.png'); | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item .img { | ||||
|  |   width: 100%; | ||||
|  |   height: 100%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function { | ||||
|  |   display: -webkit-flex; /* Safari */ | ||||
|  |   /*margin-left: 20px;*/ | ||||
|  |   margin-left: 10px; | ||||
|  |   width: 90px; | ||||
|  |   height: 120px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: column; | ||||
|  |   flex-wrap: wrap; | ||||
|  |   padding: 10px 0 0 10px; | ||||
|  |   /*margin: auto;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-box { | ||||
|  |   display: -webkit-flex; /* Safari */ | ||||
|  |   height: 30px; | ||||
|  |   width: 65px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   border: 1px rgba(190, 188, 188, 0.97) solid; | ||||
|  |   border-radius: 1px; | ||||
|  |   margin: 1px 1px 1px 1px; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item { | ||||
|  |   width: 32px; | ||||
|  |   height: 29px; | ||||
|  |   background-repeat: no-repeat; | ||||
|  |   background-size: 400px 300px; | ||||
|  | 
 | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons.png'); | ||||
|  |   /*border: 1px rgba(179, 177, 177, 0.64) solid;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item:hover { | ||||
|  |   background-color: rgba(208, 212, 208, 0.3); | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons-on.png'); | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item .img { | ||||
|  |   width: 100%; | ||||
|  |   height: 100%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | /* 滑动输入条 */ | ||||
|  | input[type='range'] { | ||||
|  |   display: block; | ||||
|  |   -webkit-appearance: none; | ||||
|  |   background-color: #bdc3c7; | ||||
|  |   width: 100%; | ||||
|  |   height: 5px; | ||||
|  |   margin: 6% auto; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb { | ||||
|  |   -webkit-appearance: none; | ||||
|  |   height: 20px; | ||||
|  |   width: 20px; | ||||
|  |   margin-top: -5px; /*使滑块超出轨道部分的偏移量相等*/ | ||||
|  |   background: #ffffff; | ||||
|  |   border-radius: 50%; /*外观设置为圆形*/ | ||||
|  |   border: solid 0.125em rgba(205, 224, 230, 0.5); /*设置边框*/ | ||||
|  |   box-shadow: 0 0.125em 0.125em #3b4547; /*添加底部阴影*/ | ||||
|  |   cursor: pointer; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-runnable-track { | ||||
|  |   height: 10px; | ||||
|  |   border-radius: 10px; /*将轨道设为圆角的*/ | ||||
|  |   box-shadow: 0 1px 1px #def3f8, inset 0 0.125em 0.125em #0d1112; /*轨道内置阴影效果*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']:focus { | ||||
|  |   outline: none; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb:hover { | ||||
|  |   border: 5px solid #b00303; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb:active { | ||||
|  |   transform: scale(1.2); | ||||
|  | } | ||||
|  | </style> | ||||
| @ -0,0 +1,526 @@ | |||||
|  | <!--    | ||||
|  |   *@描述: 云台控制 | ||||
|  |   *@作者:  | ||||
|  |   *@日期:  | ||||
|  |   *@版本:1.0 | ||||
|  |   */ | ||||
|  |   --> | ||||
|  | <template> | ||||
|  |   <div> | ||||
|  |     <div class="camera-control"> | ||||
|  |       <div class="camera-control-title"> | ||||
|  |         云台 | ||||
|  |       </div> | ||||
|  |       <hr style="background-color: #e2e2e2; height: 1px; border: 0;" /> | ||||
|  |       <div class="camera-operate"> | ||||
|  |         <div class="camera-direct"> | ||||
|  |           <!--左上--> | ||||
|  |           <div class="direct-item" style="background-position:0 0" @mousedown="leftUpStart()" @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--上--> | ||||
|  |           <div class="direct-item" style="background-position:-30px 0" @mousedown="upStart()" @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--右上--> | ||||
|  |           <div class="direct-item" style="background-position:-60px 0" @mousedown="rightUpStart()" | ||||
|  |             @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--左--> | ||||
|  |           <div class="direct-item" style="background-position:0 -30px" @mousedown="leftStart()" @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--自动--> | ||||
|  |           <div class="direct-item" style="background-position:-30px -30px" @click="autoStart()"> | ||||
|  |           </div> | ||||
|  |           <!--右--> | ||||
|  |           <div class="direct-item" style="background-position:-60px -30px" @mousedown="rightStart()" | ||||
|  |             @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--左下--> | ||||
|  |           <div class="direct-item" style="background-position:0 -60px" @mousedown="leftDownStart()" | ||||
|  |             @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--下--> | ||||
|  |           <div class="direct-item" style="background-position:-30px -60px" @mousedown="downStart()" | ||||
|  |             @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |           <!--右下--> | ||||
|  |           <div class="direct-item" style="background-position:-60px -60px" @mousedown="rightDownStart()" | ||||
|  |             @mouseup="stopMove()"> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |         <div class="camera-function"> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |               style="background-position:-128px 0;border-right: 1px rgba(179, 177, 177, 0.97) dotted;" | ||||
|  |               @mousedown="zoomIn()" @mouseup="stopMove()" title="变倍+"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" style="background-position:-92px 0;" @mousedown="zoomOut()" @mouseup="stopMove()" | ||||
|  |               title="变倍-"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |               style="background-position:-128px -30px;border-right:1px rgba(179, 177, 177, 0.97) dotted; " | ||||
|  |               @mousedown="focusIn()" @mouseup="focusStop()" title="变焦+"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" style="background-position:-92px -30px;" @mousedown="focusOut()" | ||||
|  |               @mouseup="focusStop()" title="变焦-"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |           <div class="function-box"> | ||||
|  |             <div class="function-item" | ||||
|  |               style="background-position:-202px 0; border-right:1px rgba(179, 177, 177, 0.97) dotted;" | ||||
|  |               @mousedown="handleScreenSnap()" title="抓拍"> | ||||
|  |             </div> | ||||
|  |             <div class="function-item" style="background-position:-162px -89px;" @mousedown="openImgListDialog()" | ||||
|  |               title="抓拍列表"> | ||||
|  |             </div> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |       <a-row> | ||||
|  |         <a-col span="1"></a-col> | ||||
|  |         <a-col span="19"> | ||||
|  |           <label class="demonstration">云台速度:{{ currentStep }}</label> | ||||
|  |         </a-col> | ||||
|  |       </a-row> | ||||
|  |       <a-row type="flex"> | ||||
|  |         <a-col span="2"></a-col> | ||||
|  |         <a-col span="19"> | ||||
|  |           <input type="range" min="1" max="10" step="1" v-model="currentStep" /> | ||||
|  |         </a-col> | ||||
|  |       </a-row> | ||||
|  |     </div> | ||||
|  |     <!-- 图片列表弹窗 --> | ||||
|  |     <!-- <img-list-dialog :visible.sync="screenSnapList.visible" | ||||
|  |                        :camera-id="videoInfo.cameraId" | ||||
|  |                        :title="screenSnapList.title" /> --> | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script lang="ts" setup> | ||||
|  | import { axios } from '@/utils/axios'; | ||||
|  | import Qs from 'qs' | ||||
|  | import { apiUrl } from "@/axios"; | ||||
|  | import { onBeforeUnmount, onMounted, ref } from 'vue'; | ||||
|  | 
 | ||||
|  | const ip = ref('337342439297349') | ||||
|  | const onvifUrl = ref(apiUrl.OnvifApiUrl) | ||||
|  | const currentStep = ref(5); | ||||
|  | const autoFlag = ref(false) | ||||
|  | const screenSnapList: any = ref({ | ||||
|  |   title: '抓拍列表', | ||||
|  |   visible: false | ||||
|  | }) | ||||
|  | const url: any = ref({ | ||||
|  |   isExist: '/onvif/isExists', | ||||
|  |   add: '/onvif/register', | ||||
|  |   ptzMove: '/onvif/continuousMove', | ||||
|  |   ptzStopMove: '/onvif/stopMove', | ||||
|  |   focusMove: '/onvif/focusContinuousMove', | ||||
|  |   focusStopMove: '/onvif/focusStopMove', | ||||
|  |   getSnapshot: '/onvif/getSnapshotUrl', | ||||
|  |   // screenSnap: 'camera/setting/screenSnap', | ||||
|  |   delete: '/onvif/delete' | ||||
|  | }) | ||||
|  | 
 | ||||
|  | onMounted(() => { | ||||
|  |   checkExistOnvif(); | ||||
|  | }) | ||||
|  | onBeforeUnmount(() => { | ||||
|  |   //注销 | ||||
|  |   onvifOperateHandler(url.value.delete, 'post', { cameraId: ip.value }) | ||||
|  | }) | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | //发送指令 | ||||
|  | function onvifOperateHandler(url: any, method: any, params: any, callback: any = {}) { | ||||
|  |   url = onvifUrl.value + url | ||||
|  |   let reqParams = { url: url, method: method } | ||||
|  |   let dataParam = (method === 'get') ? { params: params } : { data: Qs.stringify(params) } | ||||
|  |   Object.assign(reqParams, dataParam); | ||||
|  |   // console.log("reqParams",reqParams); | ||||
|  |   axios(reqParams).then((res: any) => { | ||||
|  |     // console.log(res); | ||||
|  |     if (res.status == 200) { | ||||
|  |       if (!res.Errors) { | ||||
|  |         // console.log("成功"); | ||||
|  |         if (callback && typeof callback === 'function') { | ||||
|  |           callback(res) | ||||
|  |         } | ||||
|  |       } else { | ||||
|  |         // callUtil.$emit('openNotification', res.Errors, 2, 'warning', '50px') | ||||
|  |       } | ||||
|  |     } else { | ||||
|  |       // callUtil.$emit('openNotification', '云台控制异常', 2, 'error', '50px') | ||||
|  |     } | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | //检查是否已经注册 | ||||
|  | function checkExistOnvif() { | ||||
|  |   // Check onvif server is exists, if not exists , add it | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   onvifOperateHandler(url.value.isExist, 'get', params, (res: any) => { | ||||
|  |     console.log(res); | ||||
|  |     if (!res.isSuccess || res.data !== true) { | ||||
|  |       console.log("不存在,请先注册"); | ||||
|  |       onvifOperateHandler(url.value.add, 'post', params, (res: any) => { | ||||
|  |         console.log("注册信息", res); | ||||
|  |         console.log("注册成功"); | ||||
|  |       }) | ||||
|  |     } | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | //指令类型 | ||||
|  | function createPtzParam(instruct: any, step: any) { | ||||
|  |   let ptzParam | ||||
|  |   let speed = 0.1 * step | ||||
|  |   switch (instruct) { | ||||
|  |     case 'up': | ||||
|  |       ptzParam = new Float32Array([0, 1, 0]) | ||||
|  |       break | ||||
|  |     case 'leftUp': | ||||
|  |       ptzParam = new Float32Array([-1, 1, 0]) | ||||
|  |       break | ||||
|  |     case 'rightUp': | ||||
|  |       ptzParam = new Float32Array([1, 1, 0]) | ||||
|  |       break | ||||
|  |     case 'down': | ||||
|  |       ptzParam = new Float32Array([0, -1, 0]) | ||||
|  |       break | ||||
|  |     case 'leftDown': | ||||
|  |       ptzParam = new Float32Array([-1, -1, 0]) | ||||
|  |       break | ||||
|  |     case 'rightDown': | ||||
|  |       ptzParam = new Float32Array([1, -1, 0]) | ||||
|  |       break | ||||
|  |     case 'left': | ||||
|  |       ptzParam = new Float32Array([-1, 0, 0]) | ||||
|  |       break | ||||
|  |     case 'right': | ||||
|  |       ptzParam = new Float32Array([1, 0, 0]) | ||||
|  |       break | ||||
|  |     case 'zoomIn': | ||||
|  |       ptzParam = new Float32Array([0, 0, 1]) | ||||
|  |       break | ||||
|  |     case 'zoomOut': | ||||
|  |       ptzParam = new Float32Array([0, 0, -1]) | ||||
|  |       break | ||||
|  |     default: | ||||
|  |       ptzParam = new Float32Array([0, 0, 0]) | ||||
|  |   } | ||||
|  |   return { pan: ptzParam[0] * speed, tilt: ptzParam[1] * speed, zoom: ptzParam[2] * speed } | ||||
|  | } | ||||
|  | 
 | ||||
|  | //停止移动 | ||||
|  | function stopMove() { | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   onvifOperateHandler(url.value.ptzStopMove, 'post', params) | ||||
|  | } | ||||
|  | //左上 | ||||
|  | function leftUpStart() { | ||||
|  |   let instruct = 'leftUp' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //上 | ||||
|  | function upStart() { | ||||
|  |   let instruct = 'up' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  |   // console.log("上", params); | ||||
|  | } | ||||
|  | //右上 | ||||
|  | function rightUpStart() { | ||||
|  |   let instruct = 'rightUp' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //下 | ||||
|  | function downStart() { | ||||
|  |   let instruct = 'down' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  |   console.log("下", params); | ||||
|  | } | ||||
|  | //左下 | ||||
|  | function leftDownStart() { | ||||
|  |   let instruct = 'leftDown' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //右下 | ||||
|  | function rightDownStart() { | ||||
|  |   let instruct = 'rightDown' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | 
 | ||||
|  | //左 | ||||
|  | function leftStart() { | ||||
|  |   let instruct = 'left' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //右 | ||||
|  | function rightStart() { | ||||
|  |   let instruct = 'right' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | 
 | ||||
|  | //变倍+ | ||||
|  | function zoomIn() { | ||||
|  |   let instruct = 'zoomIn' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //变倍- | ||||
|  | function zoomOut() { | ||||
|  |   let instruct = 'zoomOut' | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   let ptzParams = createPtzParam(instruct, step) | ||||
|  |   Object.assign(params, ptzParams) | ||||
|  |   onvifOperateHandler(url.value.ptzMove, 'post', params) | ||||
|  | } | ||||
|  | //自动 | ||||
|  | function autoStart() { | ||||
|  |   if (autoFlag.value) { | ||||
|  |     stopMove() | ||||
|  |     autoFlag.value = false | ||||
|  |   } else { | ||||
|  |     leftStart() | ||||
|  |     autoFlag.value = true | ||||
|  |   } | ||||
|  | } | ||||
|  | 
 | ||||
|  | //变焦+ | ||||
|  | function focusIn() { | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   Object.assign(params, { speed: (0.1 * step) }) | ||||
|  |   onvifOperateHandler(url.value.focusMove, 'post', params) | ||||
|  | } | ||||
|  | //变焦- | ||||
|  | function focusOut() { | ||||
|  |   let step = currentStep.value | ||||
|  |   let params = { cameraId: ip.value } | ||||
|  |   Object.assign(params, { speed: (-0.1 * step) }) | ||||
|  |   onvifOperateHandler(url.value.focusMove, 'post', params) | ||||
|  | } | ||||
|  | //停止变焦 | ||||
|  | function focusStop() { | ||||
|  |   onvifOperateHandler(url.value.focusStopMove, 'post', { cameraId: ip.value }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | //抓拍 | ||||
|  | function handleScreenSnap(){ | ||||
|  | 
 | ||||
|  | } | ||||
|  | function openImgListDialog(){ | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style scoped> | ||||
|  | .camera-control { | ||||
|  |   color: #080000; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__bar { | ||||
|  |   background-color: #b00303; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__button { | ||||
|  |   border: 2px solid #848486; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .el-slider__runway { | ||||
|  |   width: 92%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-operate { | ||||
|  |   display: -webkit-flex; | ||||
|  |   /* Safari */ | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   justify-content: center; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-speed { | ||||
|  |   padding-top: 20px; | ||||
|  |   margin-left: auto; | ||||
|  |   margin-right: auto; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-speed input { | ||||
|  |   width: 40px; | ||||
|  |   color: black; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-control-title { | ||||
|  |   padding-top: 7px; | ||||
|  |   text-align: center; | ||||
|  |   height: 35px; | ||||
|  |   line-height: 28px; | ||||
|  |   font-size: 16px; | ||||
|  |   font-weight: bold; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct { | ||||
|  |   display: -webkit-flex; | ||||
|  |   /* Safari */ | ||||
|  |   width: 110px; | ||||
|  |   height: 100px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   flex-wrap: wrap; | ||||
|  |   padding: 10px 10px 0 0; | ||||
|  |   /*margin: auto;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item { | ||||
|  |   width: 30px; | ||||
|  |   height: 30px; | ||||
|  |   background-repeat: no-repeat; | ||||
|  |   background-size: 400px 300px; | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons.png'); | ||||
|  |   margin: 1px 1px 1px 1px; | ||||
|  |   border: 1px rgba(190, 188, 188, 0.97) solid; | ||||
|  |   border-radius: 1px; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item:hover { | ||||
|  |   background-color: rgba(208, 212, 208, 0.3); | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons-on.png'); | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-direct .direct-item .img { | ||||
|  |   width: 100%; | ||||
|  |   height: 100%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function { | ||||
|  |   display: -webkit-flex; | ||||
|  |   /* Safari */ | ||||
|  |   /*margin-left: 20px;*/ | ||||
|  |   margin-left: 10px; | ||||
|  |   width: 90px; | ||||
|  |   height: 120px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: column; | ||||
|  |   flex-wrap: wrap; | ||||
|  |   padding: 10px 0 0 10px; | ||||
|  |   /*margin: auto;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-box { | ||||
|  |   display: -webkit-flex; | ||||
|  |   /* Safari */ | ||||
|  |   height: 30px; | ||||
|  |   width: 65px; | ||||
|  |   display: flex; | ||||
|  |   flex-direction: row; | ||||
|  |   border: 1px rgba(190, 188, 188, 0.97) solid; | ||||
|  |   border-radius: 1px; | ||||
|  |   margin: 1px 1px 1px 1px; | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item { | ||||
|  |   width: 32px; | ||||
|  |   height: 29px; | ||||
|  |   background-repeat: no-repeat; | ||||
|  |   background-size: 400px 300px; | ||||
|  | 
 | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons.png'); | ||||
|  |   /*border: 1px rgba(179, 177, 177, 0.64) solid;*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item:hover { | ||||
|  |   background-color: rgba(208, 212, 208, 0.3); | ||||
|  |   background-image: url('../../assets/images/ptzIcons/ptz-icons-on.png'); | ||||
|  | } | ||||
|  | 
 | ||||
|  | .camera-control .camera-function .function-item .img { | ||||
|  |   width: 100%; | ||||
|  |   height: 100%; | ||||
|  | } | ||||
|  | 
 | ||||
|  | /* 滑动输入条 */ | ||||
|  | input[type='range'] { | ||||
|  |   display: block; | ||||
|  |   -webkit-appearance: none; | ||||
|  |   background-color: #bdc3c7; | ||||
|  |   width: 100%; | ||||
|  |   height: 5px; | ||||
|  |   margin: 6% auto; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb { | ||||
|  |   -webkit-appearance: none; | ||||
|  |   height: 20px; | ||||
|  |   width: 20px; | ||||
|  |   margin-top: -5px; | ||||
|  |   /*使滑块超出轨道部分的偏移量相等*/ | ||||
|  |   background: #ffffff; | ||||
|  |   border-radius: 50%; | ||||
|  |   /*外观设置为圆形*/ | ||||
|  |   border: solid 0.125em rgba(205, 224, 230, 0.5); | ||||
|  |   /*设置边框*/ | ||||
|  |   box-shadow: 0 0.125em 0.125em #3b4547; | ||||
|  |   /*添加底部阴影*/ | ||||
|  |   cursor: pointer; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-runnable-track { | ||||
|  |   height: 10px; | ||||
|  |   border-radius: 10px; | ||||
|  |   /*将轨道设为圆角的*/ | ||||
|  |   box-shadow: 0 1px 1px #def3f8, inset 0 0.125em 0.125em #0d1112; | ||||
|  |   /*轨道内置阴影效果*/ | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']:focus { | ||||
|  |   outline: none; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb:hover { | ||||
|  |   border: 5px solid #b00303; | ||||
|  | } | ||||
|  | 
 | ||||
|  | input[type='range']::-webkit-slider-thumb:active { | ||||
|  |   transform: scale(1.2); | ||||
|  | } | ||||
|  | </style> | ||||
								
									
										File diff suppressed because it is too large
									
								
							
						
					
					Loading…
					
					
				
		Reference in new issue