80-H5图片保存(带二维码生成)

1. 采用的js库

  1. html2canvas: 采用0.5版本
  2. qrcodejs :该库已经发布很久,需要自行添加回调事件

2. 生成二维码

  1. 由于qrcodejs没有采用模块化包装,需要自行封装
  2. 由于qrcode生成二维码没有回传一个事件,需要自行加个回调函数,请参考链接

1 封装:

1
2
3
4
5
6
7
8
9
10
11
(function(root, factory) {
if (typeof define === "function" && define) {
define(factory);
} else if (typeof exports === "object") {
//Node, CommonJS之类的
module.exports = factory();
} else {
//浏览器全局变量(root 即 window)
root.QRCode = factory();
}
})(this, function() {})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
QRCode = function(el, vOption, fn) {  // line:1472
...
};

this._oDrawing = new Drawing(this._el, this._htOption, fn); // line:1506

var svgDrawer = (function() { // line:1044
var Drawing = function(el, htOption, callback) {
this._callback = callback;
this._el = el;
this._htOption = htOption;
};

var Drawing = function(el, htOption, callback) { // line:1123
this._callback = callback;
this._el = el;
this._htOption = htOption;
};

this._callback(); // line:1174

this._callback(this._elImage.src); // line:1193

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
_self.qrcode=div2canvas.qrcode("#shop-item-share__qrcode",{
text:href,
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff"
},function(url){
// 当url有值时代表当前环境支持canvas
num++;
if(num==2){
_self.html2canvas();
}
})

3.html2canvas

3.1 参考

参考链接

html2canvas 注意有些css会影响正常生成图片,比如 flex,css3 transform

此外,html2canvas需要promise的支持,建议用 babel-pollyfill 或者 es6-promise

3.2文字叠影问题

html2canvas文字含中文括号或者其他特殊字符的时候,生成图片时会跑到下面,与下面文字重叠,通过给字符加上span标签解决

1
2
3
4
5
6
7
8
9
10
function wrap(str){
var arr=str.replace(/(.)(?=(.{2})+$)/g,'$1,').split(',');
var newStr=arr.map(function(item){
return "<span>"+item+"</span>"
}).join("")
if(str.length<17){
newStr+="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
}
return newStr;
}

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
define('module/div2canvas', function(require, exports, module){
'use strict';

require('es6-promise').polyfill();
var html2canvas=require('html2canvas');
var QRCode=require('qrcode');

var div2canvas = {
/**
* 根据window.devicePixelRatio获取像素比
*/
DPR:function(){
if (window.devicePixelRatio && window.devicePixelRatio > 1) {
return window.devicePixelRatio;
}
return 1;
},
/**
* 将传入值转为整数
*/
parseValue:function(value) {
return parseInt(value, 10);
},
/**
* 绘制canvas
*/
drawCanvas:function(selector){
var _self=this;
// 获取想要转换的 DOM 节点
var dom = document.querySelector(selector);
var box = window.getComputedStyle(dom);
// DOM 节点计算后宽高
var width = _self.parseValue(box.width);
var height = _self.parseValue(box.height);
// 获取像素比
var scaleBy = _self.DPR();
// 创建自定义 canvas 元素
var canvas = document.createElement('canvas');

// 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
canvas.width = width * scaleBy;
canvas.height = height * scaleBy;
// 设定 canvas css宽高为 DOM 节点宽高
canvas.style.width = width+'px';
canvas.style.height = height+'px';
// 获取画笔
var context = canvas.getContext('2d');

// 将所有绘制内容放大像素比倍
context.scale(scaleBy, scaleBy);

// 将自定义 canvas 作为配置项传入,开始绘制
return html2canvas(dom, {canvas:canvas});
},

/**
* 图片转base64格式
*/
img2base64:function(url,crossOrigin) {
return new Promise(function(resolve,reject){
var img = new Image();

img.onload = function() {
var c = document.createElement('canvas');

c.width = img.naturalWidth;
c.height = img.naturalHeight;

var cxt = c.getContext('2d');

cxt.drawImage(img, 0, 0);
// 得到图片的base64编码数据
resolve(c.toDataURL('image/png'));
};

crossOrigin && img.setAttribute('crossOrigin', 'Anonymous');
img.src = url;
})
},

/**
* 二维码
*/
qrcode:function(selector,option,cb){
return new QRCode(document.querySelector(selector),option,cb);
}
}

module.exports = div2canvas;
});