基于canvas的二维码邀请函生成插件
去年是最忙碌的一年,实在没时间写博客了,看着互联网行业中一个又一个人的倒下,奉劝大家,健康要放在首位,保重身体。
好了,言归正传,这是17年的第一篇博文,话说这天又是产品同学跑过来问我说:hi,lenny,你看现在市面上流行各种装逼H5,随便输入点名字啥的就给我生成房产证了,这种还可以分享出去,传播率可高了,或者你再看这里,一键生成邀请函,牛逼吧,要不你也帮我做一个这个功能,我去玩点传播手段。

我看见效果后第一反映就是,肯定canvas进行的图片拼接,现在市面上流行的效果具体是如何实现的我没有去看源码,思路很清晰,于是晚饭后没有下班,开始我的插件制作之旅了。
首先,我们需要思考,既然是图片处理,那么就必然存在图片下载,我们知道图片的onload是异步回调,所有的资源必须在下载完成后才可以进行接下来的逻辑,前置资源下载的逻辑就很关键,我们不仅需要在onload事件回调后去处理我们后续的流程,同时需要在所有必须资源加载完成后才执行,所以我们需要构建一个资源数组大致如下:
[{
{
name: 'bg',
src: '../img/bg.jpg'
}, {
name: 'z',
src: '../img/z.png'
}]
为了获得最终的complete事件,我们需要利用一个全局变量监听onload或者onerror次数:
var i = 1;
arr.forEach(function(obj, index, array) {
function onLoad() {
_self[obj.name] = img;
if (i < array.length) {
++i;
} else {
console.log('complete');
};
}
var img = new Image();
img.onload = onLoad;
img.onerror = onLoad;
img.src = obj.src;
好了,资源加载完成事件我们得到了,可以继续下面的逻辑,既然是基于canvas,当然需要创建并初始化我们的canvas,我根据自己的需求,这个功能在我所使用的项目中不论初始化多少次,只会存在一个,所以我做了如下的控制:
init: function() {
var LCanvasImg_canvas = document.querySelector('#LCanvasImg_canvas');
if (LCanvasImg_canvas) {
LCanvasImg_canvas.width = this.params.cw;
LCanvasImg_canvas.height = this.params.ch;
LCanvasImg_canvas.style.display = this.params.display;
this.canvas = LCanvasImg_canvas;
} else {
var canvas = document.createElement('canvas');
canvas.id = 'LCanvasImg_canvas';
canvas.width = this.params.cw;
canvas.height = this.params.ch;
canvas.style.display = this.params.display;
document.body.appendChild(canvas);
this.canvas = canvas;
}
this.clear();
},
canvas创建好了,接下来我们需要实现图片渲染的能力,canvas的图片渲染使用的是drawImage方法,根据官方文档,该方法有3种传参方式:
JavaScript 语法 1
在画布上定位图像:
context.drawImage(img,x,y);
JavaScript 语法 2
在画布上定位图像,并规定图像的宽度和高度:
context.drawImage(img,x,y,width,height);
JavaScript 语法 3
剪切图像,并在画布上定位被剪切的部分:
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
于是,我们也充分的判断好我们调用的drawImage参数:
addImg: function(obj, callback) {
var _self = this;
var canvas = _self.canvas;
var ctx = canvas.getContext("2d");
if (obj.hasOwnProperty('sx') && obj.hasOwnProperty('sy') && obj.hasOwnProperty('sw') && obj.hasOwnProperty('sh') && obj.hasOwnProperty('x') && obj.hasOwnProperty('y') && obj.hasOwnProperty('width') && obj.hasOwnProperty('height')) {
ctx.drawImage(_self[obj.name], obj.sx, obj.sy, obj.sw, obj.sh, obj.x, obj.y, obj.width, obj.height);
} else if (obj.hasOwnProperty('x') && obj.hasOwnProperty('y') && obj.hasOwnProperty('width') && obj.hasOwnProperty('height')) {
ctx.drawImage(_self[obj.name], obj.x, obj.y, obj.width, obj.height);
} else if (obj.hasOwnProperty('x') && obj.hasOwnProperty('y')) {
ctx.drawImage(_self[obj.name], obj.x, obj.y);
} else {
ctx.drawImage(_self[obj.name], 0, 0);
}
_self.showImg();
},
接下来我们需要开发文字生成的能力,这个比较简单,如果对canvas相关api熟悉点的,这部分没有难度:
addFont: function(obj) {
var _self = this;
var canvas = _self.canvas;
var ctx = canvas.getContext("2d");
ctx.font = obj.fontsize + "px " + obj.fontfamily; //文字的字体大小和字体系列
var ftop = obj.ftop; //文字top
var fleft = obj.fleft; //文字left
ctx.textBaseline = "top"; //设置绘制文本时的文本基线。
ctx.fillText(obj.txt, fleft, ftop);
ctx.lineWidth = 1;
ctx.fillStyle = "#000";
ctx.strokeStyle = "rgba(255,255,255,0.4)";
ctx.strokeText(obj.txt, fleft, ftop);
},
最后一步是二维码的生成,这个有点坑,自己开发肯定来不及了,我选用的是一个开源插件:qrcode,根据这个插件,我们可以在一个img中动态生成二维码的base64字串,而有了这个字串,我们也很方便的将内容输出到我们的canvas中,为了保证体验,这个插件的最外层div直接display:none,避免它干扰到我们的实际项目。
<div id="qrcode" style="display: none;"></div>
/**
*
* 初始化二维码生成插件
*
*/
var qrdata = '';
var myqr = document.querySelector('#myqr');
var qrcode = document.querySelector('#qrcode');
var qr = new QRCode(qrcode, {
width: 300,
height: 300,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.L
});
由于这个img是动态变化的,我们获取base64字串的时候一定要在该img的onload事件的回调内去获取,这点非常重要:
function buildQr () {
var img = qrcode.querySelector('img');
img.onload = function() {
qrdata = img.src;
main();
};
qr.makeCode(myqr.value);
}
ok,准备工作都完成了,接下来我们需要开始初始化我们的插件了,我预先埋下了很多可配置的参数:
var canvasImg = null;
function main() {
//初始化
canvasImg = new LCanvasImg({
cw: 768,//canvas width
ch: 1163,//canvas height
iw: '100%',//output img width
ih: 'auto',//output img height
display:'none'//canvas display
});
//资源加载
canvasImg.load([{
name: 'qr',
src: qrdata
}, {
name: 'bg',
src: '../img/bg.jpg'
}, {
name: 'z',
src: '../img/z.png'
}], build);
};
看见上面的build变量了吗?我们将图片生成逻辑全部写在这个build方法中,在load资源complete后,会执行build;
function build() {
var farr = [{
txt: document.querySelector('#mytxt1').value,
fontsize: 26,
fontfamily: 'fzjt',
ftop: 140,
fleft: 194
}, {
txt: '胡鑫',
fontsize: 26,
fontfamily: 'fzjt',
ftop: 220,
fleft: 394
}, {
txt: '邓逸昕',
fontsize: 26,
fontfamily: 'fzjt',
ftop: 220,
fleft: 294
}, {
txt: document.querySelector('#mytxt1').value,
fontsize: 26,
fontfamily: 'fzjt',
ftop: 220,
fleft: 194
}];
canvasImg.addImg({
name: 'bg',
x: 0,
y: 0,
width: 768,
height: 1163
});
farr.forEach(function(obj) {
canvasImg.addFont(obj);
});
canvasImg.addImg({
name: 'z',
x: 0,
y: 0,
width: 100,
height: 100
});
canvasImg.addImg({
name: 'z',
sx: 0,
sy: 0,
sw: 150,
sh: 150,
x: 100,
y: 100,
width: 100,
height: 100
});
canvasImg.addImg({
name: 'qr',
x: 400,
y: 800,
width: 200,
height: 200
});
};
window.onload = buildQr;
最后一句话非常重要,为什么这里我需要用window.onload事件,如果你使用的是webfont,当webfont下载成功后,其实还有一小段时间需要将font字体载入进浏览器中,只有在window.onload事件时,webfont字体文件才能生效。
最后奉上效果截图:
整个demo已经上传至github上了,如果需要做类似需求的同学可以下载该插件,可以节约大家许多时间
资源地址:https://github.com/xfhxbb/LCanvasImg
基于canvas的二维码邀请函生成插件的更多相关文章
- 【krpano】二维码自动生成插件(源码+介绍+预览)
简介 在krpano生成的全景支持HTML5在手机中展示,而在手机中打开全景网址时不方便,需要输入网址. 最近研究了如何让krpano全景根据自己当前的网址,自动生成二维码,并在电脑浏览时,可以展示出 ...
- 基于Metronic的Bootstrap开发框架经验总结(14)--条码和二维码的生成及打印处理
在很多项目里面,对条形码和二维码的生成和打印也是一种很常见的操作,在Web项目里面,我们可以利用JS生成条形码和二维码的组件有很多.本文引入两个比较广泛使用的JS组件,用来处理条形码和二维码的生成处理 ...
- Android zxing 解析二维码,生成二维码极简demo
zxing 官方的代码很多,看起来很费劲,此demo只抽取了有用的部分,实现了相机预览解码,解析本地二维码,生成二维码三个功能. 简化后的结构如下: 废话少说直接上代码: BaseDecodeHand ...
- 二维码js生成库
jr-qrcode 把字符串生成二维码,并以Base64 URL形式输出. 支持白色二维码,即反色二维码. 兼容性 插件使用了H5的canvas特性进行二维码绘制,最后输出base64 url,因此本 ...
- 基于Zxing的二维码的二维码扫描之横屏扫描
最近项目条码扫描要改为横屏,网上所搜了一下,然后发现我写的需要改动几行代码就可以了,还是很给力的. 如未查看之前的代码,请移步: 基于Zxing的二维码生成和二维码扫描 修改下面写代码就可以实现横屏条 ...
- 二维码的生成细节和原理 -- 转http://news.cnblogs.com/n/191671/
二维码又称 QR Code,QR 全称 Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的 Bar Code 条形码能存更多的信息,也能表示更多的数据类型:比如:字 ...
- 【来龙去脉系列】QRCode二维码的生成细节和原理
二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型:比如:字符,数字, ...
- Java 条形码 二维码 的生成与解析
Barcode简介 Barcode是由一组按一定编码规则排列的条,空符号,用以表示一定的字符,数字及符号组成的,一种机器可读的数据表示方式. Barcode的形式多种多样,按照它们的外观分类: Lin ...
- ios-深度解析二维码的生成与使用
利用一个小demo来对二维码进行学习,总共四个界面(主界面,生成二维码界面,识别二维码界面,扫描二维码界面) 一.二维码的介绍 1.什么是二维码? 二维条码/二维码是用某种特定的 ...
随机推荐
- STM32 USB虚拟串口(转)
源:STM32 USB虚拟串口 串口调试在项目中被使用越来越多,串口资源的紧缺也变的尤为突出.很多本本人群,更是深有体会,不准备一个USB转串口工具就没办法进行开发.本章节来简单概述STM32低端芯片 ...
- 关于JAVA中hashCode
hash code 即散列码根据对象计算出的一个整型值,散列码是没有规律的. 如果两个对象相等(equal() 返回true),则hashCode一定相等,如果两个对象hashCode相等,则对象不一 ...
- iOS强制切换横屏、竖屏
切换横竖屏最直接的方式是调用device的setOrientation方法.但是从sdk3.0以后,这个方法转为似有API,如果要上AppStore的话,要慎用! if ([[UIDevice cur ...
- 【转】实用 .htaccess 用法大全
这里收集的是各种实用的 .htaccess 代码片段,你能想到的用法几乎全在这里. 免责声明: 虽然将这些代码片段直接拷贝到你的 .htaccess 文件里,绝大多数情况下都是好用的,但也有极个别情况 ...
- 在 WindowMobile 上的模拟LED 显示屏插件(转)
源:在 WindowMobile 上的模拟LED 显示屏插件 我在给一个对话框上的控件查找翻看合适的图标时,无形中看到了一个LED显示屏的图标,这里所说的LED显示屏是指由很多LED灯密集排列组成的点 ...
- 直流电机驱动PWM频率(转)
源:直流电机驱动PWM频率 1.没有统一的标准,其实PWM的频率和你的电机感抗和你需要的速度响应时间有很大的关系.一般的电机用14K就足够了.当然自需要简单的调速可以随便选. 如果电机转速比较高,感抗 ...
- XP Mode 虛擬機器 for Windows 7
免驗證官方直接下載 官網 Download Windows Virtual PC XP Mode for Windows 7 性質 Windows 7 免費 / en 多國 繁體中文(Traditio ...
- 分布式事务 & 两阶段提交 & 三阶段提交
可以参考这篇文章: http://blog.csdn.net/whycold/article/details/47702133 两阶段提交保证了分布式事务的原子性,这些子事务要么都做,要么都不做. 而 ...
- 使用SSH搭建用户注册登录系统
[转]http://blog.sina.com.cn/s/blog_a6a6b3cd01017c57.html 什么是SSH? SSH对应 struts spring hibernatestruts ...
- C#索引器的用法
索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...