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无效)

  •  tipcanvas 组件是由客户端创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。
  •  tip: 请勿在 scroll-viewswiperpicker-viewmovable-view 中使用 canvas 组件。
  •  tipcss 动画对 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生成二维码图片踩的坑的更多相关文章

  1. 微信小程序之生成二维码

    最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...

  2. 小程序动态生成二维码,生成image图片

    前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...

  3. 微信小程序条码、二维码生成模块

    代码地址如下:http://www.demodashi.com/demo/13994.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  4. vue2.0生成二维码图片并且下载图片到本地兼容写法

    vue生成二维码图片,这里使用的是qrcode.js 这个插件(亲测写法,兼容没有问题) 第一步,下载插件 需要注意,这里下载的是qrcodejs2 cnpm install --save qrcod ...

  5. JAVA生成二维码图片代码

    首先需要导入 QRCode.jar 包 下载地址看这里   http://pan.baidu.com/s/1o6qRFqM import java.awt.Color;import java.awt. ...

  6. C# 利用QRCode生成二维码图片

    网上生成二维码的组件是真多,可是真正好用的,并且生成速度很快的没几个,QRCode就是我在众多中找到的,它的生成速度快.但是网上关于它的使用说明,真的太少了,大都是千篇一律的复制粘贴.这是本要用它做了 ...

  7. js 生成二维码图片

    1.用纯JavaScript实现的微信二维码图片生成器 QRCode.js是javascript实现二维码(QRCode)制作生成库. QRCode.js有着良好的跨浏览器兼容性(高版本使用HTML5 ...

  8. qrCode生成二维码图片

    QRCode.js 是一个用于生成二维码图片的插件. 1.文件脚本 var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,th ...

  9. C#&.Net干货分享-构造QRCoderHelper生成二维码图片

    不想说废话,直接源码拿去用... /// <summary>    /// 二维码管理    /// </summary>    public class QRCoderHel ...

随机推荐

  1. Constants and Variables

    1.定义 Constants :程序编译的时候就已经存在且在程序生命周期内不会改变的值. Variables:变量本身被用来存储特定类型的数据,可以根据需要随时改变变量中所存储的数据值.每个变量都有一 ...

  2. IOS - PDF合并

    #pragma mark - Merge PDF - (void)mergePDF { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSD ...

  3. markdown图片设置

    工具:typora 1. 设置图片大小(本节引用自 https://support.typora.io/Resize-Image/) Typora允许使用<img>标签显示图像,也可用于调 ...

  4. php中mysqli 处理查询结果集总结

    在PHP开发中,我们经常会与数据库打交道.我们都知道,一般的数据处理操作流程为 接收表单数据 数据入库 //连接数据库 $link = mysqli_connect("my_host&quo ...

  5. crm 系统项目(三) 业务

    1. 项目背景 crm系统是某教育平台正在使用的项目,系统主要为 销售部.运营部.教质部门提供管理平台,随着公司规模的扩展,对公司员工的业务信息量化以及信息化建设越来越重要. crm系统为不同角色的用 ...

  6. 2015 Multi-University Training Contest 7 hdu 5379 Mahjong tree

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  7. ASP.NET-SOAP、UDDI知识点

    1. 什么是SOAP? 答:是简单访问协议.是在分布式环境中,交换信息并实现远程调用的协议.是一个基于XML的协议.使用SOAP,可以不考虑任何传输协议,但通常还是HTTP协议,可以允许任何类型的对象 ...

  8. 字符串的HashCode可能相同

    字符串的HashCode可能相同 学习了:http://blog.csdn.net/hl_java/article/details/71511815

  9. HDUOj 看病要排队 优先队列的使用 题目1873

    STL优先队列的具体描写叙述 http://blog.csdn.net/yueloveme/article/details/47106639 题目地址:http://acm.hdu.edu.cn/s ...

  10. 怎样訪问pcie整个4k的配置空间

    眼下用于訪问PCIe配置空间寄存器的方法须要追溯到原始的PCI规范. 为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,这样的方法能够訪 ...