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安装

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++;elsem += 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');// 左侧borderctx.rect(0, hasTopTitle ? 58 : 0, config.borderWidth, 300);// 右侧borderctx.rect(300 - config.borderWidth, hasTopTitle ? 58 : 0, config.borderWidth, 300);// 上方borderctx.rect(0, hasTopTitle ? 58 : 0, 300, config.borderWidth);// 下方borderctx.rect(0, 300 - config.borderWidth + (hasTopTitle ? 58 : 0), 300, config.borderWidth);ctx.fill();
}

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

qr.canvasContext = ctx;
qr.drawCanvas(false).then(async () => {// 绘制标题图片logoif (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.mzph.cn/diannao/7296.shtml

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

相关文章

华为热题总结(1)

200&#xff0c;924&#xff0c;739&#xff0c;179&#xff0c;1&#xff0c;20&#xff0c;93 200. 岛屿数量 中等 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&a…

Springboot集成Mybatispuls操作mysql数据库-03

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

土壤重金属含量分布、Cd镉含量、Cr、Pb、Cu、Zn、As和Hg、土壤采样点、土壤类型分布

土壤是人类赖以生存和发展的重要资源之一,也是陆地生态系统重要的组成部分。近年来, 随着我国城市化进程加快&#xff0c;矿产资源开发、金属加工冶炼、化工生产、污水灌溉以及不合理的化肥农药施用等因素导致重金属在农田土壤中不断富集。重金属作为土壤环境中一种具有潜在危害…

练习题(2024/5/6)

1路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], target…

vue3 axios数据请求封装

准备工作 vue3jsvite 首先确认package.json中有axios 如果没有 运行 npm install axios 安装axios 成功后在package.json文件会显示。 第一步 创建app.js、request.js 两个文件在同级目录下即可 api.js import instance from "./request"; const api_name "&qu…

前端小案例

案例一: 在 onLoad 函数中&#xff0c;首先通过 wx.getStorageSync(userInfo) 获取用户信息&#xff0c;如果用户信息存在&#xff0c;则从中提取用户ID&#xff0c;并将其存储在页面数据中&#xff0c;以便后续使用。如果用户信息不存在&#xff0c;你可以根据实际需求进行相…

linux安装 mysql

环境&#xff1a;centOS8 一、安装 1 安装wget库 sudo yum -y install wget 2. 安装 mysql 换yum源 亲测成功&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 换yum源 1.下载对应版本的repo文件 wget -O CentOS-Base.repo http://mirrors…

watch侦听器

在 Vue.js 中&#xff0c;watch 侦听器用于观察和响应 Vue 实例上的数据变动。当你想在数据变化时执行异步或开销较大的操作时&#xff0c;这个方式是最有用的。与计算属性不同&#xff0c;watch 侦听器允许你执行更复杂的逻辑&#xff0c;包括异步操作&#xff0c;并且只有当观…

C#编程模式之外观模式

创作背景&#xff1a;给位伙伴&#xff0c;五一小长假结束&#xff0c;我们继续对C#编程之路进行探索。本文将继续编程模式的研究&#xff0c;主要介绍外观模式。外观模式也称为门面模式&#xff0c;是一种结构型设计模式&#xff0c;它的目的是为子系统中的一组接口提供一个统…

力扣每日一练(螺旋矩阵)

54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,…

centos 8.2 安装配置 vsftpd 虚拟用户访问

1安装vsftp yum install vsftpd -y 2安装db5 wget https://github.com/berkeleydb/libdb/releases/download/v5.3.28/db-5.3.28.tar.gz . tar zxvf db-5.3.28.tar.gz cd db-5.3.28/build_unix/ ../dist/configure -prefix/usr/local Make Make install3建用户等 useradd…

ESCI3罗德与施瓦茨ESCI3测试接收机

181/2461/8938产品概述&#xff1a; R&S ESCI接收机的特点包括: 出色表现 多达10个子范围的可编程扫描表自动或交互式预览和最终EMI测量的内部测试程序预扫描、数据缩减&#xff08;峰列表&#xff09;和最终测量的评估功能光谱分析仪快速ACP测量时域分析&#xff08;记…

Linux内核--设备驱动(六)媒体驱动框架整理(2)--视频

目录 一、引言 二、V4L2 ------>2.1、主要结构体 ------------>2.2.1、video_device ------------>2.2.2、v4l2_device ------------>2.2.3、v4l2_subdev ------>2.2、流程 ------>2.3、驱动实例 ------>2.4、V4L2的ioctl类型 ------------>…

Unity射击游戏开发教程:(11)制造敌人爆炸

增加爆炸效果 爆炸一切都变得更好!尤其是当你消灭敌人时。在这篇文章中,我将讨论如何在敌人被击中时为其添加爆炸动画。 在敌人的预制件中,您将需要创建一个新的动画。查看控制动画的动画器,默认情况下将从进入动画到敌人爆炸动画。这意味着,一旦敌人被实例化,敌人爆炸…

【Git】【MacOS】Github从创建与生成SSH公钥

创建账号 这一步不过多赘述&#xff0c;根据自己的邮箱新创建一个账号 配置SSH公钥 本人是macOS系统&#xff0c;首先从终端输入 cd ~/.ssh进入.ssh目录,然后通过 ls查看有没有一个叫做id_rsa.pub的文件 本人之前生成过SSH公钥,如果没有的话&#xff0c;通过 ssh-keygen -t…

vue 金额组件,输入提示单位:‘千’、‘万’、‘十万’...并用‘,’三个格式化

近期项目中遇到一个需求&#xff0c;金额输入框&#xff0c;输入过程中自动提示‘千’、‘万’、‘十万’、‘百万’......等单位提示&#xff0c;鼠标失去焦点后&#xff0c;并用‘,’三位隔开计数。 例如&#xff1a; 输入&#xff1a;12345.99 失去焦点&#xff1a;12,34…

Unit3

&#x1f4e3;Unit3 ✨1. capt&#xff0c;cept&#xff0c;ceive 抓&#xff0c;收 capture captain capable capability accept be accepted as acceptance acceptable unacceptable conceive conceive of sth concept conception except nothing expect exception …

科技云报道:从亚运到奥运,大型国际赛事共赴“云端”

科技云报道原创。 “广播电视转播技术拯救了奥运会”前奥委会主席萨马兰奇这句话广为流传。 奥运会、世界杯、亚运会这样的全球大型体育赛事不仅是体育竞技的盛宴&#xff0c;也是商业盛宴&#xff0c;还是技术与人文的融合秀。随着科技的进步&#xff0c;技术在体育赛事中扮…

vue中怎样清除computed的缓存

vue中computed计算属性自带缓存&#xff0c;会提高程序的渲染性能&#xff0c;但根据业务需求以及相应的优化&#xff0c;可能要清除computed的缓存&#xff0c;具体方法和场景分为了vue2和vue3 vue2&#xff1a; this.$delete(this.someObject, cachedProperty); 使用 this…

嵌入式交叉编译:x265

下载 multicoreware / x265_git / Downloads — Bitbucket 解压编译 BUILD_DIR${HOME}/build_libs CROSS_NAMEaarch64-mix210-linuxcd build/aarch64-linuxmake cleancmake \-G "Unix Makefiles" \-DCMAKE_C_COMPILER${CROSS_NAME}-gcc \-DCMAKE_CXX_COMPILER${CR…