解析json结构绘制canvas

在工作中偶尔会遇到绘制转发卡/邀请卡的业务,且这个转发卡/邀请卡的风格会有很多,要求最后生成图片。这时候如果使用一张图片绘制一个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

如图有侵权,请联删。

原文地址:https://www.cnblogs.com/heyujun-/p/8908000.html

时间: 2024-11-13 08:13:20

解析json结构绘制canvas的相关文章

浅谈C#手动解析Json格式内容

这个应该算处女贴吧 - - 之前百度了许久基本没有一个满意的json结构的解析类库 想了想还是自己做一个吧 现在我来说下大概的思路 首先我创建了一个 JsonTokener的类 用于处理json字符串的一些操作里面有个枚举 1 public enum JsonCharType 2 { 3 BeginObject = 123, //{ 4 EndObject = 125, //} 5 BeginArray = 91, //[ 6 EndArray = 93, //] 7 DoubleQuote =

服务端提供的JSON数据接口与用户端接收解析JSON数据

首先来了解下JSON格式解析 json结构的格式就是若干个 键/值(key, value) 对的集合,该集合可以理解为字典(Dictionary),每个 键/值 对可以理解成一个对象(Object). 键/值 对中的 键(key) 一般是 一个string,值(value)可以是string.double.int等基本类型,也可以嵌套一个 键/值 对,也可以是一个数组,数组里面的数据的类型可以是基本类型,或者 键/值 对.可以看出 键/值 本来没什么,只是嵌套得多了就会觉得混乱,下面举个具体的例

go语音之进阶篇json解析到结构体

1.json解析到结构体 示例: package main import ( "encoding/json" "fmt" ) type IT struct { Company string `json:"company"` Subjects []string `json:"subjects"` //二次编码 IsOk bool `json:"isok"` Price float64 `json:"

一个Json结构对比的Python小工具兼谈编程求解问题

先上代码. jsondiff.py #_*_encoding:utf-8_*_ import argparse import json import sys reload(sys) sys.setdefaultencoding('utf-8') def parseArgs(): description = 'This program is used to output the differences of keys of two json data.' parser = argparse.Arg

Android中解析JSON形式的数据

1.JSON(JavaScript Object Notation) 定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. 2.JSON的结构: (1) Name/Value Pairs(无序的):类似所熟知的Keyed list. Hash table.Disctionary和Assoc

Java解析JSON对象

今天学习一下Java 解析 JSON 准备工作 参考文档 1) www.json.org 2 ) 参考公司其他人的代码(这个就不说了) 依赖jar包 1) org.json.jar 提供以下我的网盘链接 http://pan.baidu.com/s/1jG2zSwe 主要的类 JSON主要有两种结构 1)name/value 的集合 2)value 的集合,在大多数语言中的list,array等,这里的 value 个人觉得就是一个JSON,也就是说是JSON的集合 JAVA处理JSON的类 1

java 中解析json步骤

一.   JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧. Json建构于两种结构:     1."名称/值"对的集合(A collection of name/value pairs).不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array). 如: 

[iOS 多线程 &amp; 网络 - 2.1] - 解析json

A.iOS中json的基本使用 1.解析json数据 (1)json反序列化 对象{}格式 {key : value, key : value,...} 的键值对的结构可以反序列化为OC中的NSDictionary数组[]格式 ["java","javascript","vb",...]可以反序列化为OC中的NSArray 提示JSON的数据格式与OC中的快速包装方法非常类似JSON的数据格式同样支持嵌套 (2)json工具 从iOS 5开始,使

使用 Swift 解析 JSON

本文翻译自这篇文章,本文中所有的代码都放在Github. 我将在本文中概述一个使用 Swift 完成的处理 JSON 的解析库.一个 JSON 的例子如下: var json : [String: AnyObject] = [ "stat": "ok", "blogs": [ "blog": [ [ "id" : 73, "name" : "Bloxus test",