首页 > 其他分享 >vue项目里地图组件截图快照的实现方法---html2Canvas

vue项目里地图组件截图快照的实现方法---html2Canvas

时间:2022-09-05 11:12:30浏览次数:67  
标签:canvas vue 快照 跨域 渲染 元素 截图 html2Canvas options

一、前言

最近项目里要求要把当前地图截图展示在小窗里,之前没接触这种请求,于是我就百度了一下,发现有这么一块插件html2Canvas,它能够将dom元素转换成canvas进行截图保存,而且兼容性比较好,基本Firefox 3.5+, Google Chrome, Opera新的版本, IE9以上的浏览器都支持,就决定试用一下html2Canvas插件,看下能否实现这样子的要求。

二、过程

1、首先我们需要在vue项目(2.0项目)里下载并引入一下

// 下载
npm install html2canvas

// 引入
import html2canvas from 'html2canvas'
复制代码

2、接下来就是调用了,用法也很简单

过程就是 1、获取该元素,打算截图的dom元素,用原生js获取,用ref获取都可以,没有限制

2、手动临时创建一个canvas,在这个基础上进行dom元素的canvas化

3、调用html2canvas(dom, options)方法

4、then之后,会返回一个canvas对象,我们这个调用canvas.toDataURL('image/png'),

把canvas转成base64。

语法小知识: canvas.toDataURL(type, encoderOptions)

type是图片格式,默认为 image/png,可以是其他image/jpeg等
encoderOptions,0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值。
复制代码

5、这个base64可直接给img标签使用

6、如果需要下载保存,可以调用downloadImage函数进行下载保存

// 页面元素转图片
toImage() {
  // 获取父标签,意思是这个标签内的 DOM 元素生成图片
  // map是给截图范围内的父级元素自定义的ref名称
  const canvasBox = this.$refs.map
  // 手动创建一个 canvas 标签
  const canvas = document.createElement('canvas')
  
  if (canvasBox) {
    // 获取父级的宽高
    const width = parseInt(window.getComputedStyle(canvasBox).width)
    const height = parseInt(window.getComputedStyle(canvasBox).height)
    canvas.style.width = width + 'px'
    canvas.style.height = height + 'px'
    const context = canvas.getContext('2d')
    const options = {
      backgroundColor: null, // 设置背景色为透明
      canvas: canvas,
      useCORS: true, //是否尝试使用CORS从服务器加载图像,解决跨域问题
      tainttest: true, // 是否在渲染前测试图片
      logging: false // 不启动日志调试
    }
    
    // canvasBox是要截图的元素,options是一些相关配置
    html2canvas(canvasBox, options).then((canvas) => {
      // toDataURL 图片格式转成 base64
      const dataURL = canvas.toDataURL('image/png')
      // 下载图片到本地
       this.downloadImage(dataURL)
    })
  }
},
// 下载图片
downloadImage(dataURL) {
    // 新建一个a标签
    var oA = document.createElement("a");
    oA.download = '截图';// 设置下载的文件名
    oA.href = dataURL;
    document.body.appendChild(oA);
    oA.click(); // 模拟点击a标签
    oA.remove(); // 下载之后把创建的元素删除
}
复制代码

三、可能遇到的问题

1、截图后图片和原先效果不太符合

html2Canvas是经过计算转成canvas的,对于自定义的样式有可能不支持。

2、文字样式丢失且都变成为最小号字体。

解决方案: 需要截图的节点根样式添加font-variant: normal;

3、文字向下偏移。

解决方案: 指定html2canvas的版本号为1.0.0-alpha.12

4、不完整,缺失,留白。

出现情况: 当截图区域超过视图高度,且滚动条未处在顶部时,会出现。

解决方案1:截图之前控制滚动条至顶部。

解决方案2:设置options里的scrollX为0, scrollY为0。

如果还有偏移,检查一下绘制的box上是不是加了transform:translateX(-50%)

5、模糊,不清晰。

出现情况: 通常是图片设置为背景的情况下,截图会比较模糊。

解决方案: 将背景图通过img标签加定位的方式实现。

6、截图空白

出现情况: 截图的dom元素里有非本地的图片资源

解决方案: 给 img 元素设置 crossOrigin 属性,值为 anonymous,同时要求图片服务端 设置允许跨域(返回 CORS 头),最后是options里设置useCORS为true,允许html2Canvas跨域 加载图片资源。尤其是地图,图片资源一定要服务端设置允许跨域,不然会截空白屏。

7、想要不截取某个子元素

解决方案: 调用options里的ignoreElements函数,匹配到对应节点,返回true就可以隐藏该元素

image.png

四、总结

插件好用是好用,但是坑也不少,希望我的文章能帮大家避避坑。

五、options的相关配置

详细的options配置表,我整理了一些,有需要可以自取:

名称默认值描述
allowTaint false 是否允许跨域图像污染画布(默认不允许渲染跨域图片)
backgroundColor #ffffff canvas画布背景色(如果未在DOM中指定)。设置null为透明
canvas null 使用现有canvas元素用作绘图的基础,即在该canvas基础上继续渲染我们的element
foreignObjectRendering   false 如果浏览器支持,是否使用ForeignObject渲染  
dpi    96 可以提高清晰度,缩放比例scale = dpi/96 (该属性是新加的,低版本可能没有)
imageTimeout 15000 加载图像的超时时间(以毫秒为单位)。设置0为禁用超时。
ignoreElements (element) => false 谓词功能,可从渲染中删除匹配的元素。
logging true 启用日志以进行调试
onclone null 克隆文档以进行渲染时调用的回调函数可用于修改将要渲染的内容,而不会影响原始源文档。onclone回调函数返回复制的文档根节点document,onclone:(doc)=>{}
proxy null 用于加载跨域图像的代理的网址。如果保留为空,则不会加载跨域图像。
removeContainer true 是否清除HTML2canvas临时创建的克隆DOM元素
scale window.devicePixelRatio 用于渲染的缩放比。默认为浏览器设备像素比率。
taintTest false 是否在渲染前测试图片  
timeout 0 Number类型,单位毫秒,设置图片加载延迟  
useCORS false 是否尝试使用CORS从服务器加载图像
width element width canvas画布的宽度
height element width canvas画布的高度
x element x-offset 裁剪画布X坐标
y element y-offset 裁剪画布y坐标
scrollX element scrollX 渲染元素时要使用的x滚动位置(例如,如果Element使用position: fixed)
scrollY element scrollY 渲染元素时要使用的y滚动位置(例如,如果Element使用position: fixed)
windowWidth window.innerWidth 渲染Element时要使用的窗口宽度,这可能会影响媒体查询之类的内容
windowHeight window.innerHeight 渲染Element时要使用的窗口高度,这可能会影响媒体查询之类的内容

ps:今天更新比较水了

image.png


作者:地霊殿__三無
链接:https://juejin.cn/post/7125449911750885413
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:canvas,vue,快照,跨域,渲染,元素,截图,html2Canvas,options
From: https://www.cnblogs.com/Earth-Hall-Sanwu/p/16657397.html

相关文章

  • vue+websocket
    一、websocket是什么WebSocket通信协议于2011年被IETF定为标准RFC6455,并由RFC7936补充规范。WebSocketAPI也被[W3C]定为标准。它算是html5规范中的一个部分,算是一种协......
  • vue3——shallowReactive 与 shallowRef
    shallowReactive:只处理对象最外层属性的响应式(浅响应式)。shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。什么时候使用?如果有一个对象数据,结......
  • vue3——toRef
    一.ref与toRef的区别:ref:复制,修改响应式数据不会影响原始数据toRef引用,修改响应式数据会影响原始数据ref:数据发生改变,界面会自动更新toRef:数据发生改变,界面也不会自......
  • Vue学习之--------深入理解Vuex之getters、mapState、mapGetters(2022/9/3)
    这一篇博客的内容是在上一篇博客的基础上进行:深入理解Vuex、原理详解、实战应用@目录1、getters的使用1.1概念1.2用法1.3如何读取数据2、getters在项目中的实际应用3......
  • Vue学习之--------深入理解Vuex之多组件共享数据(2022/9/4)
    在上篇文章的基础上:Vue学习之--------深入理解Vuex之getters、mapState、mapGetters1、在state中新增用户数组2、新增Person.vue组件提示:这里使用nanoid来生成新用户......
  • Vue学习之--------深入理解Vuex之模块化编码(2022/9/4)
    在以下文章的基础上1、深入理解Vuex、原理详解、实战应用:https://blog.csdn.net/weixin_43304253/article/details/1266513682、深入理解Vuex之getters、mapState、mapG......
  • Vue简介
    1.什么是vue官方给出的概念:Vue(读音/vju/,类似于view)是一套用于构建用户界面的前端框架1.构建用户界面用vue往html页面中填充数据,非常的方便2.框架......
  • VUE构建
    VUE渐进式JavaScript框架易学易用基于标准HTML、CSS和JavaScript构建,提供容易上手的API和一流的文档。性能出色经过编译器优化、完全响应式的渲染系统,几乎不......
  • vue3项目-小兔鲜儿笔记-商品详情页01
    1.基础布局完成商品详情基础布局,路由配置,搭好页面架子  2.渲染面包屑编写一个钩子函数useGoods.js,将面包屑获取数据的逻辑抽取出来。//拿到商品信息import{......
  • jQuery和Vue入门
    jQueryjQuery:别人写好的js文件*********jquery中所有东西都是函数:jQuery的放啊发名称:first获取名称的第一个元素名称:last获取名称的最后一个元素*$(documen......