vue使用html2canvas + opacity透明覆盖,实现长按图片保存本地

485 阅读2分钟

先引出问题: 在分享的时候,要实现长按保存图片到本地,图片还得是前端自己生成,且包括图片二维码和封面图片文字等。像下面这样的截图保存到本地。

image.png

1、首先想到的方法就是在弹框出现的时候就使用html2canvas生成弹框的截图,然后把截图用css方法z-index放到弹框的上方,并且设置截图opacity透明度为0,这样长按弹框的时候,实际上是长按了截图这样就能下载本地了。实现如下图:

image.png

2、下面是实现的方法:

(1)在弹框展示的时候第一时间去调用html2canvas截取图片,如下示例代码:

// 获取海报
getDomToImage() {
 setTimeout(()=> {
  const node = document.getElementById('shareModuleWrap') // 通过id获取dom
  html2canvas(node, {useCORS: true, backgroundColor: null}).then((canvas) => {
          //将canvas转为base64格式
          //输出图片的Base64,dataUrl
          this.shareImgData = canvas.toDataURL("image/png");
      });
    }, 500);
},

注意点:如果觉的html2canvas截图加载太慢或者卡顿,很可能是页面的元素较多,需要用参数ignoreElements去掉无用元素,详细可查看我之前的文章:juejin.cn/post/733162…

(2)将保存的图片展示到弹框之上,并且设置透明度为0,到此就实现了产品的要求了,打卡下班,下面的示例代码:

<div class="qp_box_img" v-if="shareImgData">
      <img :src="shareImgData" />
</div>
.qp_box_img {
        width: 690px;
        height: 1108px;
        position: absolute;
        top: 0;
        z-index: 999;
        opacity: 0;
        img {
            width: 690px;
            height: 1108px;
        }
    }

此处,会发现特意在img外层加了一个div,为啥不能img直接加opacity透明度呢?

因为,这里在手机版谷歌浏览器里会有个坑,image标签的opacity为<0.1的话,image元素直接消失了,导致我们不能长按保存了,因此在外层加了个div(在其他手机浏览器没问题,像苹果的safari,夸克等)