需求在开发过程中,遇到了这样一个需求。h5页面需要将一个htmldom转成图片,方便用户保存。html2canvas和dom-to-image都是面向第三方百度搜索的,在写这篇笔记之前github上的star数都是有的。Dom-to-image4k??html2canvas13.7k??都试过了,都是意想不到的bug,包括一些背景图在部分手机上无法显示,空白。这个转换方法在iphone8plusios11中根本没有调用,导致无法得到想要的图像。等自己动手的想法用canvas的toDataURL获取canvas转换的base64码来替换img的url。也可以将图片上传到公司的服务器,获取图片的地址进行下载,或者将其作为参数传递给canvas绘制主要是文字和图片的绘制。文字的绘制比较简单,绘制图片也有一些需要注意的地方。Canvas初始化由于最终生成的图片可能比较模糊,你可以尝试画一个更大的canvas,可以按照设计图你的浏览器不支持Canvas?!赶紧换吧!!letc=document.getElementById("canvas");letctx=c.getContext("2d");文字绘制官方文档如图。;ctx.font="32pxPingFangSC-Regular";ctx.textAlign="left";ctx.fillText("这是一些文字",280,755);图片绘制官方文档如图,详细文档请参考canvas手册中的注意事项图片需要跨域处理,否则后面无法生成图片,即在里面添加crossOrigin属性img标签,值为anonymousconstinstBanner=document.getElementById("instBanner");instBanner.crossOrigin="anonymous";需要等到图片加载完成后再绘制到画布上,否则可能绘制不出来constposterBg=newImage();posterBg.src=mainBg;posterBg.onload=()=>{ctx.drawImage(posterBg,0,0,750,1164);}完整代码示例constposterBg=newImage();posterBg.src='https:....';//这里是图片urlposterBg.crossOrigin="anonymous";posterBg.onload=()=>{ctx.drawImage(posterBg,0,0,750,1164);}生成图片替换imgsrcletdataURL=c.toDataURL("image/png");letcanvasImg=document.getElementById("canvasImg");canvas.src=dataURL;上传服务器,获取imgurl(可作为参数,保存图片)getImgUrl();让canvasImg=document.getElementById("canvasImg");canvas.src=imgUrl;最后是绘制圆形图片的一些常用canvas处理方法ctx.save();ctx.beginPath();//开始绘图//先画一个圆。前两个参数确定圆心(x,y)。第三个参数是圆的半径。第四个参数是绘制方向。默认为false,即沿Clock手ctx.arc(60,60,30,0*Math.PI,2*Math.PI);ctx.clip();//画一个圆,在原画布上裁剪任意形状和大小一旦某个区域被裁剪,之后所有的绘制都会被限制在裁剪区域,这就是为什么我们要保存上下文ctx.drawImage('https:....',30,30,60,60);contex。恢复();//恢复之前保存的绘图上下文恢复之前保存的上午和下午的绘图,即状态可以继续绘制圆角矩形/**该方法用于绘制圆角矩形*@paramcxt:的上下文canvas*@paramx:左上角的x轴坐标*@paramy:左上角的y轴坐标*@paramwidth:矩形的宽度*@paramheight:矩形的高度*@paramradius:圆的半径*@paramlineWidth:线条粗细*@paramstrokeColor:线条颜色**/functionstrokeRoundRect(cxt,x,y,width,height,radius,/*可选*/lineWidth,/*optional*/strokeColor){//圆的直径必须小于矩形的宽高if(2*radius>width||2*radius>height){returnfalse;}cxt.save();cxt.translate(x,y);//绘制每个圆角矩形SidedrawRoundRectPath(cxt,width,height,radius);cxt.lineWidth=lineWidth||2;//如果给定值,则使用给定值,否则给定默认值2cxt.strokeStyle=strokeColor||"#000";cxt.stroke();cxt.restore();}/**该方法用于绘制一个填充颜色的圆角矩形*@paramcxt:canvascontext*@paramx:左上角x轴坐标*@paramy:左上角y轴坐标*@paramwidth:矩形的宽度*@paramheight:矩形的高度*@paramradius:圆的半径*@paramfillColor:填充Color**/functionfillRoundRect(cxt,x,y,width,height,radius,/*optional*/fillColor){//圆的直径必须小于矩形的宽高if(2*radius>width||2*radius>height){returnfalse;}cxt.save();cxt.translate(x,y);//绘制圆角矩形的每一边drawRoundRectPath(cxt,width,height,radius);cxt.fillStyle=填充颜色||"#000";//如果给定值,则使用给定值,否则给定默认值cxt.fill();cxt.restore();}函数drawRoundRectPath(cxt,width,height,radius){cxt.开始路径(0);//从右下角顺时针绘制,弧度从0到1/2PIcxt.arc(width-radius,height-radius,radius,0,Math.PI/2);//矩形底线cxt.lineTo(radius,height);//左下角圆弧,从1/2PI到PI的弧度cxt.arc(radius,height-radius,radius,Math.PI/2,Math.PI);//矩形左线cxt.lineTo(0,radius);//左上角圆弧,从PI到3/2PIcxt.arc(radius,radius,radius,Math.PI,Math.PI*3/2);//上线cxt.lineTo(width-radius,0);//右上角圆弧cxt.arc(width-radius,radius,radius,Math.PI*3/2,Math.PI*2);//右行cxt.lineTo(宽度,高度-半径);cxt.closePath();}?点击阅读原文