在工作中偶尔会遇到绘制转发卡/邀请卡的业务,且这个转发卡/邀请卡的风格会有很多,要求最后生成图片。这时候如果使用一张图片绘制一个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="data:images/1.jpg"></a>
<a href="javascript:drawPic(2)"><img src="data:images/2.jpg"></a>
<a href="javascript:drawPic(3)"><img src="data:images/3.jpg"></a>
<a href="javascript:drawPic(4)"><img src="data: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的更多相关文章

  1. C#用GDI+解析Json文件绘制Chart

    using System.Collections.Generic; namespace Chart { public class Program { static void Main(string[] ...

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

    先上代码. jsondiff.py #!/usr/bin/python #_*_encoding:utf-8_*_ import argparse import json import sys rel ...

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

    JSON格式的服务接口:http://www.cnblogs.com/visec479/articles/4118338.html 首先来了解下JSON格式解析 json结构的格式就是若干个 键/值( ...

  4. Python实现Json结构对比的小工具兼谈编程求解问题

    摘要: 通过使用Python编写一个解析Json结构对比的小工具,来提炼编程求解的通用步骤和技巧. 难度: 初级 先上代码. jsondiff.py #!/usr/bin/python #_*_enc ...

  5. 奇葩json结构解析--key是数字的json处理

    json结构如下: { "ret": "ok", "data": { "57230": { "cat_id&q ...

  6. go语言之进阶篇json解析到结构体

    1.json解析到结构体 示例: package main import ( "encoding/json" "fmt" ) type IT struct { ...

  7. Golang Json文件解析为结构体工具-json2go

    代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...

  8. 使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)

    在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象 ...

  9. C语言创建及解析Json的使用法则

    参考原文:http://blog.csdn.net/xukai871105/article/details/33013455 JSON(JavaScriptObject Notation)是一种轻量级 ...

随机推荐

  1. jpetStore 学习总结(2)

    在写jpetstore时,最难理解的应该是数据库还有每个表之间的关系了,我在这里对数据库简单的介绍. 以下是数据库的所有表:    account表是个人信息表,里面包括用户的名字,邮箱,地址,哪个城 ...

  2. 使用hexo+coding搭建免费个人博客

    1.检测node和npm 先检测一下有没有node.js和npm $ node -v //如果有,说明node.js安装成功! $ node -v v8.4.0 //如果有,说明npm安装成功! $n ...

  3. [BJOI2014]大融合(LCT)

    题面 luogu bzoj是权限题.. 题解 \(LCT\)维护子树信息 因为\(LCT\)中有一些虚子树,\(splay\)维护不了. 所以要新开一个数组来记录 然后注意\(link\)时 是先\( ...

  4. [性能测试]:关于MQ协议脚本开发

    消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们. 银行脚本使用MQ通信的较多,下面介绍一个MQ的脚本: M ...

  5. [转] Akka 使用系列之二: 测试

    [From] http://www.algorithmdog.com/akka-test 通过上一篇文章,我们已经大致了解怎么使用 Akka,期待细致用法.这篇文章将介绍如何用 Akka-testki ...

  6. 在国内运行Flutter配置的正确姿势--如出现Oops; flutter has exited unexpectedly.

    如果根据flutter的官网教程,在运行flutter doctor时无法下载依赖,请根据以下步骤 export PUB_HOSTED_URL=https://pub.flutter-io.cn ex ...

  7. Firefox、Chrome、IE9、IE8、IE7、IE6等浏览器HTTP_USER_AGENT汇总

    Firefox.Chrome.IE9.IE8.IE7.IE6 浏览器HTTP_USER_AGENT汇总 结论:  浏览器 \ OS XP(IE6) XP(IE7) XP(IE8) Win7 x64(I ...

  8. 没事用html5 canvas画一个仪表盘自用,自适应的哦

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 爬虫URL去重

    这个要看你想抓取的网页数量是哪种规模的.如果是千万以下用hash表, set, 布隆过滤器基本可以解决,如果是海量的......嗯我也没做过海量的,不过hash表之类的就别想了,内存根本不够,分割线下 ...

  10. ubuntu 配置 samba服务器

    samba配置的安装: sudo apt-get install samba smbfs smbclient 二. 创建共享目录: mkdir /home/komy/sharesudu chmod 7 ...