小程序canvas生成二维码图片踩的坑
1:生成临时图片,保证画布被加载以及渲染(即本身不可以 hidden 或是 上级元素不可以 hidden 或是 wx:if 隐藏等)
== 》 建议:因为 canvas 的组件层级(z-index)是最高的,无法通过层级改变,如自定义的弹框类似的组件总会被挡住
== 》 若不想给挡住,便要控制 canvas 隐藏(hidden 、 wx:if)
但是利用 API ctx.setGlobalAlpha = 0(只是变成不透明,视觉上给隐藏,但是还是还在,若是那位置有 tap 等事件就尴尬了)
== 》 因为我只是利用 canvas生成二维码图片, swiper 轮播等使用,必须要二维码图片。
+++++ 诸多使用把canvas生成的二维码生成图片原因原因
1:我自定义使用 alert 、confirm、message组件,因为canvas 组件由客户端native生成,改变不了层级,
所以总是总之 隐藏好麻烦,也解决不了我使用轮播使用二维码
2:官网(CSS动画对canvas无效)
tip:canvas组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。tip: 请勿在scroll-view、swiper、picker-view、movable-view中使用canvas组件。tip:css动画对canvas组件无效。bug: 避免设置过大的宽高,在安卓下会有crash的问题
解决的方法:
a:把 需要的 canvas 单独显示在屏幕外的十万八千里之外(position:fixed;top:-1000px;left:-1000px)
=》单独 单独 单独 啊 不要有父级元素(反正是用生成图片用)
注意了:保证 canvas 的 宽高与 生成二维码的宽高参数保持一致
<canvas canvas-id="QRCode-canvas-0" style="width:{{SIZE}}px;height:{{SIZE}}px;position: fixed;left: -500px; bottom: -500px;"></canvas>
b:利用插件(网上很多说明 jquery-qrcode.js插件)自己参考修改成 wx 的接口的;如 使用 wepy框架 ES6语法
import {
QRCode,
QRErrorCorrectLevel
} from './qrcode';
import wepy from 'wepy';
export default class QRCodeMixin extends wepy.mixin {
data = {
//设置画布大小
SIZE: 0,
};
async setSize(customSize = 150) {
const res = await wepy.getSystemInfoSync();
console.log('获取系统信息:*************** ', res)
//不同屏幕下canvas的适配比例;设计稿是750宽
// iphone6 => 180 px deviceWidth 375px
const scale = 375 / customSize;
const width = res.windowWidth / scale;
return parseInt(width);
};
async drawQRCode(ops = {}) {
console.time('+++++++++++ 画布绘制总耗时:');
const DEFAULT = {
render: 'canvas', //设置渲染方式 (有两种方式 table和canvas,默认是canvas)
typeNumber: 6, //计算模式
background: '#ffffff', //背景颜色
foreground: '#1A1A1A', //前景颜色
correctLevel: QRErrorCorrectLevel.H, //纠错等级 QRErrorCorrectLevel.H, =》 L 、M 、Q 、R、 H
canvasId: 'QRCode-canvas', //canvas对象 id
text: 'QR-Code' //生成二维码的内容
};
let options = Object.assign({}, DEFAULT, {
width: ops.size,//保持输入的宽高与canvas组件的宽高一致
height: ops.size
}, ops);
if (!options.canvasId || options.canvasId == '') {
throw new Error('请输入有效的画布 id !')
return false;
}
const createCanvas = async(options) => {
// create the qrcode itself
const qrcode = new QRCode(options.typeNumber, options.correctLevel);
qrcode.addData(options.text);
qrcode.make();
// get canvas context
const ctx = wx.createCanvasContext(options.canvasId);
console.log('++++++++++++++ 当前画布对象:', ctx);
// compute tileW/tileH based on options.width/options.height
const tileW = options.width / qrcode.getModuleCount();
const tileH = options.height / qrcode.getModuleCount();
//保存当前的绘图上下文
ctx.save();
// draw in the canvas
for (let row = 0; row < qrcode.getModuleCount(); row++) {
for (let col = 0; col < qrcode.getModuleCount(); col++) {
let style = qrcode.isDark(row, col) ? options.foreground : options.background;
ctx.setFillStyle(style);
let w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
let h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
}
};
//恢复之前保存的绘图上下文。
ctx.restore();
ctx.draw(true, () => {
//一定要延时一下,总是不延时,我本人的手机生成的二维码还是图片有bug
了
setTimeout(() => {
wepy.canvasToTempFilePath({
canvasId: options.canvasId,
quality: 0.9,
x: 0,
y: 0,
width: options.width,
height: options.height,
}).then(res => {
options.callback && options.callback(res.tempFilePath);
console.log('++++++++++++++++ wx.canvasToTempFilePath:', res);
});
}, 700);
);
});
};
createCanvas(options);
};
};
生成临时图片关键的一步:
ctx.draw(true, () => {
setTimeout(() => {
wepy.canvasToTempFilePath({
canvasId: options.canvasId,
quality: 0.9,
x: 0,
y: 0,
width: options.width,
height: options.height,
}).then(res => {
options.callback && options.callback(res.tempFilePath);
console.log('++++++++++++++++ wx.canvasToTempFilePath:', res);
});
}, 700);
});
不懂参考官网 API 说明:https://developers.weixin.qq.com/miniprogram/dev/api/
把混合的模块加载对应的Page 上,使用
//把二维码生成图片
const self = this;
this.drawQRCode({
text: ticketNo,
size,
callback(tempFilePath) {
//把二维码生成图片
self.QRCodeFilePath = tempFilePath;
self.$apply();
}
});
// tempFilePath 就是上面 QRCodeMixin 封装好的生成的临时图片,再用 data 接收
生成的图片:

坑1:刚开始经常遇到 andriad 机器生成图片白色的什么内容也没有(ios就正常) (因为没有在 wx.draw 后的回调调用)
坑2:控制台打印:canvas 为空 =》 就是上级或是本身给隐藏了(hidden 或是 wx:if)
坑3:生成的临时图片有时候正常有时候不正常(开发工具都正常的),真机就遇到 ,后来在 延时一下再执行 wepy.canvasToTempFilePath
坑4:轮播图本来用一个 canvas 画图并导出图片,可是有时候有bug的,有些二维码不正常的(所以我是用了三个 canvas 组件,递归执行完,很完美的图片出来,虽然用了三个看起来臃肿,本来使用 swier 触发再对应渲染的内容后再生成图片的)
<canvas canvas-id="QRCode-canvas-0" style="width:{{SIZE}}px;height:{{SIZE}}px;position: fixed;left: -500px; bottom: -500px;"></canvas>
<canvas canvas-id="QRCode-canvas-1" style="width:{{SIZE}}px;height:{{SIZE}}px;position: fixed;left: -50px; bottom: -1000px;"></canvas>
<canvas canvas-id="QRCode-canvas-2" style="width:{{SIZE}}px;height:{{SIZE}}px;position: fixed;left: -50px; bottom: -1500px;"></canvas>
生成图片
async draw(indexValidTicketList) {
const self = this;
//把二维码生成图片
self.drawQRCode({
canvasId: 'QRCode-canvas-' + self.DRAW_QRCODE_INDEX,
text: indexValidTicketList[self.DRAW_QRCODE_INDEX].ticketNo,
size: self.SIZE,
callback(tempFilePath) {
//把二维码生成图片
indexValidTicketList[self.DRAW_QRCODE_INDEX]['QRCodeFilePath'] = tempFilePath;
self.$apply();
//
self.DRAW_QRCODE_INDEX++;
//最多显示三张
if (self.DRAW_QRCODE_INDEX < indexValidTicketList.length) {
self.draw(indexValidTicketList);
} else {
self.DRAW_QRCODE_INDEX = 0;
self.$apply();
}
}
});
};
能成功生成一张图片,至于多张图片你们自己觉得合理的方法去实现,这次 用 canvas 的坑,你看到这里,这些坑你也在踩,刚好我踩过了,给你们参考,希望对你们有帮助!
小程序canvas生成二维码图片踩的坑的更多相关文章
- 微信小程序之生成二维码
最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...
- 小程序动态生成二维码,生成image图片
前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...
- 微信小程序条码、二维码生成模块
代码地址如下:http://www.demodashi.com/demo/13994.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- vue2.0生成二维码图片并且下载图片到本地兼容写法
vue生成二维码图片,这里使用的是qrcode.js 这个插件(亲测写法,兼容没有问题) 第一步,下载插件 需要注意,这里下载的是qrcodejs2 cnpm install --save qrcod ...
- JAVA生成二维码图片代码
首先需要导入 QRCode.jar 包 下载地址看这里 http://pan.baidu.com/s/1o6qRFqM import java.awt.Color;import java.awt. ...
- C# 利用QRCode生成二维码图片
网上生成二维码的组件是真多,可是真正好用的,并且生成速度很快的没几个,QRCode就是我在众多中找到的,它的生成速度快.但是网上关于它的使用说明,真的太少了,大都是千篇一律的复制粘贴.这是本要用它做了 ...
- js 生成二维码图片
1.用纯JavaScript实现的微信二维码图片生成器 QRCode.js是javascript实现二维码(QRCode)制作生成库. QRCode.js有着良好的跨浏览器兼容性(高版本使用HTML5 ...
- qrCode生成二维码图片
QRCode.js 是一个用于生成二维码图片的插件. 1.文件脚本 var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,th ...
- C#&.Net干货分享-构造QRCoderHelper生成二维码图片
不想说废话,直接源码拿去用... /// <summary> /// 二维码管理 /// </summary> public class QRCoderHel ...
随机推荐
- Unity 动画系统(Mecanim)的组成结构
三部分: Model Rigging(直译传动装置,术语翻译绑定)(连接Model与Animations) Animations
- Django中ORM之创建模型
ORM 数据库与ORM映射关系 表名 --- 类名 字段 --- 属性 表记录 --- 类示例对象 创建表(建立模型) 模型建立如下 class Book(models.Model): title = ...
- Eclipse中使用GIT将已提交到本地的文件上传至远程仓库
GIT将已提交到本地的文件上传至远程仓库: 1. 右击项目——Team——Push to Upstream,即可将已保存在本地的文件上传推至GIT远程仓库.
- python--csv文件读写
最近刚注册了kaggle账号,练习了下简单的knn算法用于手写数字识别.下载的训练和测试文本都是使用csv文件存储的,所以在此重拾下csv模块. csv文件 csv全称(Comma-Separated ...
- 《Let's Build A Simple Interpreter》之 Golang 版
一直以来对编译器/解释器等都较有兴趣.我非科班出身,当初还在大学时,只是马马虎虎看完了<编译原理>之类教材,上机非常少,对龙书之类圣经也只是浅尝辄止而已.工作至今,基本已将编译原理相关知识 ...
- [CTSC1999][网络流24题]补丁VS错误
题目:洛谷P2761.vijos P1019.codevs1239.codevs2218. 题目大意:有n个错误,m个不同的补丁. 对于一个补丁,有两个不同的字符串描述.具体如下: 如果当前错误包含第 ...
- CodeForces 362E Petya and Pipes
Petya and Pipes Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. ...
- MRv2 工作机制 、 公平调度器、MR压缩、边数据
对于节点数超过 4000 的大型集群,前一节描述的 MapReduce 系统开始面临着扩展的瓶颈. 2010 年 Yahoo 的团队开始设计下一代的 MapReduce. (Yet Another R ...
- maven这些工具负责创建项目,然后maven负责打包好war包扔进tomcat容器,tomcat容器接受的只是jar包
maven这些工具负责创建项目,然后maven负责打包好war包扔进tomcat容器,tomcat容器接受的只是jar包 2.tomcat不管你什么编译的,也不管你开发工具是什么.Tomcat只接受w ...
- ZOJ 3329
方程很明显有 d[i]=sum(pk*d[i+k])+p0*d[0]; 其中pi可以在开始时枚举求出. 设d[i]=A[i]*d[0]+B[i], 代入上式 d[i]=(sum(pk*A[i+k])+ ...