html2Canvas填坑史

需求:將html轉成圖片並保存下來

問題:

  1. 不能畫圓角;
  2. 圖片模糊;
  3. 圖片跨域;
  4. 圖片顯示不出來;
  5. 不能使用省略號;
  6. 圖片生成偶爾失敗;
  7. 如何將圖片轉成文件流,上傳

接下來,我一個個闡述一下如何解決這些問題

問題1:

主要是使用overflow:hidden,在外邊框加上border-radius即可

問題2:

圖片模糊,可以將圖片格式設置成jpeg的,同時擴大scale 的倍數,這樣就可以解決了

問題3:

跨域這個搗鼓了好久,最後 還是讓後端來允許跨域了,但是這裏前端也需要設置兩個地方:
1)設置useCORS:true, allowTaint: false
2)img元素裏面設置跨域:crossOrigin = ‘anonymous’

問題4:

圖片顯示不出來有兩個原因
1) 跨域導致的,解決方案還是讓後端允許跨域,另外img 裏面也要設置crossOrigin = ‘anonymous’
2)將img 包裝過後,最好使用img 來直接顯示圖片(我之前就用包裝過的img,然後圖片有時候能顯示,有時候顯示不出來)

問題5:

html2Canvas 就是不支持多行超出顯示省略號,這裏有兩個方案
1)超出高度之後,直接overflow:hidden
2) js控制字數,截取

問題6:

將dom 元素轉成base64 之後,顯示在img裏,在這個轉化的過程中,可以使用setTimeout ,將時間設置1000ms或者500ms,這樣就可以解決

問題7:

這個百度裏面有好多,我這裏就粘貼一下代碼,自測有效

                const base64ToBlob = function(base64Data, filename) {
                const arr = base64Data.split(',');
                const fileType = arr[0].match(/:(.*?);/)[1];
                const bstr = atob(arr[1]);
                let l = bstr.length;
                const u8Arr = new Uint8Array(l);
                while (l--) {
                    u8Arr[l] = bstr.charCodeAt(l); 
                }
                return new File([u8Arr], filename, {type:fileType})
            };
                 const file = base64ToBlob(base64Data, 'test.jpeg');

下面是全部的源代碼:

import React from 'react';
import html2canvas from 'html2canvas';
import {Toast} from 'antd-mobile';

// 具體option值可以查看文檔:http://html2canvas.hertzen.com/configuration

export function CreateImg(ele, newEle, hasNewImg){
    try {
        if(!ele) {
            Toast.info('生成圖片內容不能爲空');
            return ;
        }
        html2canvas(ele, {
            scale: 4, // 這一塊的倍數先設置4。小程序是6
            useCORS:true,
            allowTaint: false,
            logging:false,
            // taintTest: false,
        }).then(function(canvas) {
                const base64Data = canvas.toDataURL('image/jpeg',1.0);
                const newImg = new Image();
                newImg.src = base64Data;
                newImg.style.width = '3.74rem'; // 圖片寬度
                newImg.style.height = '6.16rem'; // 圖片高度
                newImg.crossOrigin = 'anonymous';
                newEle.appendChild(newImg);
                ele.style.display = 'none';
                if(base64Data) {
                    hasNewImg(true);
                }
            //  將圖片轉成file : base64-> blob -> file  繞道轉主要是爲了兼容ios
            // base64轉blob
            // const base64ToBlob = function(base64Data, filename) {
            //     const arr = base64Data.split(',');
            //     const fileType = arr[0].match(/:(.*?);/)[1];
            //     const bstr = atob(arr[1]);
            //     let l = bstr.length;
            //     const u8Arr = new Uint8Array(l);
            //     while (l--) {
            //         u8Arr[l] = bstr.charCodeAt(l);
            //     }
            //     return new File([u8Arr], filename, {type:fileType}); // 直接轉成file 格式
            // };
            // const file = base64ToBlob(base64Data, 'test.jpeg');
            // if(getFile){
            //     getFile(file);
            // }
        });
    } catch (error) {
        console.log('error:',error);
        Toast.fail('圖片生成失敗');
    }
}

// 在外部調用的時候使用
setTimeout(() => {
   CreateImg(this.imgBox, this.newImg, this.hasNewImg);
},500);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章