1.页面效果

前端实现视频框选,背景带遮罩层,中间镂空,采用自定义组件方式。页面效果如下:

无遮罩层的时候:

有遮罩层的时候 

2.解决思路

我的解决思路简单但不是最佳

我的解决思路是先选择外框作为父元素,里面的1-4作为阴影子元素,使用absolute定位阴影 

3.主要代码

1.组件代码

<template>
  <div v-show="show" ref="parent" class="shadow-box">
    <div v-for="n in 4" :ref="`shadow${n}`" :key="n" :class="`shadow${n}`" />
  </div>
</template>

<script>
export default {
  name: 'Shadow',
  props: {
    parentWidth: { // 父组件宽度
      type: Number,
      default: 768
    },
    parentHeight: { // 父组件高度
      type: Number,
      default: 432
    },
    childrenWidth: { // 子组件宽度
      type: Number,
      default: 0
    },
    childrenHeight: { // 子组件高度
      type: Number,
      default: 0
    },
    childrenX: { // 子组件X坐标
      type: Number,
      default: 0
    },
    childrenY: { // 子组件Y坐标
      type: Number,
      default: 0
    },
    borderWidth: { // 子组件边界宽度
      type: Number,
      default: 2
    },
    show: { // 是否显示
      type: Boolean,
      default: false
    }
  },
  watch: {
    'parentWidth': {
      handler(newName, oldName) {
        this.$nextTick(() => {
          this.$refs.parent.style.setProperty('--parentWidth', newName + 'px')
        })
      },
      immediate: true
    },
    'parentHeight': {
      handler(newName, oldName) {
        this.$nextTick(() => {
          this.$refs.parent.style.setProperty('--parentHeight', newName + 'px')
        })
      },
      immediate: true
    },
    'childrenWidth': {
      handler(newName, oldName) {
        this.setParams()
      },
      immediate: true
    },
    'childrenHeight': {
      handler(newName, oldName) {
        this.setParams()
      },
      immediate: true
    },
    'childrenX': {
      handler(newName, oldName) {
        this.setParams()
      },
      immediate: true
    },
    'childrenY': {
      handler(newName, oldName) {
        this.setParams()
      },
      immediate: true
    }
  },
  methods: {
    // 设置参数
    setParams() {
      this.$nextTick(() => {
        this.$refs[`shadow${1}`][0].style.setProperty('--shadow1Width', this.childrenX + 'px')
        this.$refs[`shadow${2}`][0].style.setProperty('--shadow2X', this.childrenX + 'px')
        this.$refs[`shadow${2}`][0].style.setProperty('--shadow2Width', (this.childrenWidth + this.borderWidth * 2) + 'px')
        this.$refs[`shadow${2}`][0].style.setProperty('--shadow2Height', this.childrenY + 'px')
        this.$refs[`shadow${3}`][0].style.setProperty('--shadow3X', (this.childrenX + this.childrenWidth + this.borderWidth * 2) + 'px')
        this.$refs[`shadow${3}`][0].style.setProperty('--shadow3Width', (this.parentWidth - (this.childrenX + this.childrenWidth + this.borderWidth * 2)) + 'px')
        this.$refs[`shadow${4}`][0].style.setProperty('--shadow4X', this.childrenX + 'px')
        this.$refs[`shadow${4}`][0].style.setProperty('--shadow4Y', (this.childrenY + this.childrenHeight + this.borderWidth * 2) + 'px')
        this.$refs[`shadow${4}`][0].style.setProperty('--shadow4Width', (this.childrenWidth + this.borderWidth * 2) + 'px')
        this.$refs[`shadow${4}`][0].style.setProperty('--shadow4Height', (this.parentHeight - (this.childrenY + this.childrenHeight + this.borderWidth * 2)) + 'px')
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.shadow-box {
  position: absolute;
  --parentWidth: 768px;
  --parentHeight: 432px;
  --shadow1Width: 0px;
  --shadow2X: 0px;
  --shadow2Width: 0px;
  --shadow2Height: 0px;
  --shadow3X: 0px;
  --shadow3Width: 768px;
  --shadow4X: 0px;
  --shadow4Y: 0px;
  --shadow4Width: 0px;
  --shadow4Height: 432px;
  --shadowColor: rgba(221, 221, 221, 0.6);
  width: var(--parentWidth);
  height: var(--parentHeight);
  z-index: 100;

  .shadow1 {
    position: absolute;
    left: 0;
    top: 0;
    width: var(--shadow1Width);
    height: var(--parentHeight);
    background-color: var(--shadowColor);
  }
  .shadow2 {
    position: absolute;
    left: var(--shadow2X);
    top: 0;
    width: var(--shadow2Width);
    height: var(--shadow2Height);
    background-color: var(--shadowColor);
  }
  .shadow3 {
    position: absolute;
    left: var(--shadow3X);
    top: 0;
    width: var(--shadow3Width);
    height: var(--parentHeight);
    background-color: var(--shadowColor);
  }
  .shadow4 {
    position: absolute;
    left: var(--shadow4X);
    top: var(--shadow4Y);
    width: var(--shadow4Width);
    height: var(--shadow4Height);
    background-color: var(--shadowColor);
  }
}
</style>

2.引用组件 

<Shadow
   v-for="(item, index) in areaList"
   v-show="currentPaintIndex === index && isStartPainting"
   :key="`shadow${index}`"
   :parent-width="768"
   :parent-height="432"
   :border-width="2"
   :children-x="item.X"
   :children-y="item.Y"
   :children-width="item.W"
   :children-height="item.H"/>

 有什么疑问评论区或者私信讨论交流,我也是前端新手。

Logo

前往低代码交流专区

更多推荐