当前位置:   article > 正文

uniapp生成二维码(uQRCode)与自定义绘制样式与内容

uniapp生成二维码(uQRCode)与自定义绘制样式与内容

二维码生成使用了一款基于Javascript环境开发的插件  uQRCode ,它不仅适用于uniapp,也适用于所有Javascript运行环境的前端应用和Node.js。

uQRCode 插件地址:https://ext.dcloud.net.cn/plugin?id=1287

目录

1、npm安装

2、通过import引入

3、生成二维码

4、自定义绘制样式与内容


1、npm安装

  1. npm install uqrcodejs
  2. # 或者
  3. npm install @uqrcode/js

2、通过import引入

  1. import UQRCode from 'uqrcodejs'; // npm install uqrcodejs
  2. // 或者
  3. import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js

3、生成二维码

如果只是生成二维码的话实现也特别简单,在template中加入canvas组件,并在script中创建UQRCode对象配置参数调用绘制方法即可。

<canvas id="qrcode" canvas-id="qrcode" style="width: 300px;height:300px;" />
  1. const qr = new UQRCode();
  2. qr.data = '二维码内容';
  3. qr.size = 300;
  4. qr.make();
  5. const ctx = uni.createCanvasContext('qrcode', this); // 组件内调用需传this,vue3 中 this 为 getCurrentInstance()?.proxy
  6. qr.canvasContext = ctx;
  7. qr.drawCanvas();

当然,除绘制简单的黑白块二维码外,UQRCode还支持定制块颜色、背景颜色、块形状、块之间的间距等,可绘制出各种花里胡哨的二维码,具体用法可查阅官方文档,本文不做阐述,

4、自定义绘制样式与内容

原本是可以先通过UQRCode插件把二维码生成并保存为图片,再绘制到新的画布上,但考虑到绘制时长和性能问题,我还是更想直接在二维码的画布上进行绘制。

4.1 定义配置信息

  1. const config = {
  2. qrcodeTitle: '二维码标题',
  3. logo: '二维码中间logo链接',
  4. qrcodeTitlePosition: 'center',
  5. borderWidth: 10,
  6. };
  7. /** 是否为标题logo */
  8. const isTitleLogo = config.qrcodeTitle && config.logo && config.qrcodeTitlePosition === 'center';
  9. /** 是否有标题 */
  10. const hasTitle = config.qrcodeTitle && ['top', 'bottom'].includes(config.qrcodeTitlePosition);

其中borderWidth为边框宽度,qrcodeTitlePosition为二维码标题位置

qrcodeTitlePosition

枚举值

效果条件
center标题在二维码中间当logo为空且qrcodeTitle有值时,会将qrcodeTitle的内容生成为白底黑字的图片绘制在二维码中间。
top标题在二维码上方当qrcodeTitle有值时,会将qrcodeTitle的内容绘制在二维码上方。
bottom标题在二维码上方当qrcodeTitle有值时,会将qrcodeTitle的内容绘制在二维码下方。

4.2 初始配置:指定二维码内容和大小,将areaColor=''由自己绘制二维码背景,且在qr.make()之前设置margin留出绘制边框的空间,预留空间包含边框宽度(borderWidth)和边框与二维码的间距(示例为10)

  1. const qr = new UQRCode();
  2. qr.data = '二维码内容';
  3. qr.size = 300;
  4. qr.areaColor = ''; // 不绘制背景,否则会覆盖边框或文本
  5. qr.drawReserve = true; // 保留绘制,本次绘制是否接着上一次绘制。是二维码绘制完是否还能上此基础上绘制的关键
  6. if (config.borderWidth > 0)
  7. qr.margin = config.borderWidth + 10;
  8. qr.make();

4.3 绘制logo:如果二维码中间需要绘制logo,UQRCode是支持设置logo的,无需自己绘制。

  1. if (config.logo)
  2. qr.foregroundImageSrc = config.logo; // 网络图片需先下载下来

4.4 绘制二维码背景:如果二维码上下方有标题则需要高度需要留出空间来绘制(示例用 hasTitleDraw 来判断上下方是否有标题需绘制)

  1. const ctx = uni.createCanvasContext('qrcode', this); // 组件内调用需传this,vue3 中 this 为 getCurrentInstance()?.proxy
  2. const hasTitleDraw = !isTitleLogo && hasTitle;
  3. ctx.setFillStyle('#fff');
  4. ctx.rect(0, 0, 300, hasTitleDraw ? 356 : 300);
  5. ctx.fill();

4.5 计算字符占用长度:用来计算每行绘制的文字个数

  1. function textLength(str: string, index?: number) {
  2. let m = 0;
  3. const a = str.split('');
  4. for (let i = 0; i < a.length; i++) {
  5. if (a[i].charCodeAt(0) < 299)
  6. m++;
  7. else
  8. m += 2;
  9. if (index) {
  10. if (m == index)
  11. return i;
  12. else if (m > index)
  13. return i - 1;
  14. else if (i == a.length - 1)
  15. return a.length;
  16. }
  17. }
  18. return m;
  19. }

4.6 绘制标题

  1. const isTop = config.qrcodeTitlePosition === 'top';
  2. const title = config.qrcodeTitle;
  3. if (hasTitleDraw) {
  4. ctx.setFontSize(30);
  5. ctx.setFillStyle('#000');
  6. ctx.setTextBaseline('top');
  7. ctx.fillText(
  8. title,
  9. Math.max(300 - textLength(title) * 16) / 2, 0),
  10. isTop ? 16 : 316,
  11. );
  12. if (isTop) { // 标题在二维码上方,整个二维码向下偏移
  13. qr.getDrawModules().forEach((item) => {
  14. item.y += 56;
  15. });
  16. }
  17. }

4.7 绘制边框

  1. const hasTopTitle = hasTitle && isTop;
  2. if (qr.margin > 0) {
  3. ctx.beginPath();
  4. ctx.setFillStyle('#000');
  5. // 左侧border
  6. ctx.rect(0, hasTopTitle ? 58 : 0, config.borderWidth, 300);
  7. // 右侧border
  8. ctx.rect(300 - config.borderWidth, hasTopTitle ? 58 : 0, config.borderWidth, 300);
  9. // 上方border
  10. ctx.rect(0, hasTopTitle ? 58 : 0, 300, config.borderWidth);
  11. // 下方border
  12. ctx.rect(0, 300 - config.borderWidth + (hasTopTitle ? 58 : 0), 300, config.borderWidth);
  13. ctx.fill();
  14. }

4.8 绘制二维码中间的标题logo

  1. qr.canvasContext = ctx;
  2. qr.drawCanvas(false)
  3. .then(async () => {
  4. // 绘制标题图片logo
  5. if (isTitleLogo) {
  6. // 绘制logo背景
  7. ctx.beginPath();
  8. ctx.setFillStyle('#fff');
  9. const x = 300 * 3 / 4 / 2;
  10. const y = x + (hasTopTitle ? 56 : 0);
  11. ctx.rect(x, y, 76, 76);
  12. ctx.fill();
  13. // 绘制logo文字
  14. ctx.setFontSize(30);
  15. ctx.setFillStyle('#000');
  16. ctx.setTextBaseline('top');
  17. // 绘制第1行文字
  18. let s = textLength(title) > 4 ? y + 14 : y + 28;
  19. let i = textLength(title, 4);
  20. const t1 = title.slice(0, i + 1);
  21. ctx.fillText(t1, x + (76 - textLength(t1) * 16) / 2, s);
  22. let t2 = title.slice(i + 1);
  23. // 绘制第2行文字
  24. if (t2.length > 0) {
  25. s += 68;
  26. i = textLength(t2, 4);
  27. t2 = t2.slice(0, i + 1);
  28. ctx.fillText(t2, x + (76 - textLength(t2) * 16) / 2, s);
  29. }
  30. ctx.draw(true, async () => {
  31. // 绘制完成,这里可以进行保存图片操作,如果还是太快可以setTimeout
  32. });
  33. }
  34. else {
  35. // 绘制完成,这里可以进行保存图片操作,如果还是太快可以setTimeout
  36. }
  37. });

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/552629
推荐阅读