解析json結構繪制canvas
阿新 • • 發佈:2018-04-22
屏幕尺寸 eve brush list bound scale type document borde
在工作中偶爾會遇到繪制轉發卡/邀請卡的業務,且這個轉發卡/邀請卡的風格會有很多,要求最後生成圖片。這時候如果使用一張圖片繪制一個canvas,這個工作量會相當大。分析一下轉發邀請的內容,會發現所有的裏面的元素都是一樣的,只是風格不一致,所以我使用了解析json結構來繪制canvas,如果後期需要增加風格,只要增加json就可以了。
demo圖大概這樣:
點擊下方的不同風格的圖片就會生成不一樣的圖片。
下面我們要實現代碼:
style樣式:
*{padding: 0;margin: 0;} body{width: 100%;height:100%;overflow: hidden;} .ul{ position: fixed;bottom: 0;display: flex;width: 100%;font-size: 0;text-align: center; } a{height: 1.2rem;flex: 1;font-size: 14px;margin: 0 .1rem .1rem; } img{ width: 100%;height: 100%; } .temp{ width:100%;height: 10rem;margin: 0 auto;}
html結構:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> <title>canvas+json實現方法</title> </head> <body> <div class="main"> <div class="temp"> <canvas id="canvas"></canvas> </div> <div class="ul"> <a href="javascript:drawPic(1)"><img src="images/1.jpg"></a> <a href="javascript:drawPic(2)"><img src="images/2.jpg"></a> <a href="javascript:drawPic(3)"><img src="images/3.jpg"></a> <a href="javascript:drawPic(4)"><img src="images/4.jpg"></a> </ul> </div> <script src="jquery-3.2.1.min.js"></script> <script src="demo.js"></script> </body> </html>
demo.js:
// 適應各種屏幕尺寸 ;(function(win) { var doc = win.document; var docEl = doc.documentElement; var tid; function refreshRem() { var width = docEl.getBoundingClientRect().width; if (width > 640) { // 最大寬度 width = 640; } var rem = width / 6.4; docEl.style.fontSize = rem + ‘px‘; } win.addEventListener(‘resize‘, function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); win.addEventListener(‘pageshow‘, function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); refreshRem(); })(window); // 不同風格的json結構,在實際業務中可以移到服務器中 var json={ "success":true, "msg":null, "code":1, "lists":[ { "id":1, "bgcolor":"rgb(0,0,0)", "url":"./images/1.jpg", "elements":[ //存放元素 { "type":"img", "url":"./images/user.jpg", "style":{ "width":80, "height":80, "left":20, "top":20, "border":0, "borderRadius":100 //100表示畫原形圖片 0表示矩形圖片 0-100表示圓角圖片 } }, { "type":"txt", "content":"何小姐的博客", "style":{ "color":"#fff", "left":115, "top":55, "fontsize":20, "fontfamily":"Microsoft Yahei", "textalign":"left", } }, { "type":"txt", "content":"http://www.cnblogs.com/heyujun-/", "style":{ "color":"#fff", "left":115, "top":80, "fontsize":14, "fontfamily":"Microsoft Yahei", "textalign":"left", } } ] },{ "id":2, "bgcolor":"rgb(0,0,0)", "url":"./images/2.jpg", "elements":[ //存放元素 { "type":"img", "url":"./images/user.jpg", "style":{ "width":80, "height":80, "left":20, "top":20, "border":0, "borderRadius":100 //100表示畫原形圖片 0表示矩形圖片 0-100表示圓角圖片 } }, { "type":"txt", "content":"何小姐的博客", "style":{ "color":"red", "left":115, "top":55, "fontsize":20, "fontfamily":"Microsoft Yahei", "textalign":"left", } }, { "type":"txt", "content":"http://www.cnblogs.com/heyujun-/", "style":{ "color":"red", "left":115, "top":80, "fontsize":14, "fontfamily":"Microsoft Yahei", "textalign":"left", } } ] },{ "id":3, "bgcolor":"rgb(0,0,0)", "url":"./images/3.jpg", "elements":[ //存放元素 { "type":"img", "url":"./images/user.jpg", "style":{ "width":80, "height":80, "left":20, "top":20, "border":0, "borderRadius":100 //100表示畫原形圖片 0表示矩形圖片 0-100表示圓角圖片 } }, { "type":"txt", "content":"何小姐的博客", "style":{ "color":"#fff", "left":115, "top":55, "fontsize":20, "fontfamily":"Microsoft Yahei", "textalign":"left", } }, { "type":"txt", "content":"http://www.cnblogs.com/heyujun-/", "style":{ "color":"#fff", "left":115, "top":80, "fontsize":14, "fontfamily":"Microsoft Yahei", "textalign":"left", } } ] },{ "id":4, "bgcolor":"rgb(0,0,0)", "url":"./images/4.jpg", "elements":[ //存放元素 { "type":"img", "url":"./images/user.jpg", "style":{ "width":80, "height":80, "left":20, "top":20, "border":0, "borderRadius":100 //100表示畫原形圖片 0表示矩形圖片 0-100表示圓角圖片 } }, { "type":"txt", "content":"何小姐的博客", "style":{ "color":"#fff", "left":115, "top":55, "fontsize":20, "fontfamily":"Microsoft Yahei", "textalign":"left", } }, { "type":"txt", "content":"http://www.cnblogs.com/heyujun-/", "style":{ "color":"#fff", "left":115, "top":80, "fontsize":14, "fontfamily":"Microsoft Yahei", "textalign":"left", } } ] } ] } var canvas, ctx; // 根據json的id切換canvas內容 function drawPic(id){ $.each(json.lists,function(i,v){ if(v.id==id){ drawBackground(v.url, v); } }); } // 繪制背景圖的方法 function drawBackground(url, v){ var tempW=$(‘.temp‘).width(), tempH=$(‘.temp‘).height(); canvas=document.getElementById(‘canvas‘); canvas.width=tempW; canvas.height=tempH; ctx=canvas.getContext(‘2d‘); var Img = new Image(); // Img.crossOrigin="anonymous"; //跨域問題 Img.src=url; Img.onload=function(){ ctx.save(); ctx.drawImage(Img, 0, 0, canvas.width, canvas.height); ctx.restore(); $.each(v.elements,function(ii,vv){ if(vv.type=="img"){ drawImg(vv.url, vv.style); }else if(vv.type=="txt"){ drawTxt(vv.content, vv.style); } }); } } // 繪制圓形/圓角/矩形圖片元素的方法 function drawImg(url, style){ var l=style.left, t=style.top, w=style.width, h=style.height; var Img=new Image(); // Img.crossOrigin="anonymous"; //跨域問題 Img.src=url; Img.onload=function(){ ctx.save(); if(style.borderRadius == 0){ ctx.drawImage(Img, l, t, w, h); }else if(style.borderRadius > 0 && style.borderRadius < 100){ }else if(style.borderRadius==100){ var d = w; var cx = l + w/2; var cy = t + w/2; ctx.arc(cx, cy, w/2, 0, 2 * Math.PI); ctx.clip(); ctx.drawImage(Img, l, t, d, d); } ctx.restore(); } } // 繪制文字的方法 function drawTxt(cont, style){ ctx.beginPath(); ctx.fillStyle = style.color; ctx.font = style.fontsize+‘px ‘+style.fontfamily; ctx.textAlign = style.textalign; ctx.fillText(cont, style.left, style.top); ctx.fill(); ctx.closePath(); } drawPic(1);
這樣就實現了效果,由於跨域問題,這裏的生成圖片就略過了。
當然這種方法會有一個生成圖片的時間段,導致頁面看起來是在加載中,看個人怎麽取舍。
參考:移動端頁面使用rem來做適配 https://www.jianshu.com/p/eb05c775d3c6
如圖有侵權,請聯刪。
解析json結構繪制canvas