1
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
import { GenerateFrameResult, XQrcoderProps } from "./interface.uts"
|
||||
import { generateFrame } from "./qrcode.uts"
|
||||
|
||||
// 绘制圆形定位点模式的函数
|
||||
function drawRoundedPositionPattern(ctx: CanvasRenderingContext2D, x: number, y: number, px: number, pdColor: string, bgColor: string) {
|
||||
// 外层黑色圆形 (7x7)
|
||||
ctx.fillStyle = pdColor
|
||||
ctx.beginPath()
|
||||
ctx.arc(x + px * 3.5, y + px * 3.5, px * 3.5, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
|
||||
// 中层白色圆形 (5x5)
|
||||
ctx.fillStyle = bgColor
|
||||
ctx.beginPath()
|
||||
ctx.arc(x + px * 3.5, y + px * 3.5, px * 2.5, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
|
||||
// 内层黑色圆形 (3x3)
|
||||
ctx.fillStyle = pdColor
|
||||
ctx.beginPath()
|
||||
ctx.arc(x + px * 3.5, y + px * 3.5, px * 1.5, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
}
|
||||
|
||||
// 绘制星形图案的函数
|
||||
function drawStar(ctx: CanvasRenderingContext2D, x: number, y: number, px: number) {
|
||||
const centerX = x + px / 2
|
||||
const centerY = y + px / 2
|
||||
const outerRadius = px * 0.4 // 外圆半径
|
||||
const innerRadius = px * 0.15 // 内圆半径
|
||||
const spikes = 4 // 四个尖角
|
||||
|
||||
ctx.beginPath()
|
||||
|
||||
for (let i = 0; i < spikes * 2; i++) {
|
||||
const angle = (i * Math.PI) / spikes
|
||||
const radius = i % 2 === 0 ? outerRadius : innerRadius
|
||||
const starX = centerX + Math.cos(angle) * radius
|
||||
const starY = centerY + Math.sin(angle) * radius
|
||||
|
||||
if (i === 0) {
|
||||
ctx.moveTo(starX, starY)
|
||||
} else {
|
||||
ctx.lineTo(starX, starY)
|
||||
}
|
||||
}
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
// 兼容的圆角矩形绘制函数
|
||||
function drawRoundedRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) {
|
||||
ctx.beginPath()
|
||||
|
||||
// 如果圆角半径太大,限制为宽度或高度的一半
|
||||
const maxRadius = Math.min(width, height) / 2
|
||||
radius = Math.min(radius, maxRadius)
|
||||
|
||||
// 绘制圆角矩形路径
|
||||
ctx.moveTo(x + radius, y)
|
||||
ctx.lineTo(x + width - radius, y)
|
||||
ctx.arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0)
|
||||
ctx.lineTo(x + width, y + height - radius)
|
||||
ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2)
|
||||
ctx.lineTo(x + radius, y + height)
|
||||
ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI)
|
||||
ctx.lineTo(x, y + radius)
|
||||
ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2)
|
||||
ctx.closePath()
|
||||
}
|
||||
|
||||
export function drawQrcode(opts : XQrcoderProps, img : any | null = null) {
|
||||
let fo = generateFrame(opts.text, opts.ecc)
|
||||
let points = fo.frameBuffer
|
||||
let width = fo.width
|
||||
let px = opts.size / width
|
||||
let borderWidth = 0
|
||||
const ctx = opts.ctx;
|
||||
|
||||
// 绘制背景
|
||||
ctx.fillStyle = opts.background
|
||||
ctx.fillRect(0, 0, opts.size, opts.size)
|
||||
|
||||
// 判断是否是定位点的函数
|
||||
function isPositionDetectionPattern(i : number, j : number, width : number) : boolean {
|
||||
// 左上角
|
||||
if (i < 7 && j < 7) return true;
|
||||
// 右上角
|
||||
if (i > width - 8 && j < 7) return true;
|
||||
// 左下角
|
||||
if (i < 7 && j > width - 8) return true;
|
||||
return false;
|
||||
}
|
||||
let dot = px * 0.1
|
||||
let pdColor = opts?.pdColor??opts.foreground
|
||||
|
||||
// 先绘制定位点区域(如果需要圆角)
|
||||
if ((opts?.pdRounded??false)) {
|
||||
// 绘制三个定位点的同心圆角矩形结构
|
||||
// 左上角
|
||||
drawRoundedPositionPattern(ctx, borderWidth, borderWidth, px, pdColor, opts.background)
|
||||
|
||||
// 右上角
|
||||
drawRoundedPositionPattern(ctx, borderWidth + px * (width - 7), borderWidth, px, pdColor, opts.background)
|
||||
|
||||
// 左下角
|
||||
drawRoundedPositionPattern(ctx, borderWidth, borderWidth + px * (width - 7), px, pdColor, opts.background)
|
||||
}
|
||||
|
||||
for (let i = 0; i < width; i++) {
|
||||
for (let j = 0; j < width; j++) {
|
||||
if (points[j * width + i] > 0) {
|
||||
// 设置颜色,如果是定位点则使用pdColor,否则使用foreground
|
||||
const isPostion = isPositionDetectionPattern(i, j, width);
|
||||
ctx.fillStyle = opts.foreground;
|
||||
|
||||
if (isPostion) {
|
||||
// 如果启用了圆角,定位点区域已经整体绘制过了,跳过单个方块的绘制
|
||||
if (!(opts?.pdRounded??false)) {
|
||||
ctx.fillStyle = pdColor
|
||||
ctx.fillRect(borderWidth + px * i, borderWidth + px * j, px, px)
|
||||
}
|
||||
} else {
|
||||
if (opts.mode == 'line') {
|
||||
ctx.fillRect(borderWidth + px * i, borderWidth + px * j, px, px / 2)
|
||||
} else if (opts.mode == 'circular') {
|
||||
ctx.beginPath()
|
||||
let rx = borderWidth + px * i + px / 2 - dot
|
||||
let ry = borderWidth + px * j + px / 2 - dot
|
||||
ctx.arc(rx, ry, px / 2 - dot, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
} else if (opts.mode == 'rectSmall') {
|
||||
|
||||
ctx.fillRect(borderWidth + px * i + dot, borderWidth + px * j + dot, px - dot*2, px - dot*2)
|
||||
} else if (opts.mode == 'xing') {
|
||||
// 绘制星形
|
||||
drawStar(ctx, borderWidth + px * i, borderWidth + px * j, px)
|
||||
} else if (opts.mode == 'vertical') {
|
||||
continue
|
||||
} else {
|
||||
ctx.fillRect(borderWidth + px * i, borderWidth + px * j, px, px)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 对于vertical模式,需要特殊处理垂直方向的连续点
|
||||
if (opts.mode == 'vertical') {
|
||||
// 创建已处理标记数组
|
||||
let processed:boolean[] = [] as boolean[]
|
||||
for(let km=0;km<width * width;km++){
|
||||
processed.push(false)
|
||||
}
|
||||
for (let i = 0; i < width; i++) {
|
||||
for (let j = 0; j < width; j++) {
|
||||
let index = j * width + i
|
||||
if (points[index] > 0 && !processed[index]) {
|
||||
const isPostion = isPositionDetectionPattern(i, j, width);
|
||||
|
||||
if (isPostion) {
|
||||
// 定位点跳过,已经处理过了
|
||||
continue
|
||||
}
|
||||
|
||||
// 分析垂直方向的连续点
|
||||
let verticalLength = 1
|
||||
let startJ = j
|
||||
|
||||
// 向上查找连续点
|
||||
while (startJ > 0 && points[(startJ - 1) * width + i] > 0 &&
|
||||
!isPositionDetectionPattern(i, startJ - 1, width)) {
|
||||
startJ--
|
||||
verticalLength++
|
||||
}
|
||||
|
||||
// 向下查找连续点
|
||||
let endJ = j
|
||||
while (endJ < width - 1 && points[(endJ + 1) * width + i] > 0 &&
|
||||
!isPositionDetectionPattern(i, endJ + 1, width)) {
|
||||
endJ++
|
||||
verticalLength++
|
||||
}
|
||||
|
||||
// 标记这些点为已处理
|
||||
for (let k = startJ; k <= endJ; k++) {
|
||||
processed[k * width + i] = true
|
||||
}
|
||||
|
||||
// 根据长度决定绘制方式
|
||||
ctx.fillStyle = opts.foreground
|
||||
|
||||
if (verticalLength == 1) {
|
||||
// 单个点:绘制圆点
|
||||
ctx.beginPath()
|
||||
let centerX = borderWidth + px * i + px / 2
|
||||
let centerY = borderWidth + px * j + px / 2
|
||||
ctx.arc(centerX, centerY, px * 0.25, 0, 2 * Math.PI) // 稍微减小圆点半径
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
} else if (verticalLength <= 3) {
|
||||
// 2-3个点:绘制连续线条
|
||||
let x = borderWidth + px * i + px / 2
|
||||
let y = borderWidth + px * startJ + px * 0.2 // 减少上下间距
|
||||
let lineWidth = px * 0.5 // 减少线条宽度
|
||||
let lineHeight = px * (endJ - startJ + 1) * 0.8 // 增加线条高度
|
||||
// 圆角半径适中,不完全半圆
|
||||
let radius = px * 0.5
|
||||
drawRoundedRect(ctx, x - lineWidth / 2, y, lineWidth, lineHeight, radius)
|
||||
ctx.fill()
|
||||
} else {
|
||||
// 超过3个点:分段绘制,每3个点一段
|
||||
let segments = Math.ceil(verticalLength / 3)
|
||||
for (let seg = 0; seg < segments; seg++) {
|
||||
let segStart = startJ + seg * 3
|
||||
let segEnd = Math.min(startJ + (seg + 1) * 3 - 1, endJ)
|
||||
let segLength = segEnd - segStart + 1
|
||||
|
||||
let x = borderWidth + px * i + px / 2
|
||||
let y = borderWidth + px * segStart + px * 0.2 // 减少上下间距
|
||||
let lineWidth = px * 0.5 // 减少线条宽度
|
||||
let lineHeight = px * segLength * 0.8 // 增加线条高度
|
||||
// 圆角半径适中,不完全半圆
|
||||
let radius = px * 0.5
|
||||
drawRoundedRect(ctx, x - lineWidth / 2, y, lineWidth, lineHeight, radius)
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.logo != '') {
|
||||
// #ifdef APP-ANDROID||APP-IOS||WEB
|
||||
let images = new Image(opts.logoSize, opts.logoSize)
|
||||
images.src = opts.logo
|
||||
console.log(opts.logo)
|
||||
images.onload = () => {
|
||||
|
||||
uni.getImageInfo({
|
||||
src: opts.logo,
|
||||
success: (res) => {
|
||||
ctx.save()
|
||||
ctx.fillStyle = opts.logoBgColor
|
||||
let centerx = (opts.size - opts.logoSize) / 2;
|
||||
ctx.fillRect(centerx, centerx, opts.logoSize, opts.logoSize)
|
||||
ctx.drawImage(images, 0, 0, res.width, res.height, centerx + 3, centerx + 3, opts.logoSize - 6, opts.logoSize - 6)
|
||||
ctx.restore()
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN||APP-HARMONY
|
||||
img.src = opts.logo
|
||||
img.onload = () => {
|
||||
uni.getImageInfo({
|
||||
src: opts.logo,
|
||||
success: (res) => {
|
||||
ctx.save()
|
||||
ctx.fillStyle = opts.logoBgColor
|
||||
let centerx = (opts.size - opts.logoSize) / 2;
|
||||
ctx.fillRect(centerx, centerx, opts.logoSize, opts.logoSize)
|
||||
|
||||
// #ifdef MP
|
||||
ctx.drawImage(
|
||||
img,
|
||||
0,
|
||||
0,
|
||||
res.width,
|
||||
res.height,
|
||||
centerx + 3,
|
||||
centerx + 3,
|
||||
opts.logoSize - 6,
|
||||
opts.logoSize - 6
|
||||
)
|
||||
// #endif
|
||||
// #ifdef APP-HARMONY
|
||||
let dpr = uni.getWindowInfo().pixelRatio
|
||||
ctx.drawImage(
|
||||
img,
|
||||
centerx + 3,
|
||||
centerx + 3,
|
||||
opts.logoSize - 6,
|
||||
opts.logoSize - 6
|
||||
)
|
||||
// #endif
|
||||
ctx.restore()
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
export type GenerateFrameResult = {
|
||||
frameBuffer: number[],
|
||||
width: number
|
||||
}
|
||||
export type XQrcoderProps = {
|
||||
ctx: CanvasRenderingContext2D,
|
||||
/**
|
||||
* 容错等级
|
||||
*/
|
||||
ecc:string,
|
||||
/**
|
||||
* 二维码内容
|
||||
*/
|
||||
text: string,
|
||||
/**
|
||||
* 二维码大小
|
||||
*/
|
||||
size: number,
|
||||
/**
|
||||
* 二维码前景色
|
||||
*/
|
||||
foreground: string,
|
||||
/**
|
||||
* 二维码背景色
|
||||
*/
|
||||
background: string,
|
||||
padding: number,
|
||||
/**
|
||||
* 二维码logo
|
||||
*/
|
||||
logo: string,
|
||||
/**
|
||||
* 二维码logo的背景色
|
||||
*/
|
||||
logoBgColor:string,
|
||||
/**
|
||||
* 二维码logo大小
|
||||
*/
|
||||
logoSize: number,
|
||||
/**
|
||||
* 绘制的样式目前提供
|
||||
* rect :普通码矩形
|
||||
* circular :小圆点
|
||||
* line :横向线条
|
||||
* rectSmall :小方格
|
||||
* xing :星形
|
||||
* vertical :竖向线条带圆角
|
||||
*/
|
||||
mode:String,
|
||||
/**
|
||||
* 定位点的颜色
|
||||
*/
|
||||
pdColor?: string,
|
||||
/**
|
||||
* 定位点是否使用圆角
|
||||
*/
|
||||
pdRounded?: boolean
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,361 @@
|
||||
<script lang="ts">
|
||||
import { type PropType } from "vue"
|
||||
import { getUid, rpx2px } from "../../core/util/xCoreUtil.uts"
|
||||
import { getDefaultColor } from "../../core/util/xCoreColorUtil.uts"
|
||||
import { checkIsCssUnit } from "../../core/util/xCoreUtil.uts"
|
||||
import { xConfig } from "../../config/xConfig.uts"
|
||||
import {drawQrcode} from "./drawQrcoder.uts"
|
||||
import {XQrcoderProps} from "./interface.uts"
|
||||
import { toPngFile } from "@/uni_modules/x-base642file-s"
|
||||
|
||||
type DATATYP = {
|
||||
action : string
|
||||
}
|
||||
/**
|
||||
* @name 二维码 xQrcoder
|
||||
* @description 本组件使用UTS原生代码绘制,性能非常高,如果你是在1.1.9之前版本请使用x-qrcoder-s原生插件获得高性能。从1.1.9版本后请
|
||||
* 使用组件绘制QR码来获得更高性能和更多样式配置。
|
||||
* @page /pages/index/qrcoder
|
||||
* @category 其它组件
|
||||
* @constant 平台兼容
|
||||
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
|
||||
*/
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
id: ("xQrcode-" + getUid()) as string,
|
||||
id2: ("xQrcode1" + getUid()) as string,
|
||||
isLoaded: false,
|
||||
tid2: 0
|
||||
}
|
||||
},
|
||||
props: {
|
||||
/**
|
||||
* 窗口宽
|
||||
*/
|
||||
width: {
|
||||
type: String,
|
||||
default: '250px'
|
||||
},
|
||||
/**
|
||||
* 宽器高,这将影响条码的高度
|
||||
*/
|
||||
height: {
|
||||
type: String,
|
||||
default: '250px'
|
||||
},
|
||||
/**
|
||||
* 码颜色
|
||||
*/
|
||||
color: {
|
||||
type: String,
|
||||
default: "primary"
|
||||
},
|
||||
/**
|
||||
* 码背景颜色
|
||||
*/
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "white"
|
||||
},
|
||||
/**
|
||||
* 码的定位点颜色,不填写和原前景一致
|
||||
*/
|
||||
posColor: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 条码内容
|
||||
*/
|
||||
text: {
|
||||
type: String,
|
||||
default: "https://xui.tmui.design"
|
||||
},
|
||||
/**
|
||||
* 是否绘制Logo到qr上。
|
||||
*/
|
||||
logo: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 是否绘制Logo到qr上。
|
||||
*/
|
||||
logoBgColor: {
|
||||
type: String,
|
||||
default: "#fff"
|
||||
},
|
||||
/**
|
||||
* logo大小。
|
||||
*/
|
||||
logoSize: {
|
||||
type: String,
|
||||
default: "50px"
|
||||
},
|
||||
/**
|
||||
* 边距
|
||||
*/
|
||||
padding:{
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
/**
|
||||
* 绘制的样式目前提供
|
||||
* rect :普通码矩形
|
||||
* circular :小圆点
|
||||
* line :线条
|
||||
* rectSmall :小方格
|
||||
* xing :星形
|
||||
* vertical :竖圆形
|
||||
*/
|
||||
mode:{
|
||||
type: String,
|
||||
default: "rect"
|
||||
},
|
||||
/**
|
||||
* 定位位点是否使用圆角。
|
||||
*/
|
||||
pdRounded:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
},
|
||||
/**
|
||||
* 生成自动连接的wifi码,手机原生相机扫码时,可以根据你设置帐号密码自动连接你的wifi.
|
||||
* 包含的字段:ssid:wifi名称,auth:授权方式(NONE,WPA,WEP)的一种,password:密码,hidden:是否隐藏密码,字符串'true'/'false'
|
||||
*/
|
||||
wifi:{
|
||||
type:Object as PropType<UTSJSONObject>,
|
||||
default:():UTSJSONObject => ({} as UTSJSONObject)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
_width() : number {
|
||||
let p = parseInt(this.width);
|
||||
if (this.width.lastIndexOf('rpx') > -1 || this.width.lastIndexOf('px') == -1) {
|
||||
p = rpx2px(p);
|
||||
}
|
||||
return Math.floor(p)
|
||||
},
|
||||
_height() : number {
|
||||
let p = parseInt(this.height);
|
||||
if (this.height.lastIndexOf('rpx') > -1 || this.height.lastIndexOf('px') == -1) {
|
||||
p = rpx2px(p);
|
||||
}
|
||||
return Math.floor(p)
|
||||
},
|
||||
|
||||
_color() : string {
|
||||
return getDefaultColor(this.color);
|
||||
},
|
||||
_bgColor() : string {
|
||||
return getDefaultColor(this.bgColor);
|
||||
},
|
||||
_posColor() : string {
|
||||
if(this.posColor=='') return this._color
|
||||
return getDefaultColor(this.posColor);
|
||||
},
|
||||
_text() : string {
|
||||
let wifisize = this.wifi.toMap().size
|
||||
if(wifisize>0){
|
||||
return `WIFI:T:${this.wifi['auth']??''};S:${this.wifi['ssid']??''};P:${this.wifi['password']??''};H:${this.wifi['hidden']??'true'};`
|
||||
}
|
||||
return this.text;
|
||||
},
|
||||
_logo() : string {
|
||||
return this.logo;
|
||||
},
|
||||
_logoBgColor() : string {
|
||||
return this.logoBgColor;
|
||||
},
|
||||
_padding() : number {
|
||||
return this.padding;
|
||||
},
|
||||
|
||||
_logoSize() : number {
|
||||
let p = parseInt(this.logoSize);
|
||||
if (this.logoSize.lastIndexOf('rpx') > -1 || this.logoSize.lastIndexOf('px') == -1) {
|
||||
p = rpx2px(p);
|
||||
}
|
||||
return Math.floor(p)
|
||||
},
|
||||
|
||||
},
|
||||
watch: {
|
||||
text(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
wifi:{
|
||||
handler(){
|
||||
this.drawer();
|
||||
},
|
||||
deep:true
|
||||
},
|
||||
mode() {
|
||||
this.drawer();
|
||||
},
|
||||
logo() {
|
||||
this.drawer();
|
||||
},
|
||||
color(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
bgColor(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
logoSize(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
padding(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
width(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
},
|
||||
height(newValue : string) {
|
||||
if (newValue == "") return;
|
||||
this.drawer();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// #ifndef APP-HARMONY
|
||||
this.drawer()
|
||||
// #endif
|
||||
// #ifdef APP-HARMONY
|
||||
let t = this;
|
||||
this.tid2 = setTimeout(function() {
|
||||
t.drawer()
|
||||
}, 120);
|
||||
// #endif
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearTimeout(this.tid2)
|
||||
},
|
||||
methods: {
|
||||
drawer(){
|
||||
let _this = this;
|
||||
// #ifdef APP || MP
|
||||
uni.createCanvasContextAsync({
|
||||
id:this.id2,
|
||||
component:this,
|
||||
success(context){
|
||||
let ctx = context.getContext('2d')!;
|
||||
let canvas = ctx.canvas
|
||||
if (ctx == null) return;
|
||||
let ratio = uni.getWindowInfo()?.pixelRatio??1
|
||||
ctx!.clearRect(0,0, canvas.offsetWidth,canvas.offsetHeight)
|
||||
canvas.width = canvas.offsetWidth * ratio
|
||||
canvas.height = canvas.offsetHeight * ratio
|
||||
// #ifdef APP
|
||||
ctx.reset();
|
||||
// #endif
|
||||
ctx.scale(ratio, ratio);
|
||||
let img =null as null|any
|
||||
// #ifdef MP-WEIXIN||APP-HARMONY
|
||||
img = context.createImage()
|
||||
// #endif
|
||||
drawQrcode({
|
||||
ctx:ctx,
|
||||
text:_this._text,
|
||||
size:_this._width,
|
||||
foreground:_this._color,
|
||||
background:_this._bgColor,
|
||||
padding:_this._padding,
|
||||
logo:_this._logo,
|
||||
logoSize:_this._logoSize,
|
||||
logoBgColor:_this._logoBgColor,
|
||||
ecc:"H",
|
||||
mode:_this.mode,
|
||||
pdColor:_this._posColor,
|
||||
pdRounded:_this.pdRounded,
|
||||
} as XQrcoderProps,img)
|
||||
},
|
||||
fail(){
|
||||
uni.showToast({title:'错误',icon:'none'})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef WEB
|
||||
let canvas = this.$refs['canvas'] as UniCanvasElement
|
||||
let ratio = window.devicePixelRatio;
|
||||
canvas.width = canvas.offsetWidth * ratio
|
||||
canvas.height = canvas.offsetHeight * ratio
|
||||
let ctx = canvas.getContext('2d')!
|
||||
ctx.scale(ratio, ratio);
|
||||
drawQrcode({
|
||||
ctx:ctx,
|
||||
text:this._text,
|
||||
size:this._width,
|
||||
foreground:this._color,
|
||||
background:this._bgColor,
|
||||
padding:this._padding,
|
||||
logoBgColor:_this._logoBgColor,
|
||||
logo:this._logo,
|
||||
logoSize:this._logoSize,
|
||||
ecc:"H",
|
||||
mode:this.mode,
|
||||
pdColor:_this._posColor,
|
||||
pdRounded:_this.pdRounded
|
||||
} as XQrcoderProps)
|
||||
// #endif
|
||||
|
||||
},
|
||||
/**
|
||||
* 返回一个上传图片的临时文件地址
|
||||
* @param call(string) 返回图片路径,失败返回的是空字符串
|
||||
*/
|
||||
getQrImg(call:(imgstr:string)=>void) {
|
||||
// #ifdef APP
|
||||
let ele = this.$refs['xQrcodeEle'] as UniElement;
|
||||
ele.takeSnapshot({
|
||||
success(res) {
|
||||
call(res.tempFilePath)
|
||||
},
|
||||
fail() {
|
||||
call('')
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef WEB
|
||||
let ele2= this.$refs['canvas'] as HTMLCanvasElement;
|
||||
toPngFile(ele2.toDataURL('image/png',1)).then(furl=>call(furl)).catch(call(''))
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.createCanvasContextAsync({
|
||||
id:this.id2,
|
||||
component:this,
|
||||
success(context){
|
||||
let ctx = context.getContext('2d')!;
|
||||
let canvas = ctx.canvas
|
||||
var imageData = canvas.toDataURL('image/png',1);
|
||||
toPngFile(imageData).then(furl=>call(furl)).catch(call(''))
|
||||
},
|
||||
fail(err){
|
||||
console.error(err)
|
||||
call('')
|
||||
}
|
||||
},this)
|
||||
// #endif
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<view ref="xQrcodeEle" :style="{width:_width+'px',height:_height+'px'}">
|
||||
<canvas ref="canvas" :canvas-id="id2" type="2d" :id="id2" :style="{width:_width+'px',height:_height+'px'}"></canvas>
|
||||
</view>
|
||||
</template>
|
||||
<style scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user