vue3之截图 screenShort

324 阅读1分钟

1、components/screenShort创建.vue文件

  <div>
    <screen-short
      v-if="screenshotStatus"
      @destroy-component="destroyComponent"
      @get-image-data="getImageData"
    ></screen-short>
  </div>
</template>

<script lang="ts">
  import { toRefs, reactive, defineComponent, onUnmounted } from 'vue';
  export default defineComponent({
    name: 'screen-short-component',
    setup(props, { emit }) {
      const state = reactive({
        screenshotStatus: false
      });
      // 打开截屏
      const openScreenshot = () => {
        state.screenshotStatus = true;
        onMonitorKeyup();
      };
      // 销毁组件函数
      const destroyComponent = (status: boolean) => {
        emit('destroyComponent', false);
        state.screenshotStatus = status;
      };
      // 获取裁剪区域图片信息
      const getImageData = (base64: any) => {
        emit('getBase64', base64);
      };
      // 监听键盘 `esc` 按下
      const onMonitorKeyup = () => {
        console.log('ss');

        if (!state.screenshotStatus) return false;
        // window.addEventListener('keydown', (e: any) => {
        //   if (e.keyCode === 27) destroyComponent();
        // });
      };
      // 页面销毁时
      onUnmounted(() => {
        window.removeEventListener('keydown', () => {});
      });
      return {
        openScreenshot,
        destroyComponent,
        getImageData,
        onMonitorKeyup,
        ...toRefs(state)
      };
    }
  });
</script>

2、mian.ts引入

app.use(screenShort, { enableWebRtc: false });

3、使用

 <div>
 <screen-short ref="screenShortRef" @getBase64="onGetBase64" @destroyComponent="destroyComponent" />
 ........
//点击截图
<div v-if="item.images.length < 3" class="addImg" @click="onScreenShortClick(index)">
  <img src="@/assets/images/addScreen.png" alt="" />
   <span>{{ $t('preview.addImg') }}</span>
 </div>
 </div>
</template>
//方法
      // 截屏点击
      const onScreenShortClick = (index: number) => {
        emit('isScreenshot', true);
        //用来存当前的key
        nowCount.value = index;
        screenShortRef.value.openScreenshot();
      };
      
            // 获取截屏数据(返回的是图片的base64)
      const onGetBase64 = (base64: any) => {
        // console.log('props.meshData', props.meshData);
        //upsible, lowsible, lowsibleSitu, upsibleSitu, upsibleMarker, lowsibleMarker, lbite1, lbite2
        // console.log(base64);
        // console.log('............', props.showModel);
        let newModel = [] as any;
        let modelName = [
          'upsible',
          'lowsible',
          'lowsibleSitu',
          'upsibleSitu',
          'upsibleMarker',
          'lowsibleMarker',
          'lbite1',
          'lbite2'
        ];
        props.showModel.forEach((el, index) => {
          if (el) newModel.push(modelName[index]);
        });

        (state.caseContent as any)[nowCount.value as any].images.push({
          name: base64[0],
          meshMatrixWorld: props.meshMatrix,
          cameraMatrixWorldInverse: props.meshCamera, //相机逆矩阵
          cameraProjectionMatrix: props.meshWorld, //投影矩阵
          sceenWidth: base64[1], //屏幕宽
          sceenHeight: base64[2], //屏幕高
          shortX: base64[3], //截图左上角坐标x
          shortY: base64[4], //截图左上角坐标y
          shortWidth: base64[5], //截图宽度
          shortHeight: base64[6], //截图高度
          showModel: newModel
        });
      };
      // 截图工具摧毁
      const destroyComponent = () => {
        emit('isScreenshot', false);
      };

补充:监听iframe ,在iframe嵌套的网页内截图并返回数据

   <div class="case-comment-preview">
        <iframe
          v-if="iframeSrc"
          :id="`previewIframe`"
          frameborder="0"
          style="width: 100%; height: 100%"
          :src="iframeSrc"
        ></iframe>
    </div>
</template>
//方法
      //截图 发起消息
      function cutPreview() {
        let iframe = document.getElementById(`previewIframe`) as any;
        let message = {
          type: 'openCut',
          content: ''
        };
        // 使用 postMessage 方法推送消息到 iframe
        iframe.contentWindow.postMessage(message, '*');
      }
    //iframe加载完毕,可开始截图
      window.addEventListener('message', function (event) {
        // console.log('event------', event);
        //预览加载完毕 显示截图按钮
        if (event.data.type === 'showCut') {
          console.log('可以开始截图');
          cutImg.value = false;
        } else if (event.data.type === 'cutImg') {
          // console.log('iframe发送回来的截图', event.data.content);
          // let formData = convertBase64ToFormData(event.data.content);
          // postImg(formData);
          // 调用 postImg 函数传递 FormData
          ElMessageBox.confirm(t('caseComment.sureCutImg'), t('caseControl.title'), {
            confirmButtonText: t('button.submits'),
            cancelButtonText: t('caseControl.close'),
            type: 'warning'
          }).then(() => {
            // ElMessage({
            //   type: 'success',
            //   message: '发送成功'
            // });
            let formData = convertBase64ToFormData(event.data.content);
            postImg(formData);
          });
        }
      });
   // 创建一个函数,将 base64 图片数据转换为 FormData 对象
      function convertBase64ToFormData(base64Image: string) {
        let formData = new FormData();
        // 将 base64 图片数据转换为 Blob 对象
        let byteCharacters = atob(base64Image.split(',')[1]);
        let byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        let byteArray = new Uint8Array(byteNumbers);
        let blob = new Blob([byteArray], { type: 'image/jpeg' });
        // 将 Blob 对象转换为 File 对象
        let file = convertBlobToFile(blob, 'screenshot.jpg'); // 转换为文件对象,文件名为 'image.jpg'

        formData.append(`${inintParams.value.caseId}`, file);
        let receiverId = inintParams.value.receviceId;
        formData.append('receiverId', receiverId);
        return formData;
      }