zoukankan      html  css  js  c++  java
  • 解析json结构绘制canvas

    在工作中偶尔会遇到绘制转发卡/邀请卡的业务,且这个转发卡/邀请卡的风格会有很多,要求最后生成图片。这时候如果使用一张图片绘制一个canvas,这个工作量会相当大。分析一下转发邀请的内容,会发现所有的里面的元素都是一样的,只是风格不一致,所以我使用了解析json结构来绘制canvas,如果后期需要增加风格,只要增加json就可以了。

    demo图大概这样:

    点击下方的不同风格的图片就会生成不一样的图片。

    下面我们要实现代码:

    style样式:

    *{padding: 0;margin: 0;}
    body{ 100%;height:100%;overflow: hidden;}
    .ul{ position: fixed;bottom: 0;display: flex; 100%;font-size: 0;text-align: center; }
    a{height: 1.2rem;flex: 1;font-size: 14px;margin: 0 .1rem .1rem; }
    img{  100%;height: 100%; }
    .temp{ 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

    如图有侵权,请联删。

  • 相关阅读:
    【NIO】IO与NIO的区别
    【在线工具】java开发常用在线工具
    【JVM】符号引用和直接引用
    【多线程】公平锁/非公平锁、乐观锁/悲观锁
    【Jenkins、sonar】
    开源软件记录
    Git Flow
    CF1324A Yet Another Tetris Problem 题解
    洛谷 P1199 三国游戏 题解
    CF33C Wonderful Randomized Sum 题解
  • 原文地址:https://www.cnblogs.com/heyujun-/p/8908000.html
Copyright © 2011-2022 走看看