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. hdu 1394 Minimum Inversion Number 【线段树求逆序数】

    之前写过树状数组的,再用线段树写一下--- #include<cstdio> #include<cstring> #include<iostream> #inclu ...

  2. C语言-实现整数倒序输出

    Action() { //实现一个3位数的倒序输出(123输出321) int n; int m=321; n=fun_mod(m,n); lr_output_message("%d&quo ...

  3. DDD中 与Dto搭配的AutoMapper插件,摘自《NET企业级应用架构设计》

    AutoMapper插件 实现了 DTO与Model的互相映射.

  4. luogu P2584 [ZJOI2006]GameZ游戏排名系统 Splay

    实在不想调了QAQ... Code: #include <cstdio> #include <algorithm> #include <cstring> #incl ...

  5. Pyhton学习——Day22

    #有缩进的代码表示局部作用域的代码#if_name_ =='_main_' # while True#先引入一个os模块import os,sys,time,json# print(os.path.d ...

  6. JAVA导出csv出现0.00E+00

    导出csv出现 0.00E+00的问题,打印其值为0E-8:这是因为数据表中无对应数据(decimal),查询结果则为 0e-8. 出现的字段是多个字段相加产生的和,所以这里调用了一个相加的方法.在相 ...

  7. Linux进程僵死原因排查思路

    常情况下脚本执行时间几秒完成,如果超过很长时间执行完成,可能是进程等待某些资源引起阻塞(假死状态). 场景:xx.perl读取文件并发送邮件 现象:执行脚本的进程僵死(卡住) 排查:ps -ef |g ...

  8. 小学生都能学会的python(文件操作)

    小学生都能学会的python(文件操作) 1. open("文件路径", mode="模式", encoding="编码") 文件的路径: ...

  9. python--(常用模块-2序列化)

    python--(常用模块-2序列化) 一.序列化: 把对象打散成bytes或者字符串. 方便存储和传输 序列化 把bytes或者字符串转换回对象. 反序列化 # dumps 序列化. 把对象转化成b ...

  10. js特效——自动滚动

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...