html2canvas (html to picture/html poster generation)

html2canvas version: 1.0.0-rc.4, as explained here, different versions may have different manifestations. For example, in the latest version used at the beginning, the text in the generated picture was shifted down one line for no reason, and no solution was found, so the version was reduced.

Application scenario: This time, in the Vue project, several different pages generate posters for the entire page, and generate posters for the content of the bullet box, so the canvas method is encapsulated separately, and the required pages can be imported and called. Of course, projects that are not Vue can also use my method, but the way to import files is different.

Create a new canvas.js and put the screenshot method into it

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
  })
}

Page call:
first introduce the above canvas, which is automatically generated when I open the page, so it is best to call it in the mounted life cycle, it is best to add this.$nextTick; if it is generated manually by clicking the button, it depends on the actual situation.

//页面
<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,可以按照自己的需求做后续操作
        })
      })
    },
}

Some pitfalls:
It is best not to have transform: translate and other attributes in the box outside the screenshot container. These attributes will cause the generated screenshots to sometimes be normal, and sometimes have a large offset. If there is a bullet box or other content that needs to be centered, it is recommended Use flex layout;
when taking screenshots of the entire page, if there is a distance between the top and the window, and the top of the generated picture has an offset, you can configure the y parameter in options, and the number is the distance between .save-content and the top window; in addition
, Emphasizing the next version, there is often a problem that cannot be solved due to a version problem, so sometimes you can try another version if you encounter a problem that cannot be solved; as
for the problem that there are pictures in the screenshot area and the picture is cross-domain, you must configure the picture server In order to allow cross-domain, otherwise the front-end will be useless, or directly let the back-end convert the picture into base64, and return your base64. Finally, html2canvas
is a pit, which seems very simple. After getting started, various pits, Everyone uses more pits, more debugging, and success step by step

Guess you like

Origin blog.csdn.net/LiuPangZi6/article/details/120214747