zmuniwxcanvas2d 1.0.0
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/README.md +0 -0
- package/index.d.ts +259 -0
- package/index.ts +624 -0
- package/package.json +17 -0
- package/qrcode.min.js +1 -0
- package/stackblur-es.min.js +2 -0
package/README.md
ADDED
|
File without changes
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
export interface CreateCanvasOpt {
|
|
2
|
+
/**
|
|
3
|
+
* CSS选择器字符串,用于查询canvas元素
|
|
4
|
+
* @example '#myCanvas' 或 '.canvas-class'
|
|
5
|
+
*/
|
|
6
|
+
query: string
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* canvas背景颜色(可选)
|
|
10
|
+
* @example '#ffffff' 或 'rgba(255,255,255,1)'
|
|
11
|
+
*/
|
|
12
|
+
bgColor?: string
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* canvas圆角半径(可选)
|
|
16
|
+
* @example 10 (单位:px)
|
|
17
|
+
*/
|
|
18
|
+
radius?: number
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 组件实例上下文
|
|
22
|
+
* 在自定义组件中使用时需要传入组件的this
|
|
23
|
+
*/
|
|
24
|
+
component: any
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 参考设备宽度
|
|
28
|
+
* 开发时UI设计稿的宽度,默认375,可改为750等
|
|
29
|
+
*/
|
|
30
|
+
rootWidth: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface LineStyle {
|
|
34
|
+
/**
|
|
35
|
+
* 线段颜色
|
|
36
|
+
*/
|
|
37
|
+
color?: string
|
|
38
|
+
/**
|
|
39
|
+
* 线段粗细
|
|
40
|
+
*/
|
|
41
|
+
width?: number
|
|
42
|
+
/**
|
|
43
|
+
* [虚线长度, 虚线间距]
|
|
44
|
+
*/
|
|
45
|
+
dash?: number[]
|
|
46
|
+
/**
|
|
47
|
+
* 虚线偏移量
|
|
48
|
+
*/
|
|
49
|
+
offset?: number
|
|
50
|
+
/**
|
|
51
|
+
* 线段转角样式,可选项有:bevel | round | miter
|
|
52
|
+
* 默认'bevel'
|
|
53
|
+
*/
|
|
54
|
+
join?: string
|
|
55
|
+
/**
|
|
56
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
57
|
+
* 默认'butt'
|
|
58
|
+
*/
|
|
59
|
+
cap?: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface BastInfo {
|
|
63
|
+
/**
|
|
64
|
+
* 绘制的方式
|
|
65
|
+
*/
|
|
66
|
+
type?: string
|
|
67
|
+
/**
|
|
68
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
69
|
+
*/
|
|
70
|
+
x: number
|
|
71
|
+
/**
|
|
72
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
73
|
+
*/
|
|
74
|
+
y: number
|
|
75
|
+
/**
|
|
76
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
77
|
+
*/
|
|
78
|
+
width?: number
|
|
79
|
+
/**
|
|
80
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
81
|
+
*/
|
|
82
|
+
height?: number
|
|
83
|
+
/**
|
|
84
|
+
* 线段两端样式,可选项有:butt | round | square
|
|
85
|
+
*/
|
|
86
|
+
zIndex?: number
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RectType extends BastInfo {
|
|
90
|
+
/**
|
|
91
|
+
* 背景色(填充色)
|
|
92
|
+
*/
|
|
93
|
+
bgColor?: string
|
|
94
|
+
/**
|
|
95
|
+
* 圆角
|
|
96
|
+
*/
|
|
97
|
+
radius?: number
|
|
98
|
+
/**
|
|
99
|
+
* 线条样式
|
|
100
|
+
*/
|
|
101
|
+
lineStyle?: LineStyle
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface ArcType extends BastInfo {
|
|
105
|
+
/**
|
|
106
|
+
* 弧线半径
|
|
107
|
+
*/
|
|
108
|
+
r?: number
|
|
109
|
+
/**
|
|
110
|
+
* 弧线起始角度
|
|
111
|
+
*/
|
|
112
|
+
start?: number
|
|
113
|
+
/**
|
|
114
|
+
* 弧线终止角度
|
|
115
|
+
*/
|
|
116
|
+
end?: number
|
|
117
|
+
/**
|
|
118
|
+
* 是否反向绘制弧线
|
|
119
|
+
*/
|
|
120
|
+
reverse?: boolean
|
|
121
|
+
/**
|
|
122
|
+
* 线条样式
|
|
123
|
+
*/
|
|
124
|
+
lineStyle?: LineStyle
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface BlurType extends BastInfo {
|
|
128
|
+
/**
|
|
129
|
+
* 图片宽度
|
|
130
|
+
*/
|
|
131
|
+
width?: number
|
|
132
|
+
/**
|
|
133
|
+
* 图片高度
|
|
134
|
+
*/
|
|
135
|
+
height?: number
|
|
136
|
+
/**
|
|
137
|
+
* 模糊度
|
|
138
|
+
*/
|
|
139
|
+
blur?: number
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface ImageType extends BastInfo {
|
|
143
|
+
/**
|
|
144
|
+
* 图片路径
|
|
145
|
+
*/
|
|
146
|
+
url: string
|
|
147
|
+
/**
|
|
148
|
+
* 图片宽度
|
|
149
|
+
*/
|
|
150
|
+
width?: number
|
|
151
|
+
/**
|
|
152
|
+
* 图片高度
|
|
153
|
+
*/
|
|
154
|
+
height?: number
|
|
155
|
+
/**
|
|
156
|
+
* 图片的裁剪方式,参考小程序 image 标签的 mode (opens new window) 属性
|
|
157
|
+
* 默认 scaleToFill
|
|
158
|
+
*/
|
|
159
|
+
mode?: string
|
|
160
|
+
/**
|
|
161
|
+
* 图片圆角
|
|
162
|
+
*/
|
|
163
|
+
radius?: number
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface lineListType {
|
|
167
|
+
/**
|
|
168
|
+
* 点坐标[x, y]
|
|
169
|
+
*/
|
|
170
|
+
point: [number, number]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface LineType extends BastInfo {
|
|
174
|
+
/**
|
|
175
|
+
* 组成线段的点的集合
|
|
176
|
+
*/
|
|
177
|
+
line?: lineListType[]
|
|
178
|
+
/**
|
|
179
|
+
* 线条样式
|
|
180
|
+
*/
|
|
181
|
+
lineStyle?: LineStyle
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface QrcodeType extends BastInfo {
|
|
185
|
+
/**
|
|
186
|
+
* 二维码信息内容
|
|
187
|
+
*/
|
|
188
|
+
text?: string
|
|
189
|
+
/**
|
|
190
|
+
* 二维码大小
|
|
191
|
+
*/
|
|
192
|
+
size?: number
|
|
193
|
+
/**
|
|
194
|
+
* 二维码前景色
|
|
195
|
+
*/
|
|
196
|
+
color?: string
|
|
197
|
+
/**
|
|
198
|
+
* 二维码背景色
|
|
199
|
+
*/
|
|
200
|
+
bgColor?: string
|
|
201
|
+
/**
|
|
202
|
+
* 纠错能力等级
|
|
203
|
+
*/
|
|
204
|
+
ecc?: number
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface TextType extends BastInfo {
|
|
208
|
+
/**
|
|
209
|
+
* 文本内容
|
|
210
|
+
*/
|
|
211
|
+
text?: string
|
|
212
|
+
/**
|
|
213
|
+
* 文本颜色
|
|
214
|
+
*/
|
|
215
|
+
color?: number
|
|
216
|
+
/**
|
|
217
|
+
* 字体大小
|
|
218
|
+
* 默认 12
|
|
219
|
+
*/
|
|
220
|
+
fontSize?: number
|
|
221
|
+
/**
|
|
222
|
+
* 字体粗细
|
|
223
|
+
*/
|
|
224
|
+
fontWeight?: string
|
|
225
|
+
/**
|
|
226
|
+
* 文本最大长度,设置后文字会自动换行
|
|
227
|
+
*/
|
|
228
|
+
width?: number
|
|
229
|
+
/**
|
|
230
|
+
* 基准线,可选项有:top | hanging | middle | alphabetic | ideographic | bottom
|
|
231
|
+
* 默认 top
|
|
232
|
+
*/
|
|
233
|
+
baseline?: string
|
|
234
|
+
/**
|
|
235
|
+
* 对齐方式,可选项有:left | right | center | start | end
|
|
236
|
+
* 默认 left
|
|
237
|
+
*/
|
|
238
|
+
align?: string
|
|
239
|
+
/**
|
|
240
|
+
* 最多显示行数,超出内容显示省略号,0为不限制
|
|
241
|
+
*/
|
|
242
|
+
ellipsis?: number
|
|
243
|
+
/**
|
|
244
|
+
* 行高
|
|
245
|
+
*/
|
|
246
|
+
lineHeight?: number
|
|
247
|
+
/**
|
|
248
|
+
* 字体
|
|
249
|
+
* 默认 sans-serif
|
|
250
|
+
*/
|
|
251
|
+
fontFamily?: string
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface DrawType {
|
|
255
|
+
/**
|
|
256
|
+
* 绘制方法
|
|
257
|
+
*/
|
|
258
|
+
list?: Array<RectType | ArcType | BlurType | ImageType | LineType | QrcodeType | TextType>
|
|
259
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import {
|
|
2
|
+
canvasRGB,
|
|
3
|
+
} from 'stackblur'
|
|
4
|
+
import { api as qrcodeApi } from 'qrcode'
|
|
5
|
+
import type { ArcType, BlurType, CreateCanvasOpt, DrawType, ImageType, LineStyle, LineType, QrcodeType, RectType, TextType } from './index.d.js'
|
|
6
|
+
|
|
7
|
+
const SYS_INFO = uni.getSystemInfoSync()
|
|
8
|
+
class UniWxCanvas2d {
|
|
9
|
+
query: string
|
|
10
|
+
bgColor: string | undefined
|
|
11
|
+
radius: number | undefined
|
|
12
|
+
component: any
|
|
13
|
+
canvas: any
|
|
14
|
+
canvasInfo: any
|
|
15
|
+
ctx: any
|
|
16
|
+
dpr: number
|
|
17
|
+
startTime: number | undefined
|
|
18
|
+
rootWidth: number
|
|
19
|
+
listener: any
|
|
20
|
+
constructor() {
|
|
21
|
+
this.query = '' // query查询条件
|
|
22
|
+
this.bgColor = undefined // canvas 背景色
|
|
23
|
+
this.radius = 0 // canvas 圆角
|
|
24
|
+
this.component = undefined // 如果是在自定义组件中,需要获取到自定义组件的内部 this 变量 (即,传入 this)
|
|
25
|
+
this.canvas = {} // canvas 节点
|
|
26
|
+
this.canvasInfo = undefined // wx.createSelectorQuery 返回的 res
|
|
27
|
+
this.rootWidth = 0 // 参考设备宽度 (即开发时UI设计稿的宽度,默认375,可改为750)
|
|
28
|
+
this.ctx = {} // canvas 上下文
|
|
29
|
+
this.dpr = 0 // 像素比
|
|
30
|
+
this.startTime = 0 // 绘图开始时间戳
|
|
31
|
+
this.listener = {} // 监听回调
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// canvas 画布大小 (单位: rpx)
|
|
35
|
+
get canvasSize() {
|
|
36
|
+
if (!this.canvas || !this.dpr || !this.rootWidth) {
|
|
37
|
+
return {
|
|
38
|
+
width: 0,
|
|
39
|
+
height: 0,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
width:
|
|
44
|
+
(this.canvas.width / SYS_INFO.screenWidth / this.dpr) * this.rootWidth,
|
|
45
|
+
height:
|
|
46
|
+
(this.canvas.height / SYS_INFO.screenWidth / this.dpr) * this.rootWidth,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 通过 wx.createSelectorQuery 获取 canvas 元素
|
|
51
|
+
queryCanvas() {
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
(this.component || uni).createSelectorQuery()
|
|
54
|
+
.select(this.query)
|
|
55
|
+
.fields({ node: true, size: true }, () => { })
|
|
56
|
+
.exec((res) => {
|
|
57
|
+
if (res[0]) {
|
|
58
|
+
resolve(res)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 创建画布
|
|
65
|
+
create(opts: CreateCanvasOpt) {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
const options = {
|
|
68
|
+
query: '',
|
|
69
|
+
rootWidth: 375,
|
|
70
|
+
...opts,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!options.query)
|
|
74
|
+
reject(new Error('[WxCanvas2d] \'query\' is empty.'))
|
|
75
|
+
|
|
76
|
+
this.query = options.query
|
|
77
|
+
this.bgColor = options.bgColor
|
|
78
|
+
this.component = options.component
|
|
79
|
+
this.radius = options.radius
|
|
80
|
+
this.queryCanvas().then((res) => {
|
|
81
|
+
const canvas = res[0].node
|
|
82
|
+
const ctx = canvas.getContext('2d')
|
|
83
|
+
const dpr = SYS_INFO.pixelRatio
|
|
84
|
+
this.canvas = res[0].node
|
|
85
|
+
this.canvasInfo = res
|
|
86
|
+
this.ctx = ctx
|
|
87
|
+
this.dpr = dpr
|
|
88
|
+
this.rootWidth = options.rootWidth
|
|
89
|
+
this.canvas.width = res[0].width * this.dpr
|
|
90
|
+
this.canvas.height = res[0].height * this.dpr
|
|
91
|
+
resolve('')
|
|
92
|
+
}).catch((err) => {
|
|
93
|
+
reject(err)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 清空画布
|
|
99
|
+
clear() {
|
|
100
|
+
// 画布范围
|
|
101
|
+
const scope = [
|
|
102
|
+
0,
|
|
103
|
+
0,
|
|
104
|
+
this.xDpr(this.canvasSize.width),
|
|
105
|
+
this.xDpr(this.canvasSize.height),
|
|
106
|
+
]
|
|
107
|
+
// 清空画布
|
|
108
|
+
this.ctx.clearRect(...scope)
|
|
109
|
+
// 设置圆角路径并剪切
|
|
110
|
+
if (this.radius) {
|
|
111
|
+
this.drawRectPath({
|
|
112
|
+
x: 0,
|
|
113
|
+
y: 0,
|
|
114
|
+
width: this.canvasSize.width,
|
|
115
|
+
height: this.canvasSize.height,
|
|
116
|
+
radius: this.radius,
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// 剪切路径,上下文没有保存和还原设置,所以后续所有绘制都会被限制在此剪切范围内
|
|
120
|
+
this.ctx.clip()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 绘制背景色
|
|
124
|
+
if (this.bgColor) {
|
|
125
|
+
this.ctx.fillStyle = this.bgColor
|
|
126
|
+
this.ctx.fillRect(...scope)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// canvas 大小适配
|
|
131
|
+
xDpr(val: number) {
|
|
132
|
+
if (!this.dpr || !this.rootWidth) {
|
|
133
|
+
return val
|
|
134
|
+
}
|
|
135
|
+
return val * this.dpr * SYS_INFO.screenWidth / this.rootWidth
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 绘制矩形路径
|
|
139
|
+
drawRectPath(opts: RectType) {
|
|
140
|
+
const {
|
|
141
|
+
x = 0,
|
|
142
|
+
y = 0,
|
|
143
|
+
width = 0,
|
|
144
|
+
height = 0,
|
|
145
|
+
} = opts
|
|
146
|
+
const maxRadius = Math.min(width, height) / 2
|
|
147
|
+
const radius = Math.max(0, Math.min(opts.radius || 0, maxRadius))
|
|
148
|
+
const angle = {
|
|
149
|
+
top: Math.PI * 1.5,
|
|
150
|
+
right: 0,
|
|
151
|
+
bottom: Math.PI * 0.5,
|
|
152
|
+
left: Math.PI,
|
|
153
|
+
}
|
|
154
|
+
const angleArr = [
|
|
155
|
+
[angle.left, angle.top],
|
|
156
|
+
[angle.top, angle.right],
|
|
157
|
+
[angle.right, angle.bottom],
|
|
158
|
+
[angle.bottom, angle.left],
|
|
159
|
+
]
|
|
160
|
+
const arcPos = [
|
|
161
|
+
[x + radius, y + radius].map(n => this.xDpr(n)), // left top
|
|
162
|
+
[x + width - radius, y + radius].map(n => this.xDpr(n)), // top right
|
|
163
|
+
[x + width - radius, y + height - radius].map(n => this.xDpr(n)), // right bottom
|
|
164
|
+
[x + radius, y + height - radius].map(n => this.xDpr(n)), // bottom left
|
|
165
|
+
]
|
|
166
|
+
this.ctx.beginPath()
|
|
167
|
+
arcPos.forEach((n, i) => {
|
|
168
|
+
this.ctx.arc(...n, this.xDpr(radius), ...angleArr[i])
|
|
169
|
+
})
|
|
170
|
+
this.ctx.closePath()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 设置线的样式
|
|
174
|
+
setLineStyle(opts: LineStyle) {
|
|
175
|
+
if (Object.keys(opts).length === 0)
|
|
176
|
+
return
|
|
177
|
+
const {
|
|
178
|
+
cap = 'butt',
|
|
179
|
+
join = 'bevel',
|
|
180
|
+
offset = 0,
|
|
181
|
+
dash = [1, 0],
|
|
182
|
+
color = '#000',
|
|
183
|
+
width = 2,
|
|
184
|
+
} = opts ?? {}
|
|
185
|
+
this.ctx.lineCap = cap
|
|
186
|
+
this.ctx.setLineDash(dash.map(n => this.xDpr(n)))
|
|
187
|
+
this.ctx.lineDashOffset = this.xDpr(offset)
|
|
188
|
+
this.ctx.lineJoin = join
|
|
189
|
+
this.ctx.lineWidth = this.xDpr(width)
|
|
190
|
+
this.ctx.strokeStyle = color
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
draw(opts: DrawType) {
|
|
194
|
+
return new Promise((resolve, reject) => {
|
|
195
|
+
this.startTime = Date.now()
|
|
196
|
+
this.queryCanvas().then((res: any) => {
|
|
197
|
+
this.canvas.width = res[0].width * this.dpr
|
|
198
|
+
this.canvas.height = res[0].height * this.dpr
|
|
199
|
+
this.clear()
|
|
200
|
+
const list = opts?.list?.map(n => ({ ...n, zIndex: n.zIndex || 0 })).sort((n, m) => n.zIndex - m.zIndex) || []
|
|
201
|
+
// 按顺序绘制图层方法
|
|
202
|
+
const next = (index = 0) => {
|
|
203
|
+
const nextStart = Date.now()
|
|
204
|
+
const config = list[index]
|
|
205
|
+
this.ctx.save()
|
|
206
|
+
const drawMethods = new Map<string, Function>([
|
|
207
|
+
['rect', this.drawRect.bind(this)],
|
|
208
|
+
['arc', this.drawArc.bind(this)],
|
|
209
|
+
['blur', this.drawBlur.bind(this)],
|
|
210
|
+
['image', this.drawImage.bind(this)],
|
|
211
|
+
['line', this.drawLine.bind(this)],
|
|
212
|
+
['qrcode', this.drawQrcode.bind(this)],
|
|
213
|
+
['text', this.drawText.bind(this)],
|
|
214
|
+
])
|
|
215
|
+
if (index < list.length) {
|
|
216
|
+
const method = drawMethods.get(config.type || '')
|
|
217
|
+
if (method) {
|
|
218
|
+
this.emit('beforeDraw', { index, config })
|
|
219
|
+
method(config).then(() => {
|
|
220
|
+
next(++index)
|
|
221
|
+
}).catch((error: any) => {
|
|
222
|
+
reject(error)
|
|
223
|
+
}).finally(() => {
|
|
224
|
+
this.emit('afterDraw', { index, config })
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
next(++index)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// 所有图层绘制完毕
|
|
233
|
+
resolve('')
|
|
234
|
+
}
|
|
235
|
+
this.ctx.restore()
|
|
236
|
+
}
|
|
237
|
+
next()
|
|
238
|
+
}).catch((err) => {
|
|
239
|
+
reject(err)
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 弧线
|
|
245
|
+
drawArc(opts: ArcType) {
|
|
246
|
+
return new Promise((resolve) => {
|
|
247
|
+
const {
|
|
248
|
+
x = 0,
|
|
249
|
+
y = 0,
|
|
250
|
+
r = 0,
|
|
251
|
+
start = 0,
|
|
252
|
+
end = 0,
|
|
253
|
+
reverse = false,
|
|
254
|
+
lineStyle = {},
|
|
255
|
+
} = opts
|
|
256
|
+
this.setLineStyle(lineStyle)
|
|
257
|
+
this.ctx.beginPath()
|
|
258
|
+
this.ctx.arc(
|
|
259
|
+
this.xDpr(x),
|
|
260
|
+
this.xDpr(y),
|
|
261
|
+
this.xDpr(r),
|
|
262
|
+
start,
|
|
263
|
+
end,
|
|
264
|
+
reverse,
|
|
265
|
+
)
|
|
266
|
+
this.ctx.stroke()
|
|
267
|
+
resolve('')
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// 高斯模糊
|
|
272
|
+
drawBlur(opts: BlurType) {
|
|
273
|
+
return new Promise((resolve) => {
|
|
274
|
+
const {
|
|
275
|
+
x = 0,
|
|
276
|
+
y = 0,
|
|
277
|
+
width = 0,
|
|
278
|
+
height = 0,
|
|
279
|
+
blur = 0,
|
|
280
|
+
} = opts
|
|
281
|
+
canvasRGB(
|
|
282
|
+
this.canvas,
|
|
283
|
+
this.xDpr(x),
|
|
284
|
+
this.xDpr(y),
|
|
285
|
+
this.xDpr(width),
|
|
286
|
+
this.xDpr(height),
|
|
287
|
+
blur,
|
|
288
|
+
)
|
|
289
|
+
resolve('')
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 绘制图片
|
|
294
|
+
drawImage(opts: ImageType) {
|
|
295
|
+
return new Promise((resolve, reject) => {
|
|
296
|
+
const {
|
|
297
|
+
url = '',
|
|
298
|
+
x = 0,
|
|
299
|
+
y = 0,
|
|
300
|
+
width = 0,
|
|
301
|
+
height = 0,
|
|
302
|
+
mode = 'scaleToFill',
|
|
303
|
+
radius = 0,
|
|
304
|
+
} = opts
|
|
305
|
+
const img = this.canvas.createImage()
|
|
306
|
+
img.src = url
|
|
307
|
+
img.onload = () => {
|
|
308
|
+
uni.getImageInfo({
|
|
309
|
+
src: url,
|
|
310
|
+
success: (res: any) => {
|
|
311
|
+
const imgWidth = res.width
|
|
312
|
+
const imgHeight = res.height
|
|
313
|
+
const aspectRatio = width / height
|
|
314
|
+
let widthRatio = 1
|
|
315
|
+
let heightRatio = 1
|
|
316
|
+
// 原图等比例缩放后截取范围的长宽比
|
|
317
|
+
if (mode === 'aspectFit') {
|
|
318
|
+
widthRatio = imgWidth / imgHeight < aspectRatio
|
|
319
|
+
? width / imgWidth * imgHeight / height
|
|
320
|
+
: 1
|
|
321
|
+
heightRatio = imgWidth / imgHeight > aspectRatio
|
|
322
|
+
? height / imgHeight * imgWidth / width
|
|
323
|
+
: 1
|
|
324
|
+
}
|
|
325
|
+
else if (mode === 'aspectFill') {
|
|
326
|
+
widthRatio = imgWidth / imgHeight > aspectRatio
|
|
327
|
+
? width / imgWidth * imgHeight / height
|
|
328
|
+
: 1
|
|
329
|
+
heightRatio = imgWidth / imgHeight < aspectRatio
|
|
330
|
+
? height / imgHeight * imgWidth / width
|
|
331
|
+
: 1
|
|
332
|
+
}
|
|
333
|
+
const imgCut: Record<string, number[]> = {
|
|
334
|
+
'scaleToFill': [
|
|
335
|
+
0,
|
|
336
|
+
0,
|
|
337
|
+
imgWidth,
|
|
338
|
+
imgHeight,
|
|
339
|
+
], // 缩放: 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
|
|
340
|
+
'aspectFit': [
|
|
341
|
+
(res.width - res.width * widthRatio) / 2,
|
|
342
|
+
(res.height - res.height * heightRatio) / 2,
|
|
343
|
+
res.width * widthRatio,
|
|
344
|
+
res.height * heightRatio,
|
|
345
|
+
], // 缩放: 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
|
|
346
|
+
'aspectFill': [
|
|
347
|
+
(res.width - res.width * widthRatio) / 2,
|
|
348
|
+
(res.height - res.height * heightRatio) / 2,
|
|
349
|
+
res.width * widthRatio,
|
|
350
|
+
res.height * heightRatio,
|
|
351
|
+
], // 缩放: 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
|
|
352
|
+
'widthFix': [], // 缩放: 宽度不变,高度自动变化,保持原图宽高比不变
|
|
353
|
+
'top': [
|
|
354
|
+
(imgWidth - width) / 2,
|
|
355
|
+
0,
|
|
356
|
+
width,
|
|
357
|
+
height,
|
|
358
|
+
], // 裁剪: 不缩放图片,只显示图片的顶部区域
|
|
359
|
+
'bottom': [
|
|
360
|
+
(imgWidth - width) / 2,
|
|
361
|
+
imgHeight - height,
|
|
362
|
+
width,
|
|
363
|
+
height,
|
|
364
|
+
], // 裁剪: 不缩放图片,只显示图片的底部区域
|
|
365
|
+
'center': [
|
|
366
|
+
(imgWidth - width) / 2,
|
|
367
|
+
(imgHeight - height) / 2,
|
|
368
|
+
width,
|
|
369
|
+
height,
|
|
370
|
+
], // 裁剪: 不缩放图片,只显示图片的中间区域
|
|
371
|
+
'left': [
|
|
372
|
+
0,
|
|
373
|
+
(imgHeight - height) / 2,
|
|
374
|
+
width,
|
|
375
|
+
height,
|
|
376
|
+
], // 裁剪: 不缩放图片,只显示图片的左边区域
|
|
377
|
+
'right': [
|
|
378
|
+
imgWidth - width,
|
|
379
|
+
(imgHeight - height) / 2,
|
|
380
|
+
width,
|
|
381
|
+
height,
|
|
382
|
+
], // 裁剪: 不缩放图片,只显示图片的右边区域
|
|
383
|
+
'top left': [
|
|
384
|
+
0,
|
|
385
|
+
0,
|
|
386
|
+
width,
|
|
387
|
+
height,
|
|
388
|
+
], // 裁剪: 不缩放图片,只显示图片的左上边区域
|
|
389
|
+
'top right': [
|
|
390
|
+
imgWidth - width,
|
|
391
|
+
0,
|
|
392
|
+
width,
|
|
393
|
+
height,
|
|
394
|
+
], // 裁剪: 不缩放图片,只显示图片的右上边区域
|
|
395
|
+
'bottom left': [
|
|
396
|
+
0,
|
|
397
|
+
imgHeight - height,
|
|
398
|
+
width,
|
|
399
|
+
height,
|
|
400
|
+
], // 裁剪: 不缩放图片,只显示图片的左下边区域
|
|
401
|
+
'bottom right': [
|
|
402
|
+
imgWidth - width,
|
|
403
|
+
imgHeight - height,
|
|
404
|
+
width,
|
|
405
|
+
height,
|
|
406
|
+
], // 裁剪: 不缩放图片,只显示图片的右下边区域
|
|
407
|
+
}
|
|
408
|
+
if (radius) {
|
|
409
|
+
this.ctx.save()
|
|
410
|
+
this.drawRectPath({ x, y, width, height, radius })
|
|
411
|
+
this.ctx.clip()
|
|
412
|
+
}
|
|
413
|
+
this.ctx.drawImage(
|
|
414
|
+
img,
|
|
415
|
+
...(imgCut[mode] || []),
|
|
416
|
+
this.xDpr(x) || 0,
|
|
417
|
+
this.xDpr(y) || 0,
|
|
418
|
+
this.xDpr(width || res.width),
|
|
419
|
+
this.xDpr(height || res.height),
|
|
420
|
+
)
|
|
421
|
+
if (radius) {
|
|
422
|
+
this.ctx.restore()
|
|
423
|
+
}
|
|
424
|
+
resolve('')
|
|
425
|
+
},
|
|
426
|
+
})
|
|
427
|
+
}
|
|
428
|
+
img.onerror = (err: any) => {
|
|
429
|
+
reject(err)
|
|
430
|
+
}
|
|
431
|
+
})
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// 绘制线段
|
|
435
|
+
drawLine(opts: LineType) {
|
|
436
|
+
return new Promise((resolve) => {
|
|
437
|
+
const {
|
|
438
|
+
lineStyle,
|
|
439
|
+
line = [],
|
|
440
|
+
} = opts
|
|
441
|
+
if (lineStyle) {
|
|
442
|
+
this.setLineStyle(lineStyle)
|
|
443
|
+
}
|
|
444
|
+
line.forEach((n, i) => {
|
|
445
|
+
if (!i) {
|
|
446
|
+
this.ctx.beginPath()
|
|
447
|
+
this.ctx.moveTo(...n.point.map(n => this.xDpr(n)))
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
this.ctx.lineTo(...n.point.map(n => this.xDpr(n)))
|
|
451
|
+
this.ctx.stroke()
|
|
452
|
+
}
|
|
453
|
+
})
|
|
454
|
+
resolve('')
|
|
455
|
+
})
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// 绘制二维码
|
|
459
|
+
drawQrcode(opts: QrcodeType) {
|
|
460
|
+
return new Promise((resolve) => {
|
|
461
|
+
const {
|
|
462
|
+
text = '',
|
|
463
|
+
x = 0,
|
|
464
|
+
y = 0,
|
|
465
|
+
size = 0,
|
|
466
|
+
color = '#000',
|
|
467
|
+
bgColor = '#fff',
|
|
468
|
+
ecc = 2,
|
|
469
|
+
} = opts
|
|
470
|
+
qrcodeApi.draw(
|
|
471
|
+
text,
|
|
472
|
+
this.ctx,
|
|
473
|
+
this.xDpr(x),
|
|
474
|
+
this.xDpr(y),
|
|
475
|
+
this.xDpr(size), // width
|
|
476
|
+
this.xDpr(size), // height
|
|
477
|
+
bgColor,
|
|
478
|
+
color,
|
|
479
|
+
this.component,
|
|
480
|
+
ecc,
|
|
481
|
+
)
|
|
482
|
+
resolve('')
|
|
483
|
+
})
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// 绘制矩形
|
|
487
|
+
drawRect(opts: RectType) {
|
|
488
|
+
return new Promise((resolve) => {
|
|
489
|
+
let {
|
|
490
|
+
x = 0,
|
|
491
|
+
y = 0,
|
|
492
|
+
width = 0,
|
|
493
|
+
height = 0,
|
|
494
|
+
bgColor = '',
|
|
495
|
+
radius = 0,
|
|
496
|
+
lineStyle = {},
|
|
497
|
+
} = opts
|
|
498
|
+
// 防止 radius 设置过大
|
|
499
|
+
radius = Math.min(radius, Math.min(width, height) / 2)
|
|
500
|
+
// 设置线段样式
|
|
501
|
+
this.setLineStyle(lineStyle)
|
|
502
|
+
// 设置填充色
|
|
503
|
+
this.ctx.fillStyle = bgColor
|
|
504
|
+
this.drawRectPath({
|
|
505
|
+
x,
|
|
506
|
+
y,
|
|
507
|
+
width,
|
|
508
|
+
height,
|
|
509
|
+
radius,
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
if (lineStyle.color) {
|
|
513
|
+
this.ctx.stroke()
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (bgColor) {
|
|
517
|
+
this.ctx.fill()
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
resolve('')
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
drawText(opts: TextType) {
|
|
525
|
+
return new Promise((resolve) => {
|
|
526
|
+
const {
|
|
527
|
+
x = 0,
|
|
528
|
+
y = 0,
|
|
529
|
+
color = '#000',
|
|
530
|
+
fontSize = 12,
|
|
531
|
+
fontWeight = '',
|
|
532
|
+
width = Infinity,
|
|
533
|
+
baseline = 'top', // top | hanging | middle | alphabetic | ideographic | bottom
|
|
534
|
+
align = 'left', // left | right | center | start | end
|
|
535
|
+
text = '',
|
|
536
|
+
ellipsis = 0,
|
|
537
|
+
lineHeight = opts.fontSize || 12,
|
|
538
|
+
fontFamily = 'sans-serif',
|
|
539
|
+
} = opts
|
|
540
|
+
let index = 0 // 行数下标
|
|
541
|
+
let splitStr: any = [] // 拆分后的文本数组
|
|
542
|
+
this.ctx.textAlign = align
|
|
543
|
+
this.ctx.textBaseline = baseline
|
|
544
|
+
this.ctx.fillStyle = color
|
|
545
|
+
this.ctx.font = `${fontWeight} ${this.xDpr(fontSize)}px ${fontFamily}`
|
|
546
|
+
// 拆分文本
|
|
547
|
+
Array.from(text).forEach((n, i) => {
|
|
548
|
+
let start = 0 // 截取的起始下标
|
|
549
|
+
|
|
550
|
+
String(n).split('').forEach((m, j) => {
|
|
551
|
+
const str = String(n).slice(start, j + 1)
|
|
552
|
+
|
|
553
|
+
if (this.ctx.measureText(str).width < this.xDpr(width)) {
|
|
554
|
+
splitStr[index] = str
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
splitStr[index + 1] = m // 显示不下多出来的那个字存到下一行
|
|
558
|
+
start = j
|
|
559
|
+
index++
|
|
560
|
+
}
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
index++
|
|
564
|
+
})
|
|
565
|
+
// 最大显示行,超出显示省略号
|
|
566
|
+
if (ellipsis && splitStr.length > ellipsis) {
|
|
567
|
+
splitStr = splitStr.slice(0, ellipsis)
|
|
568
|
+
splitStr[ellipsis - 1] = `${splitStr[ellipsis - 1].slice(0, -1)}...`
|
|
569
|
+
}
|
|
570
|
+
// 循环绘制文本
|
|
571
|
+
splitStr.forEach((n: string, i: number) => {
|
|
572
|
+
this.ctx.fillText(
|
|
573
|
+
n,
|
|
574
|
+
this.xDpr({
|
|
575
|
+
left: x,
|
|
576
|
+
start: x,
|
|
577
|
+
right: x + width,
|
|
578
|
+
end: x + width,
|
|
579
|
+
center: x + width / 2,
|
|
580
|
+
}[align] || x),
|
|
581
|
+
this.xDpr(y + lineHeight * i + (lineHeight - fontSize) / 2),
|
|
582
|
+
)
|
|
583
|
+
})
|
|
584
|
+
resolve('')
|
|
585
|
+
})
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// 事件监听
|
|
589
|
+
on(evt: any, cb: Function) {
|
|
590
|
+
if (this.listener[evt]) {
|
|
591
|
+
if (!this.listener[evt].includes(cb))
|
|
592
|
+
this.listener[evt].push(cb)
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
this.listener[evt] = [cb]
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// 取消监听
|
|
600
|
+
off(evt: any, cb: Function) {
|
|
601
|
+
const fns = this.listener[evt]
|
|
602
|
+
|
|
603
|
+
if (fns) {
|
|
604
|
+
if (cb) {
|
|
605
|
+
fns.some((fn: any, idx: number) => fn === cb && delete this.listener[evt][idx])
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
delete this.listener[evt]
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// 触发监听事件回调
|
|
614
|
+
emit(evt: any, pars: any) {
|
|
615
|
+
if (Array.isArray(this.listener[evt])) {
|
|
616
|
+
this.listener[evt].forEach((n: any) => n({
|
|
617
|
+
event: evt,
|
|
618
|
+
...pars,
|
|
619
|
+
}))
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export default UniWxCanvas2d
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zmuniwxcanvas2d",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [],
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"qrcode": "^1.5.4",
|
|
13
|
+
"stackblur-canvas": "^2.7.0"
|
|
14
|
+
},
|
|
15
|
+
"types": "./index.d.ts",
|
|
16
|
+
"description": ""
|
|
17
|
+
}
|
package/qrcode.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(){var r,f,o,e,t,a,n=[0,11,15,19,23,27,31,16,18,20,22,24,26,28,20,22,24,24,26,28,28,22,24,24,26,26,28,28,24,24,26,26,26,28,28,24,26,26,26,28,28],i=[3220,1468,2713,1235,3062,1890,2119,1549,2344,2936,1117,2583,1330,2470,1667,2249,2028,3780,481,4011,142,3098,831,3445,592,2517,1776,2234,1951,2827,1070,2660,1345,3177],c=[30660,29427,32170,30877,26159,25368,27713,26998,21522,20773,24188,23371,17913,16590,20375,19104,13663,12392,16177,14854,9396,8579,11994,11245,5769,5054,7399,6608,1890,597,3340,2107],l=[1,0,19,7,1,0,16,10,1,0,13,13,1,0,9,17,1,0,34,10,1,0,28,16,1,0,22,22,1,0,16,28,1,0,55,15,1,0,44,26,2,0,17,18,2,0,13,22,1,0,80,20,2,0,32,18,2,0,24,26,4,0,9,16,1,0,108,26,2,0,43,24,2,2,15,18,2,2,11,22,2,0,68,18,4,0,27,16,4,0,19,24,4,0,15,28,2,0,78,20,4,0,31,18,2,4,14,18,4,1,13,26,2,0,97,24,2,2,38,22,4,2,18,22,4,2,14,26,2,0,116,30,3,2,36,22,4,4,16,20,4,4,12,24,2,2,68,18,4,1,43,26,6,2,19,24,6,2,15,28,4,0,81,20,1,4,50,30,4,4,22,28,3,8,12,24,2,2,92,24,6,2,36,22,4,6,20,26,7,4,14,28,4,0,107,26,8,1,37,22,8,4,20,24,12,4,11,22,3,1,115,30,4,5,40,24,11,5,16,20,11,5,12,24,5,1,87,22,5,5,41,24,5,7,24,30,11,7,12,24,5,1,98,24,7,3,45,28,15,2,19,24,3,13,15,30,1,5,107,28,10,1,46,28,1,15,22,28,2,17,14,28,5,1,120,30,9,4,43,26,17,1,22,28,2,19,14,28,3,4,113,28,3,11,44,26,17,4,21,26,9,16,13,26,3,5,107,28,3,13,41,26,15,5,24,30,15,10,15,28,4,4,116,28,17,0,42,26,17,6,22,28,19,6,16,30,2,7,111,28,17,0,46,28,7,16,24,30,34,0,13,24,4,5,121,30,4,14,47,28,11,14,24,30,16,14,15,30,6,4,117,30,6,14,45,28,11,16,24,30,30,2,16,30,8,4,106,26,8,13,47,28,7,22,24,30,22,13,15,30,10,2,114,28,19,4,46,28,28,6,22,28,33,4,16,30,8,4,122,30,22,3,45,28,8,26,23,30,12,28,15,30,3,10,117,30,3,23,45,28,4,31,24,30,11,31,15,30,7,7,116,30,21,7,45,28,1,37,23,30,19,26,15,30,5,10,115,30,19,10,47,28,15,25,24,30,23,25,15,30,13,3,115,30,2,29,46,28,42,1,24,30,23,28,15,30,17,0,115,30,10,23,46,28,10,35,24,30,19,35,15,30,17,1,115,30,14,21,46,28,29,19,24,30,11,46,15,30,13,6,115,30,14,23,46,28,44,7,24,30,59,1,16,30,12,7,121,30,12,26,47,28,39,14,24,30,22,41,15,30,6,14,121,30,6,34,47,28,46,10,24,30,2,64,15,30,17,4,122,30,29,14,46,28,49,10,24,30,24,46,15,30,4,18,122,30,13,32,46,28,48,14,24,30,42,32,15,30,20,4,117,30,40,7,47,28,43,22,24,30,10,67,15,30,19,6,118,30,18,31,47,28,34,34,24,30,20,61,15,30],s=[255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175],u=[1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0],v=[],h=[],g=[],C=[],b=[],d=2;function k(r,f){var o;r>f&&(o=r,r=f,f=o),o=f,o*=f,o+=f,o>>=1,C[o+=r]=1}function m(r,o){var e;for(g[r+f*o]=1,e=-2;e<2;e++)g[r+e+f*(o-2)]=1,g[r-2+f*(o+e+1)]=1,g[r+2+f*(o+e)]=1,g[r+e+1+f*(o+2)]=1;for(e=0;e<2;e++)k(r-1,o+e),k(r+1,o-e),k(r-e,o-1),k(r+e,o+1)}function S(r){for(;r>=255;)r=((r-=255)>>8)+(255&r);return r}var w=[];function z(r,f,o,e){var t,a,n;for(t=0;t<e;t++)v[o+t]=0;for(t=0;t<f;t++){if(255!=(n=s[v[r+t]^v[o]]))for(a=1;a<e;a++)v[o+a-1]=v[o+a]^u[S(n+w[e-a])];else for(a=o;a<o+e;a++)v[a]=v[a+1];v[o+e-1]=255==n?0:u[S(n+w[0])]}}function A(r,f){var o;return r>f&&(o=r,r=f,f=o),o=f,o+=f*f,o>>=1,C[o+=r]}function p(r){var o,e,t,a;switch(r){case 0:for(e=0;e<f;e++)for(o=0;o<f;o++)o+e&1||A(o,e)||(g[o+e*f]^=1);break;case 1:for(e=0;e<f;e++)for(o=0;o<f;o++)1&e||A(o,e)||(g[o+e*f]^=1);break;case 2:for(e=0;e<f;e++)for(t=0,o=0;o<f;o++,t++)3==t&&(t=0),t||A(o,e)||(g[o+e*f]^=1);break;case 3:for(a=0,e=0;e<f;e++,a++)for(3==a&&(a=0),t=a,o=0;o<f;o++,t++)3==t&&(t=0),t||A(o,e)||(g[o+e*f]^=1);break;case 4:for(e=0;e<f;e++)for(t=0,a=e>>1&1,o=0;o<f;o++,t++)3==t&&(t=0,a=!a),a||A(o,e)||(g[o+e*f]^=1);break;case 5:for(a=0,e=0;e<f;e++,a++)for(3==a&&(a=0),t=0,o=0;o<f;o++,t++)3==t&&(t=0),(o&e&1)+!(!t|!a)||A(o,e)||(g[o+e*f]^=1);break;case 6:for(a=0,e=0;e<f;e++,a++)for(3==a&&(a=0),t=0,o=0;o<f;o++,t++)3==t&&(t=0),(o&e&1)+(t&&t==a)&1||A(o,e)||(g[o+e*f]^=1);break;case 7:for(a=0,e=0;e<f;e++,a++)for(3==a&&(a=0),t=0,o=0;o<f;o++,t++)3==t&&(t=0),(t&&t==a)+(o+e&1)&1||A(o,e)||(g[o+e*f]^=1);break}}function y(r){var f,o=0;for(f=0;f<=r;f++)b[f]>=5&&(o+=3+b[f]-5);for(f=3;f<r-1;f+=2)b[f-2]==b[f+2]&&b[f+2]==b[f-1]&&b[f-1]==b[f+1]&&3*b[f-1]==b[f]&&(0==b[f-3]||f+3>r||3*b[f-3]>=4*b[f]||3*b[f+3]>=4*b[f])&&(o+=40);return o}function F(){var r,o,e,t,a,n=0,i=0;for(o=0;o<f-1;o++)for(r=0;r<f-1;r++)(g[r+f*o]&&g[r+1+f*o]&&g[r+f*(o+1)]&&g[r+1+f*(o+1)]||!(g[r+f*o]||g[r+1+f*o]||g[r+f*(o+1)]||g[r+1+f*(o+1)]))&&(n+=3);for(o=0;o<f;o++){for(b[0]=0,e=t=r=0;r<f;r++)(a=g[r+f*o])==t?b[e]++:b[++e]=1,i+=(t=a)?1:-1;n+=y(e)}i<0&&(i=-i);var c=i,l=0;for(c+=c<<2,c<<=1;c>f*f;)c-=f*f,l++;for(n+=10*l,r=0;r<f;r++){for(b[0]=0,e=t=o=0;o<f;o++)(a=g[r+f*o])==t?b[e]++:b[++e]=1,t=a;n+=y(e)}return n}var R=null,_={get ecclevel(){return d},set ecclevel(r){d=r},get size(){return _size},set size(r){_size=r},get canvas(){return R},set canvas(r){R=r},getFrame:function(b){return function(b){var y,R,_,x,M,j,q,B;x=b.length,r=0;do{if(r++,_=4*(d-1)+16*(r-1),o=l[_++],e=l[_++],t=l[_++],a=l[_],x<=(_=t*(o+e)+e-3+(r<=9)))break}while(r<40);for(f=17+4*r,M=t+(t+a)*(o+e)+e,x=0;x<M;x++)h[x]=0;for(v=b.slice(0),x=0;x<f*f;x++)g[x]=0;for(x=0;x<(f*(f+1)+1)/2;x++)C[x]=0;for(x=0;x<3;x++){for(_=0,R=0,1==x&&(_=f-7),2==x&&(R=f-7),g[R+3+f*(_+3)]=1,y=0;y<6;y++)g[R+y+f*_]=1,g[R+f*(_+y+1)]=1,g[R+6+f*(_+y)]=1,g[R+y+1+f*(_+6)]=1;for(y=1;y<5;y++)k(R+y,_+1),k(R+1,_+y+1),k(R+5,_+y),k(R+y+1,_+5);for(y=2;y<4;y++)g[R+y+f*(_+2)]=1,g[R+2+f*(_+y+1)]=1,g[R+4+f*(_+y)]=1,g[R+y+1+f*(_+4)]=1}if(r>1)for(x=n[r],R=f-7;;){for(y=f-7;y>x-3&&(m(y,R),!(y<x));)y-=x;if(R<=x+9)break;m(6,R-=x),m(R,6)}for(g[8+f*(f-8)]=1,R=0;R<7;R++)k(7,R),k(f-8,R),k(7,R+f-7);for(y=0;y<8;y++)k(y,7),k(y+f-8,7),k(y,f-8);for(y=0;y<9;y++)k(y,8);for(y=0;y<8;y++)k(y+f-8,8),k(8,y);for(R=0;R<7;R++)k(8,R+f-7);for(y=0;y<f-14;y++)1&y?(k(8+y,6),k(6,8+y)):(g[8+y+6*f]=1,g[6+f*(8+y)]=1);if(r>6)for(x=i[r-7],_=17,y=0;y<6;y++)for(R=0;R<3;R++,_--)1&(_>11?r>>_-12:x>>_)?(g[5-y+f*(2-R+f-11)]=1,g[2-R+f-11+f*(5-y)]=1):(k(5-y,2-R+f-11),k(2-R+f-11,5-y));for(R=0;R<f;R++)for(y=0;y<=R;y++)g[y+f*R]&&k(y,R);for(M=v.length,j=0;j<M;j++)h[j]=v.charCodeAt(j);if(v=h.slice(0),M>=(y=t*(o+e)+e)-2&&(M=y-2,r>9&&M--),j=M,r>9){for(v[j+2]=0,v[j+3]=0;j--;)x=v[j],v[j+3]|=255&x<<4,v[j+2]=x>>4;v[2]|=255&M<<4,v[1]=M>>4,v[0]=64|M>>12}else{for(v[j+1]=0,v[j+2]=0;j--;)x=v[j],v[j+2]|=255&x<<4,v[j+1]=x>>4;v[1]|=255&M<<4,v[0]=64|M>>4}for(j=M+3-(r<10);j<y;)v[j++]=236,v[j++]=17;for(w[0]=1,j=0;j<a;j++){for(w[j+1]=1,q=j;q>0;q--)w[q]=w[q]?w[q-1]^u[S(s[w[q]]+j)]:w[q-1];w[0]=u[S(s[w[0]]+j)]}for(j=0;j<=a;j++)w[j]=s[w[j]];for(_=y,R=0,j=0;j<o;j++)z(R,t,_,a),R+=t,_+=a;for(j=0;j<e;j++)z(R,t+1,_,a),R+=t+1,_+=a;for(R=0,j=0;j<t;j++){for(q=0;q<o;q++)h[R++]=v[j+q*t];for(q=0;q<e;q++)h[R++]=v[o*t+j+q*(t+1)]}for(q=0;q<e;q++)h[R++]=v[o*t+j+q*(t+1)];for(j=0;j<a;j++)for(q=0;q<o+e;q++)h[R++]=v[y+j+q*a];for(v=h,y=R=f-1,_=M=1,B=(t+a)*(o+e)+e,j=0;j<B;j++)for(x=v[j],q=0;q<8;q++,x<<=1){128&x&&(g[y+f*R]=1);do{M?y--:(y++,_?0!=R?R--:(_=!_,6==(y-=2)&&(y--,R=9)):R!=f-1?R++:(_=!_,6==(y-=2)&&(y--,R-=8))),M=!M}while(A(y,R))}for(v=g.slice(0),x=0,R=3e4,_=0;_<8&&(p(_),(y=F())<R&&(R=y,x=_),7!=x);_++)g=v.slice(0);for(x!=_&&p(x),R=c[x+(d-1<<3)],_=0;_<8;_++,R>>=1)1&R&&(g[f-1-_+8*f]=1,_<6?g[8+f*_]=1:g[8+f*(_+1)]=1);for(_=0;_<7;_++,R>>=1)1&R&&(g[8+f*(f-7+_)]=1,_?g[6-_+8*f]=1:g[7+8*f]=1);return g}(b)},utf16to8:function(r){var f,o,e,t;for(f="",e=r.length,o=0;o<e;o++)(t=r.charCodeAt(o))>=1&&t<=127?f+=r.charAt(o):t>2047?(f+=String.fromCharCode(224|t>>12&15),f+=String.fromCharCode(128|t>>6&63),f+=String.fromCharCode(128|t>>0&63)):(f+=String.fromCharCode(192|t>>6&31),f+=String.fromCharCode(128|t>>0&63));return f},draw:function(r,o,e,t,a,n,i,c,l,s){if(d=s||d,o){var u=Math.min(a,n);r=this.utf16to8(r);var v=this.getFrame(r),h=u/f;i&&(o.fillStyle=i,o.fillRect(e,t,a,a)),o.fillStyle=c||"black";for(var g=0;g<f;g++)for(var C=0;C<f;C++)v[C*f+g]&&o.fillRect(e+h*g,t+h*C,h,h)}}};module.exports={api:_}}();
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function t(r){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(r)}var r=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],a=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function n(t,r,a,n,e){if("string"==typeof t&&(t=document.getElementById(t)),t&&"naturalWidth"in t){var i=e?"offset":"natural",g=t[i+"Width"],v=t[i+"Height"];if("string"==typeof r&&(r=document.getElementById(r)),r&&"getContext"in r){r.style.width=g+"px",r.style.height=v+"px",r.width=g,r.height=v;var s=r.getContext("2d");s.clearRect(0,0,g,v),s.drawImage(t,0,0,t.naturalWidth,t.naturalHeight,0,0,g,v),isNaN(a)||a<1||(n?o(r,0,0,g,v,a):f(r,0,0,g,v,a))}}}function e(r,a,n,e,o){if("string"==typeof r&&(r=document.getElementById(r)),!r||"object"!==t(r)||!("getContext"in r))throw new TypeError("Expecting canvas with `getContext` method in processCanvasRGB(A) calls!");var i=r.getContext("2d");try{return i.getImageData(a,n,e,o)}catch(t){throw new Error("unable to access image data: "+t)}}function o(t,r,a,n,o,f){if(!(isNaN(f)||f<1)){f|=0;var g=e(t,r,a,n,o);g=i(g,r,a,n,o,f),t.getContext("2d").putImageData(g,r,a)}}function i(t,n,e,o,i,f){for(var g,s=t.data,u=2*f+1,c=o-1,l=i-1,x=f+1,b=x*(x+1)/2,y=new v,h=y,m=1;m<u;m++)h=h.next=new v,m===x&&(g=h);h.next=y;for(var d=null,p=null,w=0,C=0,B=r[f],E=a[f],I=0;I<i;I++){h=y;for(var N=s[C],R=s[C+1],D=s[C+2],G=s[C+3],S=0;S<x;S++)h.r=N,h.g=R,h.b=D,h.a=G,h=h.next;for(var A=0,W=0,H=0,T=0,j=x*N,k=x*R,q=x*D,z=x*G,F=b*N,J=b*R,K=b*D,L=b*G,M=1;M<x;M++){var O=C+((c<M?c:M)<<2),P=s[O],Q=s[O+1],U=s[O+2],V=s[O+3],X=x-M;F+=(h.r=P)*X,J+=(h.g=Q)*X,K+=(h.b=U)*X,L+=(h.a=V)*X,A+=P,W+=Q,H+=U,T+=V,h=h.next}d=y,p=g;for(var Y=0;Y<o;Y++){var Z=L*B>>E;if(s[C+3]=Z,0!==Z){var $=255/Z;s[C]=(F*B>>E)*$,s[C+1]=(J*B>>E)*$,s[C+2]=(K*B>>E)*$}else s[C]=s[C+1]=s[C+2]=0;F-=j,J-=k,K-=q,L-=z,j-=d.r,k-=d.g,q-=d.b,z-=d.a;var _=Y+f+1;_=w+(_<c?_:c)<<2,F+=A+=d.r=s[_],J+=W+=d.g=s[_+1],K+=H+=d.b=s[_+2],L+=T+=d.a=s[_+3],d=d.next;var tt=p,rt=tt.r,at=tt.g,nt=tt.b,et=tt.a;j+=rt,k+=at,q+=nt,z+=et,A-=rt,W-=at,H-=nt,T-=et,p=p.next,C+=4}w+=o}for(var ot=0;ot<o;ot++){var it=s[C=ot<<2],ft=s[C+1],gt=s[C+2],vt=s[C+3],st=x*it,ut=x*ft,ct=x*gt,lt=x*vt,xt=b*it,bt=b*ft,yt=b*gt,ht=b*vt;h=y;for(var mt=0;mt<x;mt++)h.r=it,h.g=ft,h.b=gt,h.a=vt,h=h.next;for(var dt=o,pt=0,wt=0,Ct=0,Bt=0,Et=1;Et<=f;Et++){C=dt+ot<<2;var It=x-Et;xt+=(h.r=it=s[C])*It,bt+=(h.g=ft=s[C+1])*It,yt+=(h.b=gt=s[C+2])*It,ht+=(h.a=vt=s[C+3])*It,Bt+=it,pt+=ft,wt+=gt,Ct+=vt,h=h.next,Et<l&&(dt+=o)}C=ot,d=y,p=g;for(var Nt=0;Nt<i;Nt++){var Rt=C<<2;s[Rt+3]=vt=ht*B>>E,vt>0?(vt=255/vt,s[Rt]=(xt*B>>E)*vt,s[Rt+1]=(bt*B>>E)*vt,s[Rt+2]=(yt*B>>E)*vt):s[Rt]=s[Rt+1]=s[Rt+2]=0,xt-=st,bt-=ut,yt-=ct,ht-=lt,st-=d.r,ut-=d.g,ct-=d.b,lt-=d.a,Rt=ot+((Rt=Nt+x)<l?Rt:l)*o<<2,xt+=Bt+=d.r=s[Rt],bt+=pt+=d.g=s[Rt+1],yt+=wt+=d.b=s[Rt+2],ht+=Ct+=d.a=s[Rt+3],d=d.next,st+=it=p.r,ut+=ft=p.g,ct+=gt=p.b,lt+=vt=p.a,Bt-=it,pt-=ft,wt-=gt,Ct-=vt,p=p.next,C+=o}}return t}function f(t,r,a,n,o,i){if(!(isNaN(i)||i<1)){i|=0;var f=e(t,r,a,n,o);f=g(f,r,a,n,o,i),t.getContext("2d").putImageData(f,r,a)}}function g(t,n,e,o,i,f){for(var g,s=t.data,u=2*f+1,c=o-1,l=i-1,x=f+1,b=x*(x+1)/2,y=new v,h=y,m=1;m<u;m++)h=h.next=new v,m===x&&(g=h);h.next=y;for(var d,p,w=null,C=null,B=r[f],E=a[f],I=0,N=0,R=0;R<i;R++){var D=s[N],G=s[N+1],S=s[N+2],A=x*D,W=x*G,H=x*S,T=b*D,j=b*G,k=b*S;h=y;for(var q=0;q<x;q++)h.r=D,h.g=G,h.b=S,h=h.next;for(var z=0,F=0,J=0,K=1;K<x;K++)d=N+((c<K?c:K)<<2),T+=(h.r=D=s[d])*(p=x-K),j+=(h.g=G=s[d+1])*p,k+=(h.b=S=s[d+2])*p,z+=D,F+=G,J+=S,h=h.next;w=y,C=g;for(var L=0;L<o;L++)s[N]=T*B>>E,s[N+1]=j*B>>E,s[N+2]=k*B>>E,T-=A,j-=W,k-=H,A-=w.r,W-=w.g,H-=w.b,d=I+((d=L+f+1)<c?d:c)<<2,T+=z+=w.r=s[d],j+=F+=w.g=s[d+1],k+=J+=w.b=s[d+2],w=w.next,A+=D=C.r,W+=G=C.g,H+=S=C.b,z-=D,F-=G,J-=S,C=C.next,N+=4;I+=o}for(var M=0;M<o;M++){var O=s[N=M<<2],P=s[N+1],Q=s[N+2],U=x*O,V=x*P,X=x*Q,Y=b*O,Z=b*P,$=b*Q;h=y;for(var _=0;_<x;_++)h.r=O,h.g=P,h.b=Q,h=h.next;for(var tt=0,rt=0,at=0,nt=1,et=o;nt<=f;nt++)N=et+M<<2,Y+=(h.r=O=s[N])*(p=x-nt),Z+=(h.g=P=s[N+1])*p,$+=(h.b=Q=s[N+2])*p,tt+=O,rt+=P,at+=Q,h=h.next,nt<l&&(et+=o);N=M,w=y,C=g;for(var ot=0;ot<i;ot++)s[d=N<<2]=Y*B>>E,s[d+1]=Z*B>>E,s[d+2]=$*B>>E,Y-=U,Z-=V,$-=X,U-=w.r,V-=w.g,X-=w.b,d=M+((d=ot+x)<l?d:l)*o<<2,Y+=tt+=w.r=s[d],Z+=rt+=w.g=s[d+1],$+=at+=w.b=s[d+2],w=w.next,U+=O=C.r,V+=P=C.g,X+=Q=C.b,tt-=O,rt-=P,at-=Q,C=C.next,N+=o}return t}var v=function t(){!function(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}(this,t),this.r=0,this.g=0,this.b=0,this.a=0,this.next=null};export{v as BlurStack,f as canvasRGB,o as canvasRGBA,n as image,g as imageDataRGB,i as imageDataRGBA};
|
|
2
|
+
//# sourceMappingURL=stackblur-es.min.js.map
|