hy-app 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/hy-avatar/hy-avatar.vue +4 -3
- package/components/hy-badge/hy-badge.vue +3 -3
- package/components/hy-badge/index.scss +0 -1
- package/components/hy-badge/props.ts +6 -1
- package/components/hy-coupon/index.scss +7 -2
- package/components/hy-coupon/props.ts +7 -4
- package/components/hy-coupon/typing.d.ts +1 -1
- package/components/hy-datetime-picker/props.ts +1 -3
- package/components/hy-folding-panel/props.ts +1 -1
- package/components/hy-folding-panel/typing.d.ts +0 -38
- package/components/hy-folding-panel-item/hy-folding-panel-item.vue +2 -3
- package/components/hy-folding-panel-item/typing.d.ts +14 -0
- package/components/hy-icon/hy-icon.vue +3 -8
- package/components/hy-list/props.ts +1 -1
- package/components/hy-notice-bar/typing.d.ts +2 -0
- package/components/hy-popup/hy-popup.vue +0 -1
- package/components/hy-qrcode/hy-qrcode.vue +70 -4
- package/components/hy-qrcode/index.scss +3 -4
- package/components/hy-qrcode/qrcode.js +138 -0
- package/components/hy-signature/hy-signature.vue +25 -22
- package/components/hy-signature/index.scss +0 -4
- package/components/hy-tabbar/hy-tabbar.vue +137 -0
- package/components/{hy-tabBar → hy-tabbar}/index.scss +30 -30
- package/components/hy-tabbar/props.ts +59 -0
- package/components/hy-tabbar/typing.d.ts +61 -0
- package/components/hy-tabbar-group/README.md +326 -0
- package/components/hy-tabbar-group/hy-tabbar-group.vue +87 -0
- package/components/hy-tabbar-group/index.scss +57 -0
- package/components/hy-tabbar-group/props.ts +78 -0
- package/components/hy-tabbar-group/typing.ts +16 -0
- package/components/hy-tabbar-item/hy-tabbar-item.vue +103 -0
- package/components/hy-tabbar-item/index.scss +43 -0
- package/components/hy-tabbar-item/props.ts +24 -0
- package/components/hy-tabbar-item/typing.ts +22 -0
- package/components/hy-tag/props.ts +8 -2
- package/components/hy-text/props.ts +8 -2
- package/components/hy-textarea/props.ts +4 -1
- package/components/hy-tooltip/props.ts +1 -3
- package/components/hy-upload/props.ts +1 -1
- package/components/index.ts +177 -177
- package/global.d.ts +87 -85
- package/package.json +2 -2
- package/web-types.json +1 -1
- package/components/hy-tabBar/hy-tabBar.vue +0 -109
- package/components/hy-tabBar/props.ts +0 -13
- package/components/hy-tabBar/typing.d.ts +0 -54
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<view class="hy-avatar" :class="avatarClass" :style="avatarStyle" @tap="clickHandler">
|
|
3
|
-
<slot>
|
|
3
|
+
<slot v-if="$slots.default"></slot>
|
|
4
|
+
<template v-else>
|
|
4
5
|
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
|
|
5
6
|
<open-data
|
|
6
7
|
v-if="mpAvatar && allowMp"
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
<!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
|
|
17
18
|
<template v-if="mpAvatar && allowMp"></template>
|
|
18
19
|
<!-- #endif -->
|
|
19
|
-
<
|
|
20
|
+
<hy-icon v-else-if="icon" :name="icon" :size="fontSize" :color="color"></hy-icon>
|
|
20
21
|
<text
|
|
21
22
|
v-else-if="text"
|
|
22
23
|
:style="{
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
:mode="mode"
|
|
37
38
|
@error="errorHandler"
|
|
38
39
|
></image>
|
|
39
|
-
</
|
|
40
|
+
</template>
|
|
40
41
|
</view>
|
|
41
42
|
</template>
|
|
42
43
|
|
|
@@ -47,9 +47,9 @@ const emit = defineEmits<IBadgeEmit>()
|
|
|
47
47
|
* @description 整个组件的样式
|
|
48
48
|
* */
|
|
49
49
|
const badgeStyle = computed<CSSProperties>(() => {
|
|
50
|
-
const style: CSSProperties = {
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const style: CSSProperties = {
|
|
51
|
+
zIndex: props.zIndex,
|
|
52
|
+
color: props.color
|
|
53
53
|
}
|
|
54
54
|
if (props.bgColor && !props.inverted) {
|
|
55
55
|
style.backgroundColor = props.bgColor
|
|
@@ -8,7 +8,7 @@ const badgeProps = {
|
|
|
8
8
|
},
|
|
9
9
|
/** 显示的内容 */
|
|
10
10
|
value: {
|
|
11
|
-
type: Number,
|
|
11
|
+
type: [String, Number],
|
|
12
12
|
default: 0
|
|
13
13
|
},
|
|
14
14
|
/** 是否显示 */
|
|
@@ -21,6 +21,11 @@ const badgeProps = {
|
|
|
21
21
|
type: Number,
|
|
22
22
|
default: 999
|
|
23
23
|
},
|
|
24
|
+
/** 层级 */
|
|
25
|
+
zIndex: {
|
|
26
|
+
type: Number,
|
|
27
|
+
default: 999
|
|
28
|
+
},
|
|
24
29
|
/**
|
|
25
30
|
* 主题类型
|
|
26
31
|
* @values error,warning,success,primary,info
|
|
@@ -9,8 +9,8 @@ $hy-box-width: 180rpx;
|
|
|
9
9
|
|
|
10
10
|
/* 已使用/过期状态的置灰效果 */
|
|
11
11
|
@include m(disabled) {
|
|
12
|
-
filter: grayscale(
|
|
13
|
-
opacity: 0.
|
|
12
|
+
filter: grayscale(0.4) !important;
|
|
13
|
+
opacity: 0.6;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/* 优惠券卡片主体 */
|
|
@@ -34,6 +34,11 @@ $hy-box-width: 180rpx;
|
|
|
34
34
|
no-repeat,
|
|
35
35
|
radial-gradient(circle at $hy-box-width bottom, transparent 15rpx, #ff7d00 0) bottom / 100%
|
|
36
36
|
51px no-repeat;
|
|
37
|
+
//background:
|
|
38
|
+
// radial-gradient(circle at left center, transparent 15rpx, #ff7d00 0) left center / 30rpx 100% no-repeat,
|
|
39
|
+
// radial-gradient(circle at right center, transparent 15rpx, #ff7d00 0) right center / 30rpx 100% no-repeat;
|
|
40
|
+
|
|
41
|
+
|
|
37
42
|
}
|
|
38
43
|
@include m(discount) {
|
|
39
44
|
background:
|
|
@@ -7,12 +7,15 @@ const couponProps = {
|
|
|
7
7
|
type: String,
|
|
8
8
|
default: ''
|
|
9
9
|
},
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* 优惠券类型:moneyOff:满减券,discount:折扣券,fixedAmount:无门槛券
|
|
12
|
+
* @values moneyOff,discount,fixedAmount
|
|
13
|
+
* */
|
|
11
14
|
type: {
|
|
12
15
|
type: String,
|
|
13
16
|
default: ''
|
|
14
17
|
},
|
|
15
|
-
/**
|
|
18
|
+
/** 金额底部优惠券类型文字描述 */
|
|
16
19
|
typeText: {
|
|
17
20
|
type: String,
|
|
18
21
|
default: ''
|
|
@@ -27,7 +30,7 @@ const couponProps = {
|
|
|
27
30
|
type: Array,
|
|
28
31
|
default: () => ['']
|
|
29
32
|
},
|
|
30
|
-
/**
|
|
33
|
+
/** 优惠券描述备注 */
|
|
31
34
|
description: {
|
|
32
35
|
type: String,
|
|
33
36
|
default: ''
|
|
@@ -74,7 +77,7 @@ const couponProps = {
|
|
|
74
77
|
},
|
|
75
78
|
/**
|
|
76
79
|
* 按钮类型
|
|
77
|
-
* @values text,button
|
|
80
|
+
* @values text,button,none
|
|
78
81
|
* */
|
|
79
82
|
btnMode: {
|
|
80
83
|
type: String,
|
|
@@ -2,7 +2,7 @@ import type { CSSProperties } from 'vue'
|
|
|
2
2
|
|
|
3
3
|
export type CouponStatus = 'unused' | 'used' | 'expired' | 'redeemed'
|
|
4
4
|
/**
|
|
5
|
-
* moneyOff
|
|
5
|
+
* moneyOff:满减券,discount:折扣券,fixedAmount:无门槛券
|
|
6
6
|
* */
|
|
7
7
|
export type CouponType = 'moneyOff' | 'discount' | 'fixedAmount'
|
|
8
8
|
|
|
@@ -1,41 +1,3 @@
|
|
|
1
|
-
import type { Ref, ToRefs } from 'vue'
|
|
2
|
-
|
|
3
|
-
// 折叠面板组组件的Props接口
|
|
4
|
-
export interface HyFoldingPanelGroupProps {
|
|
5
|
-
/**
|
|
6
|
-
* 当前激活的面板索引,支持v-model
|
|
7
|
-
*/
|
|
8
|
-
modelValue?: number
|
|
9
|
-
/**
|
|
10
|
-
* 是否手风琴模式,默认false
|
|
11
|
-
*/
|
|
12
|
-
accordion?: boolean
|
|
13
|
-
/**
|
|
14
|
-
* 是否禁用整个折叠面板组
|
|
15
|
-
*/
|
|
16
|
-
disabled?: boolean
|
|
17
|
-
/**
|
|
18
|
-
* 是否显示边框,默认true
|
|
19
|
-
*/
|
|
20
|
-
border?: boolean
|
|
21
|
-
/**
|
|
22
|
-
* 面板大小 large, medium, small
|
|
23
|
-
*/
|
|
24
|
-
size?: HyApp.SizeType
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 父组件提供给子组件的配置接口
|
|
28
|
-
export interface HyFoldingPanelGroupConfig extends ToRefs<HyFoldingPanelGroupProps> {
|
|
29
|
-
/**
|
|
30
|
-
* 当前激活的索引
|
|
31
|
-
*/
|
|
32
|
-
activeIndex: Ref<number | string>
|
|
33
|
-
/**
|
|
34
|
-
* 更新激活索引的方法
|
|
35
|
-
*/
|
|
36
|
-
updateActiveIndex: (index: number | string) => void
|
|
37
|
-
}
|
|
38
|
-
|
|
39
1
|
// 折叠面板组组件的事件接口
|
|
40
2
|
export interface IFoldingPanelGroupEmits {
|
|
41
3
|
/**
|
|
@@ -67,8 +67,7 @@ export default {
|
|
|
67
67
|
|
|
68
68
|
<script setup lang="ts">
|
|
69
69
|
import { ref, computed, inject, onMounted } from 'vue'
|
|
70
|
-
import type { IFoldingPanelItemEmits } from './typing'
|
|
71
|
-
import type { HyFoldingPanelGroupConfig } from '../hy-folding-panel/typing'
|
|
70
|
+
import type { IFoldingPanelConfig, IFoldingPanelItemEmits } from './typing'
|
|
72
71
|
import { addUnit, IconConfig } from '../../libs'
|
|
73
72
|
import foldingPanelItemProps from './props'
|
|
74
73
|
// 组件
|
|
@@ -86,7 +85,7 @@ const props = defineProps(foldingPanelItemProps)
|
|
|
86
85
|
const emit = defineEmits<IFoldingPanelItemEmits>()
|
|
87
86
|
|
|
88
87
|
// 尝试从父组件注入配置
|
|
89
|
-
const groupConfig = inject<
|
|
88
|
+
const groupConfig = inject<IFoldingPanelConfig>('hy-folding-panel')
|
|
90
89
|
|
|
91
90
|
// 内部展开状态
|
|
92
91
|
const expanded = ref(props.defaultOpen)
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import foldingPanelProps from '../hy-folding-panel/props'
|
|
2
|
+
import type { ExtractPropTypes, ToRefs } from 'vue'
|
|
3
|
+
|
|
4
|
+
export interface IFoldingPanelConfig extends ToRefs<ExtractPropTypes<typeof foldingPanelProps>> {
|
|
5
|
+
/**
|
|
6
|
+
* 当前激活的索引
|
|
7
|
+
*/
|
|
8
|
+
activeIndex: Ref<number | string>
|
|
9
|
+
/**
|
|
10
|
+
* 更新激活索引的方法
|
|
11
|
+
*/
|
|
12
|
+
updateActiveIndex: (index: number | string) => void
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
// 折叠面板项组件的事件接口
|
|
2
16
|
export interface IFoldingPanelItemEmits {
|
|
3
17
|
/**
|
|
@@ -7,12 +7,7 @@
|
|
|
7
7
|
:mode="imgMode"
|
|
8
8
|
:style="[imgStyle, customStyle]"
|
|
9
9
|
></image>
|
|
10
|
-
<text
|
|
11
|
-
v-else
|
|
12
|
-
class="hy-icon__icon"
|
|
13
|
-
:class="uClasses"
|
|
14
|
-
:style="[iconStyle, customStyle]"
|
|
15
|
-
></text>
|
|
10
|
+
<text v-else :class="uClasses" :style="[iconStyle, customStyle]"></text>
|
|
16
11
|
<!-- 这里进行空字符串判断,如果仅仅是v-if="label",可能会出现传递0的时候,结果也无法显示 -->
|
|
17
12
|
<text
|
|
18
13
|
v-if="label"
|
|
@@ -58,9 +53,9 @@ const emit = defineEmits<IIconEmits>()
|
|
|
58
53
|
|
|
59
54
|
const uClasses = computed(() => {
|
|
60
55
|
let classes: string | string[] = [
|
|
56
|
+
'hy-icon__icon',
|
|
61
57
|
'iconfont',
|
|
62
|
-
`${props.customPrefix}-${props.name}
|
|
63
|
-
props.customPrefix
|
|
58
|
+
`${props.customPrefix}-${props.name}`
|
|
64
59
|
]
|
|
65
60
|
if (props.isRotate) classes.push('hy-rotate')
|
|
66
61
|
if (props.color)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<canvas
|
|
7
7
|
class="hy-qrcode__content--canvas"
|
|
8
8
|
:id="cid"
|
|
9
|
-
|
|
9
|
+
type="2d"
|
|
10
10
|
:style="{ width: addUnit(size), height: addUnit(size) }"
|
|
11
11
|
/>
|
|
12
12
|
<!-- #endif -->
|
|
@@ -36,8 +36,7 @@ export default {
|
|
|
36
36
|
import { getCurrentInstance, ref, watch, nextTick } from 'vue'
|
|
37
37
|
import type { IQrcodeEmits } from './typing'
|
|
38
38
|
import QRCode from './qrcode.js'
|
|
39
|
-
import { addUnit, error } from '../../libs'
|
|
40
|
-
import qrCodeProps from './props'
|
|
39
|
+
import { addUnit, error, random } from '../../libs'
|
|
41
40
|
// 组件
|
|
42
41
|
import HyLoading from '../hy-loading/hy-loading.vue'
|
|
43
42
|
import HyImage from '../hy-image/hy-image.vue'
|
|
@@ -48,7 +47,73 @@ import HyImage from '../hy-image/hy-image.vue'
|
|
|
48
47
|
*/
|
|
49
48
|
defineOptions({})
|
|
50
49
|
|
|
51
|
-
const props = defineProps(
|
|
50
|
+
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
51
|
+
const props = defineProps({
|
|
52
|
+
/** 实例ID字符串(如果有多个二维码组件必须设置不一样的cid) */
|
|
53
|
+
cid: {
|
|
54
|
+
type: String,
|
|
55
|
+
default: 'hy-qrcode-canvas_' + random(1, 1000)
|
|
56
|
+
},
|
|
57
|
+
/** 二维码大小 */
|
|
58
|
+
size: {
|
|
59
|
+
type: Number,
|
|
60
|
+
default: 200
|
|
61
|
+
},
|
|
62
|
+
/** 二维码内容 */
|
|
63
|
+
text: String,
|
|
64
|
+
/** 是否显示二维码 */
|
|
65
|
+
show: {
|
|
66
|
+
type: Boolean,
|
|
67
|
+
default: true
|
|
68
|
+
},
|
|
69
|
+
/** 二维码背景色 */
|
|
70
|
+
background: {
|
|
71
|
+
type: String,
|
|
72
|
+
default: '#ffffff'
|
|
73
|
+
},
|
|
74
|
+
/** 二维码颜色 */
|
|
75
|
+
foreground: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: '#000000'
|
|
78
|
+
},
|
|
79
|
+
/** 定位角点颜色 */
|
|
80
|
+
pdGround: {
|
|
81
|
+
type: String,
|
|
82
|
+
default: '#000000'
|
|
83
|
+
},
|
|
84
|
+
/** 是否是自定义组件 */
|
|
85
|
+
usingComponents: {
|
|
86
|
+
type: Boolean,
|
|
87
|
+
default: true
|
|
88
|
+
},
|
|
89
|
+
/** 容错级别 */
|
|
90
|
+
lv: {
|
|
91
|
+
type: Number,
|
|
92
|
+
default: 3
|
|
93
|
+
},
|
|
94
|
+
/** 二维码中间图标 */
|
|
95
|
+
icon: String,
|
|
96
|
+
/** 二维码中间图标大小 */
|
|
97
|
+
iconSize: {
|
|
98
|
+
type: Number,
|
|
99
|
+
default: 40
|
|
100
|
+
},
|
|
101
|
+
/** 显示加载状态 */
|
|
102
|
+
showLoading: {
|
|
103
|
+
type: Boolean,
|
|
104
|
+
default: true
|
|
105
|
+
},
|
|
106
|
+
/** 加载中提示语 */
|
|
107
|
+
loadingText: {
|
|
108
|
+
type: String,
|
|
109
|
+
default: '二维码生成中...'
|
|
110
|
+
},
|
|
111
|
+
/** 是否预览 */
|
|
112
|
+
allowPreview: {
|
|
113
|
+
type: Boolean,
|
|
114
|
+
default: false
|
|
115
|
+
}
|
|
116
|
+
})
|
|
52
117
|
const emit = defineEmits<IQrcodeEmits>()
|
|
53
118
|
|
|
54
119
|
const instance = getCurrentInstance()
|
|
@@ -73,6 +138,7 @@ const initQrCode = () => {
|
|
|
73
138
|
image: props.icon, // 二维码图标
|
|
74
139
|
imageSize: props.iconSize, // 二维码图标大小
|
|
75
140
|
cbResult: function (res: any) {
|
|
141
|
+
console.log(res)
|
|
76
142
|
// 生成二维码的回调
|
|
77
143
|
_result(res)
|
|
78
144
|
}
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
position: relative;
|
|
7
7
|
|
|
8
8
|
@include m(canvas) {
|
|
9
|
-
// 移除fixed定位,确保canvas在H5端能正确绘制
|
|
10
9
|
position: fixed;
|
|
11
|
-
top: -99999rpx;
|
|
12
|
-
left: -99999rpx;
|
|
13
|
-
z-index: -99999;
|
|
10
|
+
// top: -99999rpx;
|
|
11
|
+
// left: -99999rpx;
|
|
12
|
+
// z-index: -99999;
|
|
14
13
|
overflow: hidden;
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -1146,6 +1146,111 @@ let QRCode = {}
|
|
|
1146
1146
|
}
|
|
1147
1147
|
return options.foreground
|
|
1148
1148
|
}
|
|
1149
|
+
// 为2D Canvas添加辅助函数
|
|
1150
|
+
function drawIconWithBackground(canvas, ctx, options, qrCodeAlg) {
|
|
1151
|
+
// 在小程序中使用canvas.createImage()而不是wx.createImage()
|
|
1152
|
+
const img = canvas.createImage()
|
|
1153
|
+
img.src = options.image
|
|
1154
|
+
img.onload = function () {
|
|
1155
|
+
var ratioImgSize = options.imageSize || 40
|
|
1156
|
+
var x = Number(((options.size - ratioImgSize) / 2).toFixed(2))
|
|
1157
|
+
var y = Number(((options.size - ratioImgSize) / 2).toFixed(2))
|
|
1158
|
+
|
|
1159
|
+
// 绘制圆角矩形背景
|
|
1160
|
+
drawRoundedRect2D(ctx, x, y, ratioImgSize, ratioImgSize, 2, options.background)
|
|
1161
|
+
|
|
1162
|
+
// 绘制图标
|
|
1163
|
+
ctx.drawImage(img, x, y, ratioImgSize, ratioImgSize)
|
|
1164
|
+
|
|
1165
|
+
// 导出图片
|
|
1166
|
+
exportCanvasImage(canvas, options)
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// 添加错误处理
|
|
1170
|
+
img.onerror = function (e) {
|
|
1171
|
+
console.error('Failed to load QR code icon:', e)
|
|
1172
|
+
// 即使图标加载失败也要导出二维码
|
|
1173
|
+
exportCanvasImage(canvas, options)
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
function drawRoundedRect2D(ctx, x, y, width, height, r, fillColor) {
|
|
1178
|
+
ctx.beginPath()
|
|
1179
|
+
ctx.moveTo(x + r, y)
|
|
1180
|
+
ctx.arcTo(x + width, y, x + width, y + r, r)
|
|
1181
|
+
ctx.arcTo(x + width, y + height, x + width - r, y + height, r)
|
|
1182
|
+
ctx.arcTo(x, y + height, x, y + height - r, r)
|
|
1183
|
+
ctx.arcTo(x, y, x + r, y, r)
|
|
1184
|
+
ctx.closePath()
|
|
1185
|
+
ctx.fillStyle = fillColor
|
|
1186
|
+
ctx.fill()
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function exportCanvasImage(canvas, options) {
|
|
1190
|
+
setTimeout(() => {
|
|
1191
|
+
wx.canvasToTempFilePath(
|
|
1192
|
+
{
|
|
1193
|
+
canvas: canvas,
|
|
1194
|
+
quality: 1,
|
|
1195
|
+
success: function (res) {
|
|
1196
|
+
if (options.cbResult) {
|
|
1197
|
+
options.cbResult(res.tempFilePath)
|
|
1198
|
+
}
|
|
1199
|
+
},
|
|
1200
|
+
fail: function (res) {
|
|
1201
|
+
if (options.cbResult) {
|
|
1202
|
+
options.cbResult(res)
|
|
1203
|
+
}
|
|
1204
|
+
},
|
|
1205
|
+
complete: function () {
|
|
1206
|
+
uni.hideLoading()
|
|
1207
|
+
}
|
|
1208
|
+
},
|
|
1209
|
+
options.context
|
|
1210
|
+
)
|
|
1211
|
+
}, options.text.length + 100)
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
// 2D Canvas二维码绘制函数
|
|
1215
|
+
function drawQRCode2D(canvas, ctx, options, qrCodeAlg) {
|
|
1216
|
+
var count = qrCodeAlg.getModuleCount()
|
|
1217
|
+
var ratioSize = options.size
|
|
1218
|
+
|
|
1219
|
+
// 清除画布
|
|
1220
|
+
ctx.clearRect(0, 0, ratioSize, ratioSize)
|
|
1221
|
+
// 设置背景色
|
|
1222
|
+
ctx.fillStyle = options.background
|
|
1223
|
+
ctx.fillRect(0, 0, ratioSize, ratioSize)
|
|
1224
|
+
|
|
1225
|
+
//计算每个点的长宽
|
|
1226
|
+
var tileW = (ratioSize / count).toPrecision(4)
|
|
1227
|
+
var tileH = (ratioSize / count).toPrecision(4)
|
|
1228
|
+
|
|
1229
|
+
//绘制二维码
|
|
1230
|
+
for (var row = 0; row < count; row++) {
|
|
1231
|
+
for (var col = 0; col < count; col++) {
|
|
1232
|
+
var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
|
|
1233
|
+
var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
|
|
1234
|
+
var foreground = getForeGround({
|
|
1235
|
+
row: row,
|
|
1236
|
+
col: col,
|
|
1237
|
+
count: count,
|
|
1238
|
+
options: options
|
|
1239
|
+
})
|
|
1240
|
+
ctx.fillStyle = qrCodeAlg.modules[row][col] ? foreground : options.background
|
|
1241
|
+
ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
if (options.image) {
|
|
1246
|
+
// 绘制中间图标
|
|
1247
|
+
drawIconWithBackground(canvas, ctx, options, qrCodeAlg)
|
|
1248
|
+
} else {
|
|
1249
|
+
// 导出图片
|
|
1250
|
+
exportCanvasImage(canvas, options)
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1149
1254
|
// 创建canvas
|
|
1150
1255
|
let createCanvas = function (options) {
|
|
1151
1256
|
if (options.showLoading) {
|
|
@@ -1154,6 +1259,39 @@ let QRCode = {}
|
|
|
1154
1259
|
mask: true
|
|
1155
1260
|
})
|
|
1156
1261
|
}
|
|
1262
|
+
|
|
1263
|
+
// 尝试使用2D Canvas (小程序端)
|
|
1264
|
+
try {
|
|
1265
|
+
if (!options.nvueContext && typeof wx !== 'undefined' && wx.createSelectorQuery) {
|
|
1266
|
+
const query = wx.createSelectorQuery().in(options.context)
|
|
1267
|
+
query
|
|
1268
|
+
.select('#' + options.canvasId)
|
|
1269
|
+
.fields({ node: true, size: true })
|
|
1270
|
+
.exec((res) => {
|
|
1271
|
+
if (res[0] && res[0].node) {
|
|
1272
|
+
const canvas = res[0].node
|
|
1273
|
+
const ctx = canvas.getContext('2d')
|
|
1274
|
+
|
|
1275
|
+
// 设置canvas尺寸
|
|
1276
|
+
const dpr = wx.getSystemInfoSync().pixelRatio
|
|
1277
|
+
canvas.width = options.size * dpr
|
|
1278
|
+
canvas.height = options.size * dpr
|
|
1279
|
+
ctx.scale(dpr, dpr)
|
|
1280
|
+
|
|
1281
|
+
// 创建二维码算法实例
|
|
1282
|
+
var qrCodeAlg = new QRCodeAlg(options.text, options.correctLevel)
|
|
1283
|
+
|
|
1284
|
+
// 使用2D Canvas绘制
|
|
1285
|
+
drawQRCode2D(canvas, ctx, options, qrCodeAlg)
|
|
1286
|
+
return
|
|
1287
|
+
}
|
|
1288
|
+
})
|
|
1289
|
+
}
|
|
1290
|
+
} catch (e) {
|
|
1291
|
+
console.warn('2D Canvas initialization failed, falling back to legacy mode:', e)
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
// 回退到传统Canvas方式
|
|
1157
1295
|
var ctx = ''
|
|
1158
1296
|
if (options.nvueContext) {
|
|
1159
1297
|
ctx = options.nvueContext
|
|
@@ -46,37 +46,39 @@
|
|
|
46
46
|
>
|
|
47
47
|
</slot>
|
|
48
48
|
<template v-else>
|
|
49
|
-
<
|
|
49
|
+
<hy-flex gap="12">
|
|
50
|
+
<block v-if="enableHistory">
|
|
51
|
+
<hy-button
|
|
52
|
+
size="small"
|
|
53
|
+
plain
|
|
54
|
+
shape="circle"
|
|
55
|
+
@click="revoke"
|
|
56
|
+
:disabled="lines.length <= 0"
|
|
57
|
+
:text="revokeText"
|
|
58
|
+
></hy-button>
|
|
59
|
+
<hy-button
|
|
60
|
+
size="small"
|
|
61
|
+
plain
|
|
62
|
+
shape="circle"
|
|
63
|
+
@click="restore"
|
|
64
|
+
:disabled="redoLines.length <= 0"
|
|
65
|
+
:text="restoreText"
|
|
66
|
+
></hy-button>
|
|
67
|
+
</block>
|
|
50
68
|
<hy-button
|
|
51
69
|
size="small"
|
|
52
70
|
plain
|
|
53
71
|
shape="circle"
|
|
54
|
-
@click="
|
|
55
|
-
:
|
|
56
|
-
:text="revokeText"
|
|
72
|
+
@click="clear"
|
|
73
|
+
:text="clearText"
|
|
57
74
|
></hy-button>
|
|
58
75
|
<hy-button
|
|
59
76
|
size="small"
|
|
60
|
-
plain
|
|
61
77
|
shape="circle"
|
|
62
|
-
@click="
|
|
63
|
-
:
|
|
64
|
-
:text="restoreText"
|
|
78
|
+
@click="confirmSignature"
|
|
79
|
+
:text="confirmText"
|
|
65
80
|
></hy-button>
|
|
66
|
-
</
|
|
67
|
-
<hy-button
|
|
68
|
-
size="small"
|
|
69
|
-
plain
|
|
70
|
-
shape="circle"
|
|
71
|
-
@click="clear"
|
|
72
|
-
:text="clearText"
|
|
73
|
-
></hy-button>
|
|
74
|
-
<hy-button
|
|
75
|
-
size="small"
|
|
76
|
-
shape="circle"
|
|
77
|
-
@click="confirmSignature"
|
|
78
|
-
:text="confirmText"
|
|
79
|
-
></hy-button>
|
|
81
|
+
</hy-flex>
|
|
80
82
|
</template>
|
|
81
83
|
</view>
|
|
82
84
|
</view>
|
|
@@ -105,6 +107,7 @@ import signatureProps from './props'
|
|
|
105
107
|
|
|
106
108
|
// 组件
|
|
107
109
|
import HyButton from '../hy-button/hy-button.vue'
|
|
110
|
+
import HyFlex from '../hy-flex/hy-flex.vue'
|
|
108
111
|
|
|
109
112
|
/**
|
|
110
113
|
* 用于签名场景,基于 Canvas 实现的签名组件。提供了基础签名、历史记录、笔锋效果等功能。
|