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

news2025/1/10 10:40:52

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

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

目录

1、npm安装

2、通过import引入

3、生成二维码

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


1、npm安装

npm install uqrcodejs
# 或者
npm install @uqrcode/js

2、通过import引入

import UQRCode from 'uqrcodejs'; // npm install uqrcodejs
// 或者
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;" />

const qr = new UQRCode();
qr.data = '二维码内容';
qr.size = 300;
qr.make();
const ctx = uni.createCanvasContext('qrcode', this); // 组件内调用需传this,vue3 中 this 为 getCurrentInstance()?.proxy
qr.canvasContext = ctx;
qr.drawCanvas();

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

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

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

4.1 定义配置信息

const config = {
  qrcodeTitle: '二维码标题',
  logo: '二维码中间logo链接',
  qrcodeTitlePosition: 'center',
  borderWidth: 10,
};

  /** 是否为标题logo */
  const isTitleLogo = config.qrcodeTitle && config.logo && config.qrcodeTitlePosition === 'center';
  /** 是否有标题 */
  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)

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

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

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

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

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

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

function textLength(str: string, index?: number) {
  let m = 0;
  const a = str.split('');
  for (let i = 0; i < a.length; i++) {
    if (a[i].charCodeAt(0) < 299)
      m++;
    else
      m += 2;
    if (index) {
      if (m == index)
        return i;
      else if (m > index)
        return i - 1;
      else if (i == a.length - 1)
        return a.length;
    }
  }
  return m;
}

4.6 绘制标题

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

4.7 绘制边框

const hasTopTitle = hasTitle && isTop;
if (qr.margin > 0) {
  ctx.beginPath();
  ctx.setFillStyle('#000');
  // 左侧border
  ctx.rect(0, hasTopTitle ? 58 : 0, config.borderWidth, 300);
  // 右侧border
  ctx.rect(300 - config.borderWidth, hasTopTitle ? 58 : 0, config.borderWidth, 300);
  // 上方border
  ctx.rect(0, hasTopTitle ? 58 : 0, 300, config.borderWidth);
  // 下方border
  ctx.rect(0, 300 - config.borderWidth + (hasTopTitle ? 58 : 0), 300, config.borderWidth);
  ctx.fill();
}

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

qr.canvasContext = ctx;
qr.drawCanvas(false)
  .then(async () => {
    // 绘制标题图片logo
    if (isTitleLogo) {
      // 绘制logo背景
      ctx.beginPath();
      ctx.setFillStyle('#fff');
      const x = 300 * 3 / 4 / 2;
      const y = x + (hasTopTitle ? 56 : 0);
      ctx.rect(x, y, 76, 76);
      ctx.fill();
      // 绘制logo文字
      ctx.setFontSize(30);
      ctx.setFillStyle('#000');
      ctx.setTextBaseline('top');
      // 绘制第1行文字
      let s = textLength(title) > 4 ? y + 14 : y + 28;
      let i = textLength(title, 4);
      const t1 = title.slice(0, i + 1);
      ctx.fillText(t1, x + (76 - textLength(t1) * 16) / 2, s);
      let t2 = title.slice(i + 1);
      // 绘制第2行文字
      if (t2.length > 0) {
        s += 68;
        i = textLength(t2, 4);
        t2 = t2.slice(0, i + 1);
        ctx.fillText(t2, x + (76 - textLength(t2) * 16) / 2, s);
      }
      ctx.draw(true, async () => {
        // 绘制完成,这里可以进行保存图片操作,如果还是太快可以setTimeout
      });
    }
    else {
      // 绘制完成,这里可以进行保存图片操作,如果还是太快可以setTimeout
    }
  });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1647498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

fabric搭建生产网络

fabric搭建生产网络 一、生成组织结构与身份证书 解包 hyperledger-fabric-linux-amd64-2.5.0.tar.gz 1.1、crypto-config.yaml配置文件 ./bin/cryptogen showtemplate > crypto-config.yaml 将crypto-config.yaml内容修改为&#xff1a; # -------------------------…

pygame实现鼠标绘制并调节画笔大小

pygame实现鼠标绘制并调节画笔大小 pygame介绍调节画笔大小鼠标绘制效果 pygame介绍 Pygame是一个开源的Python库&#xff0c;专为电子游戏开发而设计。它建立在SDL&#xff08;Simple DirectMedia Layer&#xff09;的基础上&#xff0c;允许开发者使用Python这种高级语言来实…

微信个人号开发api接口-视频号矩阵接口-VIdeosApi

友情链接&#xff1a;VIdeosApi 获取用户主页 接口地址&#xff1a; http://api.videosapi.com/finder/v2/api/finder/userPage 入参 { "appId": "{{appid}}", "lastBuffer": "", "toUserName": "v2_060000231003b2…

03、 Kafaka单机环境部署

03、 Kafka单机环境部署 1、 Docker 安装单机版本搭建 &#xff08;1&#xff09;安装Zookeeper docker pull zookeeper&#xff08;2&#xff09;启动zookeeper docker run -d --name zookeeper -p 2181:2181 zookeeper&#xff08;3&#xff09;安装 Kafka docker pull …

酷开科技线上出游,用酷开系统云逛博物馆!

五一假期&#xff0c;当全国各地的旅游景点迎来人潮高峰期时&#xff0c;酷开科技为那些寻求宁静假期体验的消费者带来了一个独特的解决方案——“云逛博物馆”。通过酷开系统&#xff0c;消费者可以在家中的电视上&#xff0c;体验维也纳艺术史博物馆的沉浸式画展&#xff0c;…

AI图书推荐:Zapier和AI融合来自动化业务流程

这本书《Zapier和AI融合来自动化业务流程》&#xff08;Automate It with Zapier and Generative AI&#xff09;由Kelly Goss撰写&#xff0c;这本书是为想要使用Zapier和AI集成功能来自动化重复性任务、提高生产力的微型、小型或中型企业的业务所有者、运营经理和团队准备的。…

抖音爆火的QQ价格评估前端源码

最近抖音很火直播给别人测qq价值多少&#xff0c;这个源码只有前端&#xff0c; 包含激活码验证页&#xff0c;评估页 源码免费下载地址抄笔记 (chaobiji.cn)

【新手入门】Github与Git使用教程

Github与Git 一、Github基础教程 1.1 基本操作 点击代码文件可以直接查看文件的内容&#xff0c;支持在线修改文件&#xff0c;只需要点击(文件内容)右上角的编辑按钮即可进行编辑。 README.md一般介绍项目的功能&#xff0c;用法&#xff0c;注意事项&#xff1b;有时还有…

【LLM第四篇】名词解释:SFT

看到京东的一段开场白&#xff0c;觉得很有道理&#xff1a; 2023年&#xff0c;大语言模型以前所未有的速度和能力改变我们对智能系统的认知&#xff0c;成为技术圈最被热议的话题。但“百模大战”终将走向“落地为王”&#xff0c;如何将大语言模型的强大能力融入实际业务、…

【Django学习笔记(八)】MySQL的数据管理

MySQL的数据管理 前言正文1、新增数据2、删除数据3、修改数据4、查询数据5、案例&#xff1a;员工管理5.1 创建表结构5.1.1 创建数据库5.1.2 创建数据表 5.2 Python操作MySQL5.2.1 pymysql 的基本操作步骤5.2.2 优化 pymysql 的基本操作步骤5.2.3 查询数据5.2.4 修改数据5.2.5 …

数据结构之栈的超详细讲解

目录 引言 一.栈的概念 二.栈的结构 三.栈的实现 栈结构的实现 栈操作函数的声明 栈中方法的实现 栈的初始化 栈的销毁 入栈 出栈 取栈顶元素 判断栈中是否为空 获取栈中数据个数 四.测试 代码展示: 结构展示: 五.小结 六.完整代码 Stack.h Stack.c text…

看Diffusion模型如何提升端到端自动驾驶的能力

文章链接&#xff1a;https://openreview.net/pdf?idyaXYQinjOA 自动驾驶领域在分割和规划模型性能方面取得了显著进展&#xff0c;这得益于大量数据集和创新的架构。然而&#xff0c;这些模型在遇到罕见子群&#xff0c;比如雨天条件时&#xff0c;往往表现不佳。获取必要的…

编程入门(六)【Linux系统基础操作二】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 &#x1f525;前言&#x1f680;文件与目录的操作命令cd change directory的缩…

RSA理解版本2

RSA原理理解 起源&#xff1a; RSA是一种公钥密码算法&#xff0c;它的名字是由它的三位开发者&#xff0c;即Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏的首字母组成的。 简介&#xff1a; RSA加密算法是一种非对称加密算法&#xff0c;在公开密钥加密和电子商业中…

JWK和JWT 学习

JWK和JWT 介绍 JWK (JSON Web Key) 和 JWT (JSON Web Token) 是现代Web应用程序中用于安全通信的两个重要概念。它们都是基于JSON的&#xff0c;并且是OAuth 2.0和OpenID Connect等协议的核心组成部分。 官方文档 JWT官方网站 JWK和JWK Set的RFC文档 JWT的RFC文档 JWK (JS…

linux内核网络源码--通知链

内核的很多子系统之间有很强的依赖性&#xff0c;其中一个子系统侦测到或者产生的事件&#xff0c;其他子系统可能都有兴趣&#xff0c;为了实现这种交互需求&#xff0c;linux使用了所谓的通知链。 本章我们将看到 通知链如何声明以及网络代码定义了哪些链 内核子系统如何向通…

Qt | QLCDNumber 类(LCD 数字),LCD 表示液晶显示屏

01、上节回顾 Qt 基础教程合集02、QLCDNumber 1、QLCDNumber 类用于显示类似于 LCD 显示屏上的字符(见右图) ​ 2、QLCDNumber 类是 QFrame 类的直接子类,因此 QLCDNumber 以使用从 QFrame 类继承而来的边框效果 3、QLCDNumber 可显示的符号有:0,1,2,3,4,5,6,7,8,…

Docker——consul的容器服务更新与发现

一、什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服务的压力承载&#xff0c;服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构&#xff0c;起初的解决手段…

OceanBase 如何实现多层面的资源隔离

OceanBase的资源隔离涵盖了多个方面&#xff0c;如物理机器间的隔离、不同租户之间的隔离、同一租户内的隔离&#xff0c;以及针对大型查询请求的隔离等。在实际应用OceanBase的过程中&#xff0c;我们经常会遇到这些操作场景或产生相关需求。这篇文章针对这些内容进行了简要的…

数据库系统原理实验报告5 | 数据查询

整理自博主本科《数据库系统原理》专业课自己完成的实验报告&#xff0c;以便各位学习数据库系统概论的小伙伴们参考、学习。 专业课本&#xff1a; ———— 本次实验使用到的图形化工具&#xff1a;Heidisql 目录 一、实验目的 二、实验内容 1.找出读者所在城市是“shangh…