好好学习,认真工作

网页截图标注方式

背景

随着网页功能变得越来越丰富,运营方也经常需要及时的了解用户的需求,收集用户对于当前网页的意见。本专利就是实现一种对网页截图进行标注的功能,在使用html2canvas导出图片后,封装canvas的api对网页截图画箭头,矩形和输入文字标注,最终将标注结果的图片导出。有易用、兼容性强、高性能的特性。

实现思路

  1. 截图模块生成对于的base64编码,将根据用户的设备像素比(devicePixelRatio)调整图片显示大小,确保了兼容性
  2. 标注模块获取了图片bae64编码之后,在内部的底层Canvas渲染此图片,并将初始图片存储标注模块内部维护historeList数组
  3. 用户通过交互栏,选择操作类型(矩形、箭头、文字)之后,将在顶层canvas上进行拖拽和文字输入的操作
  4. 每次操作结束之后,将会记录顶层的操作记录,并在底层图片重复此操作,同时清空顶层canvas,便于下次标注
  5. 将底层更新的图片存储到historeList数组
  6. 用户每次点击撤销的时候,将historeList的前一个图片去渲染底层图片
  7. 确定之后将底层图片输出

附图

图一,总体流程图

图二、内部实现过程

具体交互

 

 实现代码

截图模块

页面html,具体作用:

  • checkbox选中之后开始截图
  • fakeImg则用来暂存当前的图片
  • clipCanvas则是第三方库html2canvas截图的canvas依赖
  • originImg则是显示给用户看的截图
  • 点击shotScreen-ctrl对截图开始标注
<div class="shotScreen">
      <div class="shotScreen-header">
        <el-checkbox v-model="withShot" @change="shotScreenImg">提供截图(仅截取当前可视区域)</el-checkbox>
      </div>
      <div class="shotScreen-body" v-loading="shotLoading">
        <img id="fakeImg" v-if="showOriginImg"  :src="shotSrc" style="display: none;">
        <img v-if="shotSrc" id="cacheImg" @click="editShot" :src="shotSrc" alt="" class="shotScreen-img">
        <div class="shotScreen-tip" v-else>暂无图片</div>
        <span v-if="shotSrc" @click="editShot" class="shotScreen-ctrl"></span>
        <canvas id="clipCanvas" :width="canvasWidth" :height="canvasHeight" style="display:none"></canvas>
        <img :src="originSrc" alt="" v-if="showOriginImg" id="originImg" style="display: none;">
      </div>
    </div>
<draftImageEditor ref="imageEditor" @outputImgSrc="outputImgSrc" />

 

在选择提供截图之后,依赖第三方库html2canvas输出图片并且获取图片的宽度和高度

 

 1 shotScreenImg(val) {
 2       if (val) {
 3         if (this.cacheShotSrc) {
 4           this.shotSrc = this.cacheShotSrc;
 5           return
 6         }
 7         const clipCanvas = document.getElementById('clipCanvas');
 8         this.shotLoading = true;
 9         this.showOriginImg = true;
10         this.$nextTick(()=>{          
11           const originImg = document.getElementById('originImg');
12           originImg.onload = () => {
13             const ctx = clipCanvas.getContext('2d');
14             ctx.drawImage(originImg, 0, document.documentElement.scrollTop * this.scale, this.canvasWidth, this.canvasHeight, 0, 0, this.canvasWidth, this.canvasHeight)
15             const canvasUrl = clipCanvas.toDataURL('image/png');
16             this.shotSrc = canvasUrl
17             this.cacheShotSrc = canvasUrl
18             this.shotLoading = false
19           }
20         })
21         html2canvas(document.getElementById('app'), {
22           useCORS: true,
23           allowTaint: false,
24         }).then(canvas => {
25           this.originSrc = canvas.toDataURL('image/png');
26           const fakeImg = document.getElementById('fakeImg')
27           fakeImg.onload = () => {
28             this.shotImgWidth = fakeImg.width * 2;
29             this.shotImgHeight = fakeImg.height * 2;
30           }
31         }).catch(e => {
32           console.error('error', e)
33         })
34       } else {
35         this.shotSrc = '';
36       }
37     },

点击标注图片时候

editShot() {
      const cacheImg = document.getElementById('cacheImg')
      this.$refs.imageEditor.open(cacheImg, this.shotImgWidth, this.shotImgHeight)
    }

标准模块

 

标注模块主要依赖api

 

posted on 2025-02-12 09:52  peace_1  阅读(32)  评论(0)    收藏  举报