html2canvas填坑指难

前端生成图片只有一种方法,就是用canvas画图,转成图片格式。

使用原生canvas画图,简单的实现画图还可以操作,如果是画海报,画二维码,就比较吃力,一般用现成的库来做。

画二维码有专门的二维码生成库 qrcode
把dom转成图片有专门库 html2canvas,一般前端生成海报都是用这个库

html2canvas 使用直接参考官网,使用比较简单

使用过程中我遇到的坑

  1. 图片资源跨域问题
  2. 股东页面后,截图不完整
  3. 图片有背景颜色

1.

图片跨域可以加
useCORS: true

经测试,就算加了允许跨域设置在一些苹果手机还是会出现截图为空白的情况,
需要把海报中的图片转成 base64 图片,在生成截图,就不会出现跨域问题了。

2.

页面滚动后,截图不完整
对于要生成分享的海报,在页面没有显示的。一般做法是把海报样式写好,隐藏在可视区域外,点击生成海报,然后截图

.outview {
     
    position: fixed; /*设置成 absolute 有遇到截图空白问题,建议设置成 fixed*/
    top: 0; /* 需要设置 不然出现滚动截图不完整*/
    left: -9999px;
}

3.

设计给的海报有圆角,生成海报图片后,圆角有白色背景,设置 backgroundColor: 'transparent' 可以解决

示例代码是在vue项目中使用的,如果需要在其他地方使用需要自行修改。
完整代码:

const handlePoster = {
     
  data() {
     
      return {
     
          cover: '', // 海报封面图
          posterSrc: '', // 生成的海报
      }
  },
  methods: {
     
    createImage() {
     
        this.$vux.loading.show({
     
            text: '生成海报中'
        })
        if (this.cover.indexOf('data:image') > -1) {
     
          this.dom2canvas()
          return
        }
        // 处理图片跨域问题,把图片转成base64
        let imageEl = new Image()
        imageEl.crossOrigin = '*' // 设置图片允许跨域访问
        // 防止读取本地(浏览器)缓存,本地图片有跨域问题
        imageEl.src = this.detailsInfo.image + '?v' + Math.random() 
        imageEl.onload = () => {
     
          let base64 = getBase64Image(imageEl)
          this.cover = base64
          this.$nextTick(() => {
     
            this.dom2canvas()
          })
        }
        imageEl.onerror = () => {
     
          this.$vux.loading.hide()
          this.$vux.toast.text('生成海报失败请重试')
        }
      },
      dom2canvas() {
     
        html2canvas(this.$refs.boxPoster.$el, {
     
          logging: true,
          useCORS: true,
          scrollY: 0, // 页面滚动后截图不完整,需要设置
          scrollX: 0,
          backgroundColor: 'transparent', // 背景图片有默认颜色,需要设置
        }).then((canvas) => {
     
          this.posterSrc = canvas.toDataURL()
          this.$vux.loading.hide()
        })
      },
    }
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
     
  mixins: [myMixin]
})
var component = new Component() // 在组件中使用
// 不推荐全局混入
// Vue.mixin(handlePoster)

截图不完整问题可参考

你可能感兴趣的:(JavaScript,canvas,html2canvas)