使用html2canvas生成canvas图片并下载
过程中遇到的几个常见问题
- 后端返回的图片跨域
- 海报内容多行文本省略号截图失败
- 图片模糊
海报效果图
话不多说上代码
<View className='postersBox'>
<View className='posterBg'>
<img className='posterBg-bgImg'
src={info.h5ShareUrl}
crossOrigin='anonymous'>
</img>
<View className='productTitle'>{info[groupName]}</View>
<View className='productCanvas'>
<canvas id='productCanvas' width={'540px'} height={'280px'} style={{ width:'270px',height: '140px' }}></canvas>
</View>
</View>
</View>
let canvas: any = document.querySelector("#productCanvas");
const ratio = window.devicePixelRatio || 1;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "#3D3D3D";
const fontSize = 32;
const lineHeight = fontSize * 1.42;
ctx.font = `${fontSize}px sans-serif`;
ctx.textAlign = "center";
ctx.textBaseline = "top";
const str = info?.description;
const lines: any = [];
let line = "";
let count = 0;
for (let i = 0; i < str.length; i++) {
if (ctx.measureText(line + str[i]).width > canvas.width) {
count++;
if (count == 6) {
lines.push(line.replace(/.$/, "..."));
line = "";
} else {
lines.push(line);
line = "";
}
}
line += str[i];
}
lines.push(line);
lines.forEach((item, index) => {
console.log(canvas.width / 2,
lineHeight * index + (lineHeight - fontSize) / 2)
ctx.fillText(
item,
canvas.width / 2,
lineHeight * index + (lineHeight - fontSize) / 2
);
});
ctx.scale(ratio, ratio)
const posterBg: any = document.querySelector('.posterBg')
return new Promise(() => {
setTimeout(() => {
html2canvas(posterBg, {
useCORS: true,
allowTaint: true,
}).then((res) => {
const posterBgWx = document.createElement('img')
const postersBox: any = document.querySelector('.postersBox')
postersBox.appendChild(posterBgWx)
posterBgWx.className = 'posterBgWx'
posterBgWx.src = res
.toDataURL('image/jpeg')
.replace('image/jpeg', 'image/octet-stream')
})
}, 300)
})
图片跨域在此场景尝试img转base64等格式处理无效最后在img标签加crossOrigin='anonymous'属性并配合后端配置CORS解决(根据实际情况配置)