前言

上周六有个群友@我说Gitee的反馈模块新增了截图性能,我就去体验了下,发现他们用的就是我的插件,本文就跟大家分享下这个插件,欢送各位感兴趣的开发者浏览本文。

插件地址与实现原理

本插件采纳原生js实现,能够集成在任意一个web我的项目中,插件npm地址与GitHub地址请移步:

  • js-screen-shot(npm)
  • js-screen-shot(GitHub)

插件的实现原理请移步:

  • 实现Web端自定义截屏
  • 实现Web端自定义截屏(JS版)
在线体验本插件,可移步我的开源我的项目chat-system进行体验,插件的运行成果视频请移步实现web端自定义截屏性能-成果视频。

Gitee产品经理的青眼

月初的时候,Gitee的产品经理在掘金看到我的截图插件js-screen-shot感觉还不错,他们最近在做这方面的性能,就打算将我的插件间接集成进去,跟我沟通了下版权相干的事件。

沟通实现后,他问我要不要把插件在Gitee也放一份,能够帮我举荐下,我毫不犹豫的抱住了大腿,就把插件搬过来了,失去一波首页举荐

Gitee的反馈模块须要登录后,点页面右侧的发送反馈图标。

影响体验的一些小问题

上周二,从GitHub来了个网友,加了我微信,给我的插件提了两个issues,因为周内没工夫解决这些问题,就打算周末对立解决下插件的issues。

整顿无效的issues

工夫回到上周六早上,我关上GitHub瞅了一眼issues,许久不看竟然曾经有19条了。

通过一番整顿,去掉一些无用的和曾经批改好了的,最终确定了4条:

  • 调用者能够在框选区域外绘制问题
  • 截图区域工具栏首次点击时删除裁剪框的8个可操作点
  • 修复框选实现后,鼠标点击其余地位截图工具栏跟着挪动问题
  • 增加可选参数反对单击截全屏性能

解决issues

问题整顿实现,接下来就是解决问题环节了。

选区外绘制问题

失常状况下,截图区域确立后,用户都会在裁剪框区域内进行绘制,所以我就没思考这个边界状况,插件用的人多了后,天然就有人发现了这个问题,咱们拿gitee的反馈模块举例(gitee目前用的还是我的旧版插件,必定存在这个问题),如下所示,咱们绘制的4个红色方框都超出裁剪框了:

实现思路

这个问题解决起来比较简单,裁剪框曾经绘制好了,晓得它的坐标信息,咱们在进行绘制时,只须要判断以后鼠标地位是否超出裁剪框的坐标点区域即可。局部实现代码如下所示:

// 获取裁剪框地位信息const cutBoxPosition = this.data.getCutOutBoxPosition();// 绘制中工具的起始x、y坐标不能小于裁剪框的起始坐标// 绘制中工具的起始x、y坐标不能大于裁剪框的完结坐标// 以后鼠标的x坐标不能小于裁剪框起始x坐标,不能大于裁剪框的完结坐标// 以后鼠标的y坐标不能小于裁剪框起始y坐标,不能大于裁剪框的完结坐标if (      !getDrawBoundaryStatus(startX, startY, cutBoxPosition) ||      !getDrawBoundaryStatus(currentX, currentY, cutBoxPosition)   )      return;

getDrawBoundaryStatus函数实现如下所示:

/** * 获取工具栏工具边界绘制状态 * @param startX x轴绘制终点 * @param startY y轴绘制终点 * @param cutBoxPosition 裁剪框地位信息 */export function getDrawBoundaryStatus(  startX: number,  startY: number,  cutBoxPosition: positionInfoType): boolean {  if (    startX < cutBoxPosition.startX ||    startY < cutBoxPosition.startY ||    startX > cutBoxPosition.startX + cutBoxPosition.width ||    startY > cutBoxPosition.startY + cutBoxPosition.height  ) {    // 无奈绘制    return false;  }  // 能够绘制  return true;}
具体代码请移步提交记录: fix: 修复插件调用者能够在框选区域外绘制问题
实现成果

实现后的成果如下所示:

工具栏追随鼠标挪动问题

这个问题能够形容为:裁剪框确定后,工具栏尚未点击,此时鼠标点其余地位,截图工具栏就跟着鼠标从新计算了地位,咱们持续用Gitee来举例,如下所示:

实现思路

当鼠标左键抬起时,如果工具栏尚未被点击,则会依据以后鼠标的地位联合裁剪框的大小确立截图工具栏的地位。用户只是单纯的点击了裁剪框区域的任意地位,工具栏就跟着挪动了。

解决这个问题也很简略,咱们只须要在鼠标挪动时增加一个标识,鼠标抬起时判断这个标识是否为true即可。局部代码如下所示:

  // 鼠标拖动状态  private dragFlag = false;  // 鼠标挪动事件  private mouseMoveEvent = (event: MouseEvent) => {     // 工具栏未抉择且鼠标处于按下状态时    if (!this.data.getToolClickStatus() && this.data.getDragging()) {      // 批改拖动状态为true;      this.dragFlag = true;    }  }    // 鼠标抬起事件  private mouseUpEvent = () => {    // 鼠标尚未拖动且工具栏未抉择则不批改工具栏地位    if (!this.dragFlag && !this.data.getToolClickStatus()) {      // 还原裁剪框的坐标      this.drawGraphPosition.startX = this.drawGraphPrevX;      this.drawGraphPosition.startY = this.drawGraphPrevY;      // 显示截图工具栏      this.data.setToolStatus(true);      return;    }  }
具体代码请移步提交记录:fix: 修复框选实现后,鼠标点击其余地位截图工具栏跟着挪动问题
实现后果

修复后的成果如下所示:

删除8个可操作点

去年截图插件刚写好时,我就发现这个问题了,当截图工具栏点击后裁剪框就不容许更改了,如果8个可操作点仍然存在的话,看起来很奇怪,过后想到的思路是间接删除边框的8点,然而这8个点都是绘制下来的,折腾了挺久没找到计划就搁置了,这个问题如下图所示:

实现思路

一年后的明天,我晓得删除那8个点的思路必定行不通,我就一遍又一遍的体验QQ的截图,察看他是怎么做的,忽然,我灵感惊现,我既然有裁剪框的坐标和大小信息,我从新绘制一下这个裁剪框不就好了,裁剪框周围的8个可操作点删除后,我就能够删掉生成图片时优化那8个点的计算逻辑,导致范畴不准确问题,从而实现完满截图。局部实现代码如下所示:

  // 工具栏尚未点击,以后属于首次点击,从新绘制一个无像素点的裁剪框  if (!data.getToolClickStatus()) {    // 获取裁剪框地位信息    const cutBoxPosition = data.getCutOutBoxPosition();    // 开始绘制无像素点裁剪框    drawCutOutBox(      cutBoxPosition.startX,      cutBoxPosition.startY,      cutBoxPosition.width,      cutBoxPosition.height,      screenShortCanvas,      data.getBorderSize(),      screenShortController as HTMLCanvasElement,      ScreenShortImageController,      false    );  }
具体代码请移步提交记录:fix: 截图区域工具栏首次点击时删除裁剪框的8个可操作点
实现成果

实现单击截全屏性能

给我提issues的那个网友心愿截图插件加载结束后,用户不拖拽生成选框,间接鼠标左键单击就能截取整个屏幕,我感觉这个需要须要的人不多,就将其做成了可选参数。

实现思路

这个也很简略,鼠标抬起时,如果开启了单击截全屏,则从坐标(0,0)地位绘制一个与画布等同大小的裁剪框即可,局部代码如下所示:

  // 鼠标抬起事件  private mouseUpEvent = () => {    if (      cutBoxPosition.width === 0 &&      cutBoxPosition.height === 0 &&      cutBoxPosition.startX === 0 &&      cutBoxPosition.startY === 0 &&      !this.dragFlag &&      this.clickCutFullScreen    ) {      // 设置裁剪框地位为全屏      this.tempGraphPosition = drawCutOutBox(        0,        0,        this.screenShortImageController.width,        this.screenShortImageController.height,        this.screenShortCanvas,        this.data.getBorderSize(),        this.screenShortController,        this.screenShortImageController      ) as drawCutOutBoxReturnType;    }  }
具体代码请移步提交记录:feat: 增加可选参数反对单击截全屏性能

写在最初

至此,文章就分享结束了。

我是神奇的程序员,一位前端开发工程师。

如果你对我感兴趣,请移步我的集体网站,进一步理解。

  • 文中如有谬误,欢送在评论区斧正,如果这篇文章帮到了你,欢送点赞和关注
  • 本文首发于神奇的程序员公众号,未经许可禁止转载