本篇主要記錄使用使用canvas將多圖合成一張圖片的方法及遇見的幾個坑。
實現代碼及思路
// 把多張圖拼接成一張
canvasDrawImage(imgData, obj) {
let self = this;
let width = 50;
let height = 50;
// 獲取最大的寬度和所有的高度
imgData.forEach(img => {
width = img.w > width ? img.w : width;
height = height + img.h;
})
// 初始化canvas
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
// 繪製矩形添加白色背景色
context.rect(0, 0, width, height);
context.fillStyle = "#fff";
context.fill();
// 多圖繪製,下一張的y應該是上一張的高度
let beforeHeight = 0;
let p = [];
imgData.forEach(img => {
if (img.imageUrl) {
// 因爲圖片加載會有延遲,因此使用promise 保證合併圖片的正確性
let p1 = new Promise(resolve => {
let imgUpload = new Image();
// 防止跨域
imgUpload.setAttribute('crossOrigin', 'anonymous');
imgUpload.src = img.imageUrl.indexOf('?') > -1 ? img.imageUrl + '&v=' + Math.random() : img.imageUrl + '?v=' + Math.random();
imgUpload.onload = function () {
context.drawImage(imgUpload, 0, beforeHeight, img.w, img.h);
beforeHeight = beforeHeight + img.h;
resolve(true)
}
});
p.push(p1);
}
});
Promise.all(p).then(res => {
try {
let img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
let src = canvas.toDataURL("image/png");
console.log(src)
// to do something...
} catch (e) {
self.mergeLoading = false;
self.mergeSuccess(obj);
console.log(e)
}
})
}
遇到的坑的說明
context.drawImage(imgUpload, 0, beforeHeight, img.w, img.h);
這裏的第一個參數是圖片,可以是img的 dom 元素,不是圖片的地址,必須是圖片加載後纔可以~
2、使用過程中報錯context的方法有問題,這裏需要在圖片後面加個後綴
imgUpload.src = img.imageUrl.indexOf('?') > -1 ? img.imageUrl + '&v=' + Math.random() : img.imageUrl + '?v=' + Math.random();
3、canvas.toDataURL("image/png")
,第一個參數要填寫!此外如果返回的是data;
空數據,那麼要注意看下是不是canvas的高度沒設置好!