vue 使用 HTML2CANVAS 实现移动端H5页面截图

说明:项目中需要一个分享海报,通常都是一张海报和一个后端生成的二维码,业务需求是要求两张图片合在一起,保存到手机之后可以分享给好友。

1、通过 npm 或者下载已建立的版本来安装 html2canvas。

npm install html2canvas

2、在vue模板使用,

通过ref找到需要截图的模块,比如一个弹出框的海报,指定ref,获取dom

注意:你需要截图的dom块不需要任何css,特别不要有定位的样式,如果需要定位的话,在父元素(.poster-content)把css写好,确保截图的完整性,里面的子元素可以使用定位的css(比如需要把二维码定位到海报的指定位置),不受影响。

// 通过ref获取dom
<div class="poster-content">
    <div ref="screenshotDOM">
        <span class="clos" @click="handleClos">&times;</span>
        <img src="你的图片地址" alt="">
        <img class="qrcode" src="你的二维码图片地址" alt="">
    </div>
    <button @click="handleScreenshot">保存海报</button>
</div>

<script setup lang="ts">
import { computed, ref } from "vue";
import { drawToPic } from "@/utils";

const screenshotDOM = ref();

// vue3 写法
handleScreenshot(){
    drawToPic(screenshotDOM.value)
}

// vue2 写法
handleScreenshot(){
  drawToPic(this.$refs.screenshotDOM)
}
</script>

html2canvas 的二次封装(在单独的 utils/index.js(ts)),options配置项可以根据需求配置,也可以不传。

import html2canvas from 'html2canvas'

/**
* @param {element} el       截图的dom区域(通过ref获取打的dom)     
* @param {Object} options   插件的一些自定义配置
* 注意:1、配置项官网地址: https://allenchinese.github.io/html2canvas-docs-zh-cn/docs/html2canvas-configuration.html
*      2、获取dom的时候需要等待页面加载完成之后
*      3、ignoreElements 方法会遍历所有节点,我这里给了一个id为clos的结点,因为不需要在截图中留下,就把该节点排除了.
*/ 
export function drawToPic(el: Element) {
    const width = parseInt(window.getComputedStyle(el).width)
    const height = parseInt(window.getComputedStyle(el).height)
    const cs = document.createElement('canvas')
    const scale = 1
    cs.width = width * scale
    cs.height = height * scale
    const options = {
        useCORS: true,
        canvas: cs,
        scale: scale,
        ignoreElements: (element: Element) => element.id === 'clos',
    }
    html2canvas(<HTMLElement>el, options).then((canvas) => {
        const url = URL.createObjectURL(base64ToBlob(canvas.toDataURL("image/png")))
        downloadImage(url)
    })
}


// base64转blob
function base64ToBlob(code: any) {
    const parts = code.split(';base64,')
    const contentType = parts[0].split(':')[1]
    const raw = window.atob(parts[1])
    const rawLength = raw.length
    const uInt8Array = new Uint8Array(rawLength)
    for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i)
    }
    return new Blob([uInt8Array], {type: contentType})
}
//下载图片
function downloadImage(url: any) {
    // 这里使用 img 是因为在客户端中,不能直接下载,要调用原生的方法
    const createImg = document.createElement('img')
    createImg.setAttribute('src', url)
    // 如果是在网页中可以直接创建一个 a 标签直接下载
    const a = document.createElement('a')
    a.href = url
    window.open(a.href) //测试时候使用,截图之后新开一个浏览器页面查看是否截图成功
    // a.download = new Date().getTime().toString()
    // a.click()
}

写在结尾:

有的远程图片地址可能有跨域的问题,这个需要和后端协调一下。如果暂时有跨域问题,可以使用本地的图片测试该截图功能是否能正常使用,后续再解决图片跨域的问题,如果你的项目图片没有跨域问题,那就更好了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值