纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。

查阅很多资料后,几乎没有一个能完整解决问题的,都是东平西凑,各种调试才勉强解决生成图片的坑。

因为canvas始终会跨域,一般都是通过设置后端,改的麻烦也不知道行不行,所以就前端自己想办法解决,绕过后端。

canvas生成图片有要求,不可以是display:none;我是定位z-index负值,不设置透明度,除非你要生成透明的。

先贴下代码:


        

 此处为了方便,我直接写的内联样式,可无视、

import QRCode from 'qrcodejs2'  // 引入qrcode
import html2canvas from "html2canvas" // 生成图片;
import CompassImg from '@/common/js/filerar.js'
data(){
  return {
    showPoster: false,
    imgUrl : '', // 海报生成图
    posterimgUrl:'',// 海报图链接base64转码
  }
},
watch:{
    posterimgUrl(){ // 监听转码后的base64图片,有才生成图
            if(this.posterimgUrl){
                setTimeout(()=>{
                    this.createImage();
                })
            }
        }
},
methods:{
    // 展示分享海报
    toShowPoster() { // 点击这个按钮生成图片,上图html里没展示,随便写哪里都行、
        this.handleScroll();
        setTimeout(()=>{ // 转码生成之前,先监听滚动,否则出现截图不全甚至图片为空、
            this.showPoster = true; // 显示要被生成的海报元素
            this.showQRCode(); // 生成二维码 qrcodejs插件
            this.getPosterimgUrl(); // 获取海报图的图片链接,并转码
           })
    },
    handleScroll() {
      // 获取滚动距顶部的距离,显示
      let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      if(scrollTop>0){// 监听是否滚动,只要滚动了,每次点击生成的时候就让页面回到顶部,解决因滑动导致的生成图片不全甚至空白、
          console.log(scrollTop,'scrollTop');
          var c = setTimeout(() => window.scrollTo(0, 0), 16);//滚动至顶部
       }else{
            console.log('销毁');
            clearTimeout(c);
         }
     },
     showQRCode() { // 生成二维码
         this.$nextTick(()=>{
              var qrcode = new QRCode(this.$refs.qrcodeContainer, {
                  text: 'https://www.baidu.com,
                  width: '75',
                  height: '75',
                  colorDark: '#000000',
                  colorLight: '#ffffff',
                  correctLevel: QRCode.CorrectLevel.H
                
                })
            })
      },
      // 后端传入的图片链接src,转码
      getPosterimgUrl() {
            let pimg = this.product_data.image_banner[0]; //后端获取的图片链接
            // let index = pimg.toLowerCase().indexOf('.com') + 4;
            // let indexstr = pimg.substr(0,index);
            // let newImg = pimg.replace(indexstr,'//file.xxx.com');
            // console.log(newImg);

            var image = new Image();
            // image.crossOrigin = "*"; // 支持跨域图片 这一行会导致iOS微信报安全错误,换下一行的方式写法就好了,安卓没发现问题、
            image.setAttribute("crossOrigin",'anonymous'); // 解决iOS微信端报错 securityError...insource啥的、
          image.src = pimg + '?v=' + Math.random(); // 处理缓存
          image.onload = ()=>{//一定要在onload后去压缩转码,否则可能因图片未加载传入,报错或者undefind之类的
            var base64 = CompassImg(image);
               this.posterimgUrl= base64 // 将压缩转码后的图片保存,用以生成海报
          }
        },
        // 生成最终海报图
        createImage() {
            
            html2canvas(this.$refs.imageWrapper,{
                useCORS: true,
                backgroundColor: null,
                allowTaint: true
            }).then((canvas) => {
                let dataURL = canvas.toDataURL("image/png");
                this.imgUrl = dataURL;
            });
        },
 },
destroyed() {
        window.removeEventListener('scroll', this.handleScroll); //离开页面需要移除这个监听的事件
        console.log('监听销毁-- this.handleScroll');
    },


// compassImg引入的方法 filerar.js文件  base64压缩图片的方法

/* function getBase64Image(img) {
      var canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, img.width, img.height);
        var dataURL = canvas.toDataURL("image/png"); // 可选其他值 image/jpeg
      return dataURL;
      
}
  export default getBase64Image
*/

看下效果图:

纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第1张图片纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第2张图片

 

纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第3张图片 纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第4张图片

安卓和iOS都未报错。只打印了销毁。other_err忽略,其他组件的。

看下本地的iOS调试效果。滑动后的:

纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第5张图片

 滑动后,生成正常。按钮是悬浮出来的,如果包含在生成图的元素里,就会按钮也展示了。本地忽略了调试,只在真机调试了位置。

看看生成的图:

纯前端H5,利用html2canvas,base64转码,生成图片,解决iOS和安卓微信的坑,生成不全,空白,跨域等问题。_第6张图片

 无按钮,可以长按保存。可识别二维码。

下面再捋一捋思路。

在无后端帮助解决canvas跨域(非本地图片)的情况下,直接生成的图会显示空白。想了一个办法:

1、那就在生成前,把需要的图片src进行base64转码;(这里很多坑,iOS,安卓都有区别。图二js里解释了)

2、转码成功后,可以正常生成图片,但是发现新的问题,只要滑动了。就会截取少了滑动的部分。我选择暴力解决,转码生成前就去监听scroll事件,如果滚动了就让回到顶部,再生成。这就需要一个异步处理了。关闭页面,销毁监听。

本文是查阅了很多百度资料,综合解决了自己的H5微信ios,android的问题,且只生成一张图。多图的暂时为尝试。

你可能感兴趣的:(vue学习,js补基础,心得历程,html2canvas,html生成图片,canvas图片跨域)