'use strict' class Cutshot { constructor(opt) { const ops = { el: '', color: '#fff' } this.opt = Object.assign({}, ops, opt) } createCanvas(el) { // debugger const canvas = document.createElement('canvas') canvas.width = el.offsetWidth canvas.height = el.offsetHeight canvas.style.zIndex = 99 canvas.style.position = 'absolute' canvas.style.top = 0 canvas.style.left = 0 el.appendChild(canvas) return canvas } createEvent() { var self = this var el if ((self.opt.el).match(/[#.]/)) { el = document.querySelector(self.opt.el) if (!el) { return console.log('传入的节点没有查找到') } } else { el = document.querySelectorAll(self.opt.el) if (el.length === 0) { return console.log('传入的节点没有查找到') } } self.offsetWidth = el.offsetWidth self.offsetHeight = el.offsetHeight el.style.position = 'relative' // 新建一个canvas const canvas = self.createCanvas(el) var ctx = canvas.getContext('2d') // 将画布赋值给全局 self.ctx = ctx canvas.onmousedown = function(ev) { // 判断是否为左键点击事件 self.clearShot() if (ev.button !== 0) { return } var x = ev.offsetX var y = ev.offsetY drag(x, y, self.opt.color) } function drag(x, y, color) { canvas.onmousemove = function(ev) { var tx = ev.offsetX var ty = ev.offsetY // 清除原画布内容 ctx.clearRect(0, 0, canvas.width, canvas.height) // 画出当前坐标对应区域 ctx.beginPath() ctx.lineWidth = '2' ctx.moveTo(x, y) ctx.lineTo(tx, y) ctx.lineTo(tx, ty) ctx.lineTo(x, ty) ctx.closePath() ctx.strokeStyle = color ctx.stroke() self.position = { x: x, y: y, tx: tx, ty: ty } } canvas.onmouseup = function() { canvas.onmousemove = null canvas.onmouseup = null } } } clearShot() { if (this.ctx) { this.position = {} this.ctx.clearRect(0, 0, this.offsetWidth, this.offsetHeight) } } getResultImage(video) { if (this.position && this.position.tx) { if (video) { video.setAttribute('crossOrigin', 'Anonymous') const videoWidth = video.videoWidth || 1920 const videoHeight = video.videoHeight || 1080 const canvas = document.createElement('canvas') canvas.width = this.offsetWidth canvas.height = this.offsetHeight var ctx = canvas.getContext('2d') console.log(videoWidth, videoHeight, this.offsetWidth, this.offsetHeight) ctx.drawImage(video, 0, 0, videoWidth, videoHeight, 0, 0, this.offsetWidth, this.offsetHeight) ctx.beginPath() ctx.lineWidth = '2' ctx.moveTo(this.position.x, this.position.y) ctx.lineTo(this.position.tx, this.position.y) ctx.lineTo(this.position.tx, this.position.ty) ctx.lineTo(this.position.x, this.position.ty) ctx.closePath() ctx.strokeStyle = this.opt.color ctx.stroke() var base64 = canvas.toDataURL('image/png') // 获取坐标点位 const dots = this.getDots(this.position) return { base64: base64, dots: dots } } } else { alert('请先截取报警区域') } } getDots(pos) { try { const wRate = this.offsetWidth / 1920 const hRate = this.offsetHeight / 1080 let topleft = "" let bottomleft = "" let topright = "" let bottomright = "" let leftX = pos.x let rightX = pos.tx if (pos.x > pos.tx) { leftX = pos.tx rightX = pos.x } else { leftX = pos.x rightX = pos.tx } let topY = pos.y let bottomY = pos.ty if (pos.y > pos.ty) { topY = pos.ty bottomY = pos.y } else { topY = pos.y bottomY = pos.ty } topleft = `${Math.ceil(leftX / wRate)},${Math.ceil(topY / hRate)}` bottomleft = `${Math.ceil(leftX / wRate)},${Math.ceil(bottomY / hRate)}` topright = `${Math.ceil(rightX / wRate)},${Math.ceil(topY / hRate)}` bottomright = `${Math.ceil(rightX / wRate)},${Math.ceil(bottomY / hRate)}` return [topleft, bottomleft, bottomright, topright] } catch (error) { return [0, 0, 0, 0] } } init() { var self = this self.createEvent() return self } }