在開發過程當中遇到這麼一個需求,h5頁面須要將一個html dom轉化成圖片,便於用戶保存。html
二者在寫這篇筆記以前在github上的星星數分別是ios
dom-to-image 4k ⭐️git
html2canvas 13.7k ⭐️github
二者都有嘗試過,都有意想不到的bug,包括canvas
等等跨域
利用canvas的toDataURL來拿到canvas轉化的base64碼,來替換img的url, 也能夠把圖片上傳到公司的服務器上,獲得圖片的地址來進行下載,或做爲參數來傳遞瀏覽器
那麼canvas的繪製主要就是文本和圖片的繪製,文本繪製相對簡單,圖片繪製有一些注意點。服務器
因爲最後生成的圖片可能會模糊,能夠儘可能畫大一點畫布,能夠按照設計圖來dom
<canvas id="canvas" width="750" height="1164"> 你的瀏覽器竟然不支持Canvas?!趕快換一個吧!! </canvas>
let c = document.getElementById("canvas"); let ctx = c.getContext("2d");
ctx.fillStyle = "#fff"; ctx.font = "32px PingFangSC-Regular"; ctx.textAlign = "left"; ctx.fillText("這是一些文字", 280, 755);
const instBanner = document.getElementById("instBanner"); instBanner.crossOrigin = "anonymous";
const posterBg = new Image(); posterBg.src = mainBg; posterBg.onload = () => { ctx.drawImage(posterBg, 0, 0, 750, 1164); }
const posterBg = new Image(); posterBg.src = 'https:....'; //這裏是圖片url posterBg.crossOrigin = "anonymous"; posterBg.onload = () => { ctx.drawImage(posterBg, 0, 0, 750, 1164); }
let dataURL = c.toDataURL("image/png"); let canvasImg = document.getElementById("canvasImg"); canvas.src = dataURL;
let dataURL = c.toDataURL("image/png"); function getImgUrl(dataURL){ //一些上傳服務器的代碼 return imgUrl } let imgUrl = getImgUrl(); let canvasImg = document.getElementById("canvasImg"); canvas.src = imgUrl;
ctx.save(); ctx.beginPath(); //開始繪製 //先畫個圓 前兩個參數肯定了圓心 (x,y) 座標 第三個參數是圓的半徑 四參數是繪圖方向 默認是false,即順時針 ctx.arc(60, 60, 30, 0 * Math.PI, 2 * Math.PI); ctx.clip();//畫好了圓 剪切 原始畫布中剪切任意形狀和尺寸。一旦剪切了某個區域,則全部以後的繪圖都會被限制在被剪切的區域內 這也是咱們要save上下文的緣由 ctx.drawImage('https:....', 30, 30, 60, 60); contex.restore(); //恢復以前保存的繪圖上下文 恢復以前保存的繪圖上下午即狀態 還能夠繼續繪製
/**該方法用來繪製圓角矩形 *@param cxt:canvas的上下文環境 *@param x:左上角x軸座標 *@param y:左上角y軸座標 *@param width:矩形的寬度 *@param height:矩形的高度 *@param radius:圓的半徑 *@param lineWidth:線條粗細 *@param strokeColor:線條顏色 **/ function strokeRoundRect(cxt,x,y,width,height,radius,/*optional*/lineWidth,/*optional*/strokeColor){ //圓的直徑必然要小於矩形的寬高 if(2*radius>width || 2*radius>height){return false;} cxt.save(); cxt.translate(x,y); //繪製圓角矩形的各個邊 drawRoundRectPath(cxt,width,height,radius); cxt.lineWidth = lineWidth||2;//如果給定了值就用給定的值不然給予默認值2 cxt.strokeStyle=strokeColor||"#000"; cxt.stroke(); cxt.restore(); } /**該方法用來繪製一個有填充色的圓角矩形 *@param cxt:canvas的上下文環境 *@param x:左上角x軸座標 *@param y:左上角y軸座標 *@param width:矩形的寬度 *@param height:矩形的高度 *@param radius:圓的半徑 *@param fillColor:填充顏色 **/ function fillRoundRect(cxt,x,y,width,height,radius,/*optional*/fillColor){ //圓的直徑必然要小於矩形的寬高 if(2*radius>width || 2*radius>height){return false;} cxt.save(); cxt.translate(x,y); //繪製圓角矩形的各個邊 drawRoundRectPath(cxt,width,height,radius); cxt.fillStyle=fillColor||"#000";//如果給定了值就用給定的值不然給予默認值 cxt.fill(); cxt.restore(); } function drawRoundRectPath(cxt,width,height,radius){ cxt.beginPath(0); //從右下角順時針繪製,弧度從0到1/2PI cxt.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/2PI cxt.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(width,height-radius); cxt.closePath(); }
» 點擊閱讀原文iphone