记录使用hmtl2canvas踩得坑

27 阅读3分钟

记录一下最近写功能踩到的坑

需求:实现一个签字板的功能,应对一些协议需要签名的地方调起签字板进行签名

实现:使用signature_pad就可以实现签字板功能,具体可以自行查看文档。

这个倒很简单,重点是需要把协议内容和签名嵌在一块然后生成一张图,方便用户查看给哪些协议签了名。

看起来也挺简单,话不多说,开始干。这里查到有现成的轮子html2canvas,使用起来也挺简单

[html2canvas文档链接]  allenchinese.github.io/html2canvas… 

// 贴一点简单的代码
html2canvas(需要转换为图片的dom,配置项) // 配置项可以自己查看文档
const canvas = await html2canvas(
      document.querySelector(`${this.signDOM_id} ${this.signDealDOM_id}`),
      {
        useCORS: true,
      }
    );

接下来就踩坑了:

1、使用cdn图片时发现并没有把cdn图也一起生成图片,看之前大佬总结的是开启配置项

useCORS: true

意思就是允许从服务器加载图片

2、当我想把协议和图片嵌在一起生成图片却发现图片很模糊,还有如果协议过长会导致图片内容显示不全

图片模糊解决办法:

function DPR() {
      // 设置DPR
      if (window.devicePixelRatio && window.devicePixelRatio > 1) {
        return window.devicePixelRatio;
      }
      return 1;
    }
const options = {
    scale: DRP() * 4    
}
​

图片显示不全解决:

在网上查找的解决办法都是说因为滚动条没有到最顶部,所以导致图片没生成完整

实际上我的需求只是根据dom生成一张图

1、首先,我获取到协议的内容,再获取签字生成的img,重新拼成一个新的dom,但是html2canvas生成的图片必须是一个没有设置display:none的dom元素,也就是一个真实存在的dom。

刚开始我的解决思路是,把拼成的dom先display:block,然后生成图片后再 none。后来发现dom会闪现,体验很差。

emmm,既然它必须存在,那我能不能把它移到我看不见的地方,ok,代码如下

position: fixed;
top: 100%

使用固定定位,移到屏幕外,这样就看不见了!

2、解决了根据dom生成图片的问题,现在再解决因为协议过长会导致图片显示不全的问题。

ps:因为我做了个一个图片预览的功能,方便在本地查看,上传的服务器的图片我就没再查看了,小伙伴可以自己看一下

先贴之前会导致图片显示不全的代码:

.showSign {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  z-index: 9999;
  background-color: rgba(255, 255, 255, 0.8);
  /* 这里就是因为flex布局导致图片拉伸,会很丑。本意是想居中图片 */
  display: flex;
  justify-content: center;
  align-items: center;
  display: none;
}
.showSign b {
  position: absolute;
  right: 20px;
  top: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  text-align: center;
  line-height: 20px;
  color: #aaa;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  cursor: pointer;
}
.showSign img {
  position: absolute;
  top: 100px;
  width: 80%;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}

修改后正常显示的代码

.showSign {
  position: fixed;
  top: 0;
  left: 0;
  /* 把距离底部也设为0 */
  bottom: 0;
  width: 100vw;
  /* 开启y轴滚动条 */
  overflow-y: scroll;
  z-index: 9999;
  background-color: rgba(255, 255, 255, 0.8);
  display: none;
}
.showSign b {
  position: absolute;
  right: 20px;
  top: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  text-align: center;
  line-height: 20px;
  color: #aaa;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  cursor: pointer;
}
.showSign img {
  position: absolute;
  top: 100px;
  left: 50%;
  /* 使用translate x轴 y轴都设-50%就可以了 */
  transform: translate(-50%);
  width: 80%;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}

接下来查看生成的协议带签名的图片就可以查看然后往下滚动查看了

文笔很差,只是记录自己踩得坑