html2canvas(html转图片/html海报生成)

html2canvas 版本: 1.0.0-rc.4,这里说明下,不同的版本可能会有不同的表现形式。比如一开始用的最新的版本,出现了生成的图片中的文字无缘无故向下偏移一行,没有找到解决办法,于是降低了版本。

应用场景:本次是在vue项目中,几个不同的页面,有将整个页面生成海报,也有将弹框内容生成海报,所以将canvas方法单独封装了,需要的页面引入调用即可。当然,不是vue的项目,也可以使用我这方法,只是引入文件方式不一样。

新建canvas.js,将截图方法放入其中

import html2canvas from "html2canvas"

function DPR() {
    
     // 获取设备dpi
  if (window.devicePixelRatio && window.devicePixelRatio > 1) {
    
    
      return window.devicePixelRatio;
  }
  return 1;
};
export function canvas(params, callback) {
    
    
  // params.dom 需要转成图片的dom  css选择器
  let content_html = document.querySelector(params.dom)
  let width = content_html.offsetWidth;
  let height = content_html.offsetHeight
  let canvas = document.createElement("canvas")
  // 获取像素比
  let scaleBy = DPR()
  // 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
  canvas.width = width * scaleBy;
  canvas.height = height * scaleBy;
  // 设定 canvas css宽高为 DOM 节点宽高
  canvas.style.width = width + "px"
  canvas.style.height = height + "px"
  // 获取画笔
  // var rect = document.querySelector(params.dom).getBoundingClientRect();
  let context = canvas.getContext("2d")
  // context.translate(-rect.left, -rect.top);
  // 将所有绘制内容放大像素比倍
  // context.scale(scaleBy, scaleBy)
  // context.scale(1, 1)
  var opts = {
    
    
    allowTaint: false, //允许加载跨域的图片,默认false不可与useCORS同时存在
    tainttest: true, //检测每张图片都已经加载完成
    scale: scaleBy, // 添加的scale 参数,默认window.devicePixelRatio
    canvas: canvas, //自定义 canvas
    logging: false, //日志开关,发布的时候记得改成false
    // width: width, //dom 原始宽度,试过感觉影响不大
    // height: height, //dom 原始高度,试过感觉影响不大
    useCORS: true,
    ignoreElements: (element) => {
    
     //不需要转化的元素
      if (element.id == 'ig') return true
    },
    backgroundColor: null,
    // scrollY: 0,//通过外部调用地方传入
    // y: 0, //通过外部调用地方传入
    // dpi: scaleBy * 3
  };
  // 合并外部自定义参数(不同情况调用可能需设置不同参数)
  if(params.options) {
    
    
    opts = Object.assign( opts, params.options )
  }
  console.log(opts)
  html2canvas(content_html, opts).then(canvas => {
    
    
    var image = new Image()
    image.setAttribute("crossOrigin", "anonymous")
    // 获取生成的base64图片的url
    var imgUrl = canvas
      .toDataURL("image/jpeg")
      .replace("image/jpeg", "image/octet-stream")
    image.onload = function () {
    
    
      var canvas = document.createElement("canvas")
      canvas.width = image.width
      canvas.height = image.height
      var context = canvas.getContext("2d")
      context.drawImage(image, 0, 0, image.width, image.height)
      var url = canvas.toDataURL("image/png")
      // 回调,将生成的图片base64地址传出去,供调用的地方使用图片
      callback(url)
      // var a = document.createElement("a")
      // var event = new MouseEvent("click")
      // a.download = "图片"
      // a.href = url
      // a.dispatchEvent(event)
    }
    image.src = imgUrl
  })
}

页面调用:
首先引入上面的canvas,我这里是打开页面自动生成,所以最好在mounted生命周期中调用,最好加上this.$nextTick;如果是手动点按钮生成,就看实际情况调用

//页面
<div class="save-content>这个div是截图区域,里面内容按实际要求自己布局</div>
import {
    
     canvas } from "../../utils/canvas"
mounted(){
    
    
    this.$nextTick(()=>{
    
    
      setTimeout(()=>{
    
    
        this.loading = false
        this.getCanvas()
      },1000)
      //我这里延迟1s,是做了一个生成中的loading提示动画
    })
  },
methods: {
    
    
	// 截图
    getCanvas(){
    
    
      var that = this
      //dom对应页面上的css选择器选中的截图容器,option是另外的一些参数,回调是方法返回的图片base64,可以具体看上面的方法,一些配置参数也可以去html2canvas官网查看
      canvas({
    
     dom: '.save-content', options: {
    
     scrollX: 0, scrollY: 0 } }, (res)=>{
    
    
        this.$nextTick(()=>{
    
    
			console.log(res)
			//这里的res就是上面封装的canvas方法回调返回的图片base64,可以按照自己的需求做后续操作
        })
      })
    },
}

一些坑:
截图容器外面的盒子最好不要有transform: translate 等属性,这些属性会造成生成的截图有时候正常,有时候又有很大的偏移,如果有弹框或其他内容需要居中,建议用flex布局;
在做整个页面截图的时候,若是顶部距离视窗有距离,生成的图片顶部有偏移,可在options里配置y参数,数量为.save-content容易距离顶部视窗的距离;
另外,在强调下版本,经常会因为版本问题出现一个问题而无法解决,所以有时候碰到问题解决不了了可以换个版本试试;
关于需要截图区域内有图片,并且图片跨域问题,必须图片服务器配置了允许跨域,不然前端怎么搞都没有用,,或者直接让后端将图片转成base64,在返回你base64也行,
最后,html2canvas就是个坑,看似很简单,入手后各种坑,大家使用中多采坑,多调试,一步步的成功

猜你喜欢

转载自blog.csdn.net/LiuPangZi6/article/details/120214747