svg+canvas 标签画不规则区域选择高亮效果

一、背景:

在一个业务需求中,需要用鼠标点击画不规则区域,并结合AI智能+相应算法,用来进行预警以及报警。

二、实现思路:

利用svg和canvas进行实现

三、实现代码:

话不多说,直接上干货

<template>
  <div>
    <div class="my-btns">
      <div class="my-button" @click="clearDraw"> 清除画布 </div>
      <div class="my-button"  v-for="(item) in tmepPointCounts"
           :class="pointCounts == item?'active':''" @click="pointCounts = item"> {{ item }} </div>
      <div class="my-button" @click="toArray"> 转成数组 </div>
    </div>

    <div style="position:relative;" @click="divClick($event)" @mousemove="divMove($event)">
      <video id="myVideo" width="750" height="420" muted
        controls="true" autoplay="true" loop="true" mediatype="video" crossorigin="anonymous" >
        <source :src="videoSrc" type="video/mp4">
      </video>
      <div v-if="isShowCanvas" class="my-line">
        <canvas id="myCanvas" width="750" height="420"></canvas>
      </div>
      <div class="my-line-svg">
        <svg width="750" height="420" version="1.1" xmlns="http://www.w3.org/2000/svg">
          <polygon :points="clickCount == this.pointCounts ? myPoints:myMovePoints"
            style="fill:#ff0000;stroke:#fafa03;stroke-width:2;opacity:0.2"/>
        </svg>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tmepPointCounts:[3,5,7,9], // 设置画几边形
      isShowCanvas:true, // 是否显示canvas画布
      firstClickY:0, // 画第一个点的坐标x
      firstClickX:0, // 画第一个点的坐标y
      clickCount:0, // 已画了几个点
      myMovePoints:'', // 画时的形状
      myPoints:'', // 画完的时形状
      pointCounts:5, // 画几边形
      videoSrc:'https://vd4.bdstatic.com/mda-mip2p9qcv2q4hwcb/cae_h264_clips/1632450404071812791/mda-mip2p9qcv2q4hwcb.mp4?auth_key=1632464540-0-0-4f7af03614e4253d72f9e3ea8fdb652e&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=',
    };
  },
  mounted() {
    this.$nextTick(function(){
      this.doDraw()
      this.pauseVideo()
    })
  },
  methods: {
    toArray(){
      let myPointsArr = this.myPoints.split(' ');
      console.log("myPointsArr--",myPointsArr)
    },
    divMove(e){
      console.log(this.clickCount,"<--this.clickCount-----this.pointCounts-->",this.pointCounts)
      if(this.clickCount >= this.pointCounts) return
      console.log(this.clickCount,this.myPoints,"--移动--",e)
      let x = e.offsetX
      let y = e.offsetY
      this.myMovePoints = this.myPoints + x + ',' + y + ' '
    },
    divClick(e){
      console.log(this.clickCount,"--点击--",e)
      //e.layerX e.layerY  e.offsetX e.offsetY
      if(this.clickCount < this.pointCounts){
        this.clickCount++
        let x = e.offsetX
        let y = e.offsetY

        // canvas 画边框线
        if(this.clickCount == 1){
          this.myPoints = ''
          this.firstClickX = x
          this.firstClickY = y
          this.doDrawMoveTo(x,y)
        } else if(this.clickCount == this.pointCounts){
          this.doDrawLineTo(x,y)
          this.doDrawLineTo(this.firstClickX,this.firstClickY)
        } else{
          this.doDrawLineTo(x,y)
        }

        // svg (也可以画边框线的)
        this.myPoints += x + ',' + y
        if(this.clickCount < this.pointCounts) this.myPoints += ' '
        console.log("this.myPoints--",this.myPoints)
      }
    },
    doDrawLineTo(x,y){
      // 获取canvas
      var canvas = document.getElementById("myCanvas")
      var a = setInterval(() =>{
        // 重复获取
        canvas = document.getElementById("myCanvas")
        if(!canvas){
          return false
        } else {
          clearInterval(a)
          // 可以理解为一个画笔,可画路径、矩形、文字、图像
          var ctx = canvas.getContext('2d')
          ctx.strokeStyle = "red"
          ctx.lineWidth = 1;

          ctx.lineTo(x,y);
          ctx.stroke();
        }
      },1)
    },
    doDrawMoveTo(x,y){
      // 获取canvas
      var canvas = document.getElementById("myCanvas")
      var a = setInterval(() =>{
        // 重复获取
        canvas = document.getElementById("myCanvas")
        if(!canvas){
          return false
        } else {
          clearInterval(a)
          // 可以理解为一个画笔,可画路径、矩形、文字、图像
          var ctx = canvas.getContext('2d')
          ctx.strokeStyle = "red"
          ctx.lineWidth = 1;

          //e.layerX e.layerY  e.offsetX e.offsetY
          ctx.moveTo(x,y);
          ctx.stroke();
        }
      },1)
    },
    clearDraw(){
      // 清除svg
      this.myPoints = ''
      this.myMovePoints = ''
      this.clickCount = 0

      // 清除canvas
      // var canvas = document.getElementById("myCanvas")
      // var ctx = canvas.getContext('2d')
      // ctx.clearRect(0,0,1000,600)
      this.isShowCanvas = false
      this.$nextTick(function(){
        this.isShowCanvas = true
      })
    },
    doDraw(){
      // 获取canvas
      var canvas = document.getElementById("myCanvas")
      // 由于弹窗,确保已获取到
      var a = setInterval(() =>{
        // 重复获取
        canvas = document.getElementById("myCanvas")
        if(!canvas){
          return false
        } else {
          clearInterval(a)
          // 可以理解为一个画笔,可画路径、矩形、文字、图像
          var ctx = canvas.getContext('2d')
          ctx.strokeStyle = "red"
          ctx.lineWidth = 1;
          ctx.strokeRect(20, 20, 120, 120)
          // ctx.strokeRect(730, 0, 200, 100)

          //e.layerX e.layerY  e.offsetX e.offsetY
          // 六角形
          ctx.moveTo(80,20);
          ctx.lineTo(30,50);
          ctx.lineTo(30,106);
          ctx.lineTo(80,140);
          ctx.lineTo(130,106);
          ctx.lineTo(130,50);
          ctx.lineTo(80,20);

          // 伞型
          ctx.moveTo(482,70);
          ctx.lineTo(472,92);
          ctx.lineTo(370,70);
          ctx.lineTo(260,120);
          ctx.lineTo(640,260);
          ctx.lineTo(580,140);
          ctx.lineTo(486,96);
          ctx.lineTo(492,78);
          ctx.lineTo(482,70);

          // 六角矩形
          ctx.moveTo(730,0);
          ctx.lineTo(730,60);
          ctx.lineTo(810,60);
          ctx.lineTo(810,90);
          ctx.lineTo(930,90);
          ctx.lineTo(930,0);
          ctx.lineTo(730,0);
          ctx.stroke();
        }
      },1)
    },
    pauseVideo(){
      let video = document.getElementById("myVideo")
      console.log("进来播放")
      video.play();
      if(video.play()){
        setTimeout(()=>{
          video.currentTime=4;
          video.pause();
        },8000)
      }
    }
  },
};
</script>

<style lang="scss" scoped>
.my-btns{
  display: flex;
}
.my-button{
  margin:10px 10px;
  width: 100px;
  text-align: center;
  padding: 10px 0;
  background-color: #00a2d4;
  color: #fcfcfc;
  border-radius: 20px;
}
.active{
  background-color: #0a7ca0;
}
.my-line{
  position: absolute;
  top: 0;
  left: 0;
}
.my-line-svg{
  position: absolute;
  top: 0;
  left: 0;
}
</style>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值