本次作h5 活動,遇到一個需求,點擊button 把html 生成圖片,長按保存功能 因爲html的結構比較複雜,使用canvas 直接畫相對來講增長了不小工做量,因此使用html2canvas ,html2canvas的使用比較簡單,可是坑也不少css
談到跨域問題,應該只要入了canvas toDataURL 轉成圖片的坑就應該遇到過這個問題,若是不進行跨域處理生成圖片不能跨域的圖片會空白處理 這個沒有好的解決方案, 圖片服務器須要配置Access-Control-Allow-Origin 因爲公司的開發build 與 js 是兩個團隊在作,build 團隊的圖片地址都是不可跨域的,並且頁面因此的圖片設置都是background image 的形式,針對這個問題我作了以下處理html
固然這樣尚未結束,配置html2canvasvue
html2canvas(dom, {
backgroundColor: null,
canvas,
//allowTaint: true,
useCORS: true
})
複製代碼
useCORS 設置容許跨域,特別提醒 allowTaint 也是容許跨域,可是這個容許跨域只是容許你跨域生成canvas ,可是仍是不能把canvas轉化成圖片,要想解決toDataURL 的跨域問題,還須要使用useCORS。可是這兩個屬性不能共生web
把scale 設置成二倍直接上代碼算法
* 根據window.devicePixelRatio獲取像素比
*/
function DPR() {
if (window.devicePixelRatio && window.devicePixelRatio > 1) {
return window.devicePixelRatio;
}
return 1;
}
.....
// DOM 節點計算後寬高
const width = parseValue(box.width);
const height = parseValue(box.height);
// 獲取像素比
const scaleBy = DPR()*2;
// 建立自定義 canvas 元素
var canvas = document.createElement('canvas');
// 設定 canvas 元素屬性寬高爲 DOM 節點寬高 * 像素比
canvas.width = width * scaleBy;
canvas.height = height * scaleBy;
// 設定 canvas css寬高爲 DOM 節點寬高
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
// 獲取畫筆
const context = canvas.getContext('2d');
// 將全部繪製內容放大像素比倍
context.scale(scaleBy, scaleBy);
// imageSmoothingEnabled Canvas 2D API 用來設置圖片是否平滑的屬性,true表示圖片平滑(默認值),false表示圖片不平滑,默認的改變大小的算法會形成圖片模糊而且破壞圖片原有的像素。 若是那樣的話,設置屬性值爲false。
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
.....
html2canvas(dom, {
backgroundColor: null,
canvas,
width: width, // 設置width
height: height, // 設置height
scale: scaleBy,// 設置scaleBy
useCORS: true
})
複製代碼
過程當中使用的雪碧圖最容易出現模糊的狀況,因此圖片須要使用2倍圖canvas
可能這個題目不是很好的描述問題。我先描述一下問題所在,因爲html2canvas 生成圖片所在的html 必須是真實存在的,不然生成canvas爲空白。也就是須要生成html不能設置 disabled: none; visibility: hidden; 等屬性。 所以代表在調用html2canvas 生成canvas 過程當中必須dom 節點渲染完成。所以這就會致使在生成canvas 會出現原有html 的閃現 這個問題其實也比較好解決,用了一個小技巧,使用top 屬性,把html 移除視野 top:100%
固然這個解決方案比較多,目前我用的是這個跨域
這個問題,自己須要生成的html 中有一部分是輪播圖,這樣html dom 會動態渲染, 解決方案很簡單,取消輪播圖,直接用 v-if(注:工程使用vue 開發)斷定進行html 渲染,取消輪播bash
這個問題我也沒找到緣由,結果就是雖然設置了background-repeat: no-repeat; 可是圖片底部會出現大約1像素的重複。 因爲沒有找到根本緣由,使用了最直接的的方案解決,直接把圖片高度增長2像素,成功避免了這個問題。(哈哈哈哈,我真是一個投機取巧的鬼才)服務器
因爲代碼中有段文字須要多行末尾省略號,因此出現以下cssdom
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
複製代碼
在html2canvas中,會將css中的display中的值映射成一個數字,而在下圖的映射表中,只要找到了flex的映射值,並無--webkit-flex的映射值,因此-webkit-flex被映射成了DISPLAY.NONE,從而致使了isVisible的計算值返回了false,最終致使了沒法生成想要的canvas
解決方案不使用flex佈局,js 實現文字溢出,此方案僅限於文字個數具體的狀況下,因此比較侷限,你們有好的方案歡迎補充 css
height:2倍的line-height; /*根據實際需求更改*/
display:inline-block;
複製代碼
js
contentText(num){
const ellipsis = oldContentText.length > num?'...':''
return oldContentText.slice(0,num) + ellipsis
}
複製代碼