vislite 1.2.0 → 1.2.1-alpha.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.
Files changed (162) hide show
  1. package/AUTHORS.txt +6 -6
  2. package/CHANGELOG +279 -274
  3. package/LICENSE +20 -20
  4. package/README.md +175 -175
  5. package/lib/Buffer/index.es.js +1 -1
  6. package/lib/Buffer/index.es.min.js +1 -1
  7. package/lib/Canvas/index.es.js +1 -1
  8. package/lib/Canvas/index.es.min.js +1 -1
  9. package/lib/Cardinal/index.es.js +1 -1
  10. package/lib/Cardinal/index.es.min.js +1 -1
  11. package/lib/Eoap/index.es.js +1 -1
  12. package/lib/Eoap/index.es.min.js +1 -1
  13. package/lib/Hermite/index.es.js +1 -1
  14. package/lib/Hermite/index.es.min.js +1 -1
  15. package/lib/Matrix4/index.es.js +1 -1
  16. package/lib/Matrix4/index.es.min.js +1 -1
  17. package/lib/Mercator/index.es.js +1 -1
  18. package/lib/Mercator/index.es.min.js +1 -1
  19. package/lib/RawCanvas/index.es.js +1 -1
  20. package/lib/RawCanvas/index.es.min.js +1 -1
  21. package/lib/SVG/index.es.js +1 -1
  22. package/lib/SVG/index.es.min.js +1 -1
  23. package/lib/Shader/index.es.js +1 -1
  24. package/lib/Shader/index.es.min.js +1 -1
  25. package/lib/Texture/index.es.js +1 -1
  26. package/lib/Texture/index.es.min.js +1 -1
  27. package/lib/TreeLayout/index.es.js +1 -1
  28. package/lib/TreeLayout/index.es.min.js +1 -1
  29. package/lib/animation/index.es.js +1 -1
  30. package/lib/animation/index.es.min.js +1 -1
  31. package/lib/assemble/index.es.js +1 -1
  32. package/lib/assemble/index.es.min.js +1 -1
  33. package/lib/getLoopColors/index.es.js +1 -1
  34. package/lib/getLoopColors/index.es.min.js +1 -1
  35. package/lib/getWebGLContext/index.es.js +1 -1
  36. package/lib/getWebGLContext/index.es.min.js +1 -1
  37. package/lib/index.umd.js +1 -1
  38. package/lib/index.umd.min.js +1 -1
  39. package/lib/initOption/index.es.js +1 -1
  40. package/lib/initOption/index.es.min.js +1 -1
  41. package/lib/mergeOption/index.es.js +1 -1
  42. package/lib/mergeOption/index.es.min.js +1 -1
  43. package/lib/move/index.es.js +1 -1
  44. package/lib/move/index.es.min.js +1 -1
  45. package/lib/rotate/index.es.js +1 -1
  46. package/lib/rotate/index.es.min.js +1 -1
  47. package/lib/ruler/index.es.js +1 -1
  48. package/lib/ruler/index.es.min.js +1 -1
  49. package/lib/scale/index.es.js +1 -1
  50. package/lib/scale/index.es.min.js +1 -1
  51. package/lib/throttle/index.es.js +1 -1
  52. package/lib/throttle/index.es.min.js +1 -1
  53. package/minialipay/ui-canvas/drawImage.js +35 -35
  54. package/minialipay/ui-canvas/index.acss +4 -4
  55. package/minialipay/ui-canvas/index.axml +3 -3
  56. package/minialipay/ui-canvas/index.d.ts +1 -1
  57. package/minialipay/ui-canvas/index.js +100 -100
  58. package/minialipay/ui-canvas/index.json +6 -6
  59. package/miniprogram/ui-canvas/drawImage.js +35 -35
  60. package/miniprogram/ui-canvas/index.js +117 -117
  61. package/miniprogram/ui-canvas/index.json +4 -4
  62. package/miniprogram/ui-canvas/index.wxml +4 -4
  63. package/miniprogram/ui-canvas/index.wxss +5 -5
  64. package/package/Buffer/index.ts +2 -2
  65. package/package/Canvas/index.ts +2 -2
  66. package/package/Cardinal/index.ts +2 -2
  67. package/package/Eoap/index.ts +2 -2
  68. package/package/Hermite/index.ts +2 -2
  69. package/package/Matrix4/index.ts +2 -2
  70. package/package/Mercator/index.ts +2 -2
  71. package/package/RawCanvas/index.ts +2 -2
  72. package/package/SVG/index.ts +2 -2
  73. package/package/Shader/index.ts +2 -2
  74. package/package/Texture/index.ts +2 -2
  75. package/package/TreeLayout/index.ts +2 -2
  76. package/package/animation/index.ts +2 -2
  77. package/package/assemble/index.ts +2 -2
  78. package/package/getLoopColors/index.ts +2 -2
  79. package/package/getWebGLContext/index.ts +40 -40
  80. package/package/index.ts +75 -75
  81. package/package/initOption/index.ts +2 -2
  82. package/package/mergeOption/index.ts +2 -2
  83. package/package/move/index.ts +2 -2
  84. package/package/rotate/index.ts +2 -2
  85. package/package/ruler/index.ts +2 -2
  86. package/package/scale/index.ts +2 -2
  87. package/package/throttle/index.ts +2 -2
  88. package/package.json +78 -78
  89. package/src/Canvas.ts +84 -84
  90. package/src/Eoap.ts +66 -66
  91. package/src/Matrix4/index.ts +84 -84
  92. package/src/Matrix4/move.ts +12 -12
  93. package/src/Matrix4/rotate.ts +15 -15
  94. package/src/Matrix4/scale.ts +11 -11
  95. package/src/Matrix4/transform.ts +64 -64
  96. package/src/Mercator.ts +27 -27
  97. package/src/SVG.ts +24 -24
  98. package/src/common/assemble.ts +22 -22
  99. package/src/common/canvas/arc.ts +51 -51
  100. package/src/common/canvas/config.ts +158 -158
  101. package/src/common/canvas/default.ts +61 -61
  102. package/src/common/canvas/gradient.ts +31 -31
  103. package/src/common/canvas/index.ts +188 -188
  104. package/src/common/canvas/painter.ts +430 -430
  105. package/src/common/canvas/texts.ts +18 -18
  106. package/src/common/option.ts +29 -29
  107. package/src/common/setStyle.ts +5 -5
  108. package/src/common/svg/config.ts +194 -194
  109. package/src/common/svg/default.ts +26 -26
  110. package/src/common/svg/gradient.ts +53 -53
  111. package/src/common/svg/index.ts +332 -332
  112. package/src/common/svg/tool.ts +42 -42
  113. package/src/common/tree/index.ts +25 -25
  114. package/src/common/tree/toInnerTree.ts +59 -59
  115. package/src/common/tree/toPlainTree.ts +132 -132
  116. package/src/common/type.ts +26 -26
  117. package/src/common/webgl/buffer.ts +79 -79
  118. package/src/common/webgl/getWebGLContext.ts +45 -45
  119. package/src/common/webgl/shader.ts +75 -75
  120. package/src/common/webgl/texture.ts +97 -97
  121. package/src/getLoopColors.ts +42 -42
  122. package/src/interpolation/Cardinal.ts +110 -110
  123. package/src/interpolation/Hermite.ts +65 -65
  124. package/src/layout/TreeLayout.ts +188 -188
  125. package/src/move.ts +7 -7
  126. package/src/rotate.ts +7 -7
  127. package/src/ruler.ts +209 -209
  128. package/src/scale.ts +6 -6
  129. package/types/Buffer.d.ts +23 -23
  130. package/types/Canvas.d.ts +344 -344
  131. package/types/CanvasConfig.d.ts +116 -116
  132. package/types/CanvasOption.d.ts +8 -8
  133. package/types/CanvasOpts.d.ts +9 -9
  134. package/types/Cardinal.d.ts +13 -13
  135. package/types/Gradient.d.ts +14 -14
  136. package/types/Hermite.d.ts +18 -18
  137. package/types/Map.d.ts +9 -9
  138. package/types/Matrix4.d.ts +47 -47
  139. package/types/SVG.d.ts +243 -243
  140. package/types/SVGConfig.d.ts +89 -89
  141. package/types/Shader.d.ts +16 -16
  142. package/types/Texture.d.ts +16 -16
  143. package/types/Tree.d.ts +69 -69
  144. package/types/TreeConfig.d.ts +36 -36
  145. package/types/TreeLayout.d.ts +54 -54
  146. package/types/TreeOption.d.ts +48 -48
  147. package/types/animation.d.ts +5 -5
  148. package/types/assemble.d.ts +5 -5
  149. package/types/getLoopColors.d.ts +5 -5
  150. package/types/getWebGLContext.d.ts +7 -7
  151. package/types/index.d.ts +165 -160
  152. package/types/move.d.ts +5 -5
  153. package/types/option.d.ts +12 -12
  154. package/types/painterConfig.d.ts +4 -4
  155. package/types/rotate.d.ts +5 -5
  156. package/types/ruler.d.ts +10 -10
  157. package/types/scale.d.ts +5 -5
  158. package/types/throttle.d.ts +5 -5
  159. package/types/ui-canvas.d.ts +4 -4
  160. package/types/uni-canvas.d.ts +3 -3
  161. package/uni-app/drawImage.js +19 -19
  162. package/uni-app/ui-canvas.vue +284 -284
@@ -1,431 +1,431 @@
1
- import type CanvasOptsType from '../../../types/CanvasOpts'
2
-
3
- import { initText, initArc, initCircle, initRect } from './config'
4
- import texts from './texts'
5
- import defaultFactory from "./default"
6
-
7
- class Painter {
8
-
9
- painter: CanvasRenderingContext2D
10
- __region: Painter | null | undefined = null
11
-
12
- __onlyRegion: boolean = false
13
- __onlyView: boolean = false
14
-
15
- __isPainter: boolean
16
-
17
- // 用于记录配置
18
- // 因为部分配置的设置比较特殊,只先记录意图
19
- __specialConfig = defaultFactory("special") as {
20
- [key: string]: any
21
- }
22
-
23
- private __initConfig = defaultFactory("init")
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
- constructor(canvas: HTMLCanvasElement, opts: CanvasOptsType = {}, region?: Painter, isPainter = false, scaleSize = 1) {
27
- this.painter = canvas.getContext("2d", opts) as CanvasRenderingContext2D
28
- this.__region = region
29
- this.__isPainter = isPainter
30
-
31
- // 默认配置canvas2D对象已经存在的属性
32
- this.painter.textBaseline = 'middle'
33
- this.painter.textAlign = 'left'
34
- }
35
-
36
- useConfig(key: string, value: any) {
37
- if (this.__region && !this.__onlyView) {
38
- if (['fillStyle', 'strokeStyle', 'shadowBlur', 'shadowColor'].indexOf(key) < 0) {
39
- this.__region.useConfig(key, value)
40
- }
41
- }
42
-
43
- if (this.__isPainter && this.__onlyRegion) return this
44
-
45
- /**
46
- * -----------------------------
47
- * 特殊的设置开始
48
- * -----------------------------
49
- */
50
-
51
- if (key == 'lineDash') {
52
- if (this.painter.setLineDash) this.painter.setLineDash(value)
53
- }
54
-
55
- /**
56
- * -----------------------------
57
- * 常规的配置开始
58
- * -----------------------------
59
- */
60
-
61
- // 如果已经存在默认配置中,说明只需要缓存起来即可
62
- else if (key in this.__specialConfig) {
63
-
64
- // 文字非整数可能存在问题,修复一下
65
- if (key == 'fontSize') {
66
- value = Math.round(value)
67
- }
68
-
69
- this.__specialConfig[key] = value
70
- }
71
-
72
- // 其它情况直接生效即可
73
- else if (key in this.__initConfig) {
74
- (this.painter as any)[key] = value
75
- }
76
-
77
- // 如果属性未被定义
78
- else {
79
- throw new Error('Illegal configuration item of painter : ' + key + " !")
80
- }
81
-
82
- return this
83
- }
84
-
85
- // 文字
86
- fillText(text: string, x: number, y: number, deg: number = 0) {
87
- if (this.__region && !this.__onlyView) this.__region.fillText(text, x, y, deg)
88
-
89
- if (this.__isPainter && this.__onlyRegion) return this
90
-
91
- this.painter.save()
92
- initText(this.painter, this.__specialConfig, x, y, deg).fillText(text, 0, 0)
93
- this.painter.restore()
94
- return this
95
- }
96
- strokeText(text: string, x: number, y: number, deg: number = 0) {
97
- if (this.__region && !this.__onlyView) this.__region.strokeText(text, x, y, deg)
98
-
99
- if (this.__isPainter && this.__onlyRegion) return this
100
-
101
- this.painter.save()
102
- initText(this.painter, this.__specialConfig, x, y, deg).strokeText(text, 0, 0)
103
- this.painter.restore()
104
- return this
105
- }
106
- fullText(text: string, x: number, y: number, deg: number = 0) {
107
- if (this.__region && !this.__onlyView) this.__region.fullText(text, x, y, deg)
108
-
109
- if (this.__isPainter && this.__onlyRegion) return this
110
-
111
- this.painter.save()
112
- initText(this.painter, this.__specialConfig, x, y, deg)
113
- this.painter.fillText(text, 0, 0)
114
- this.painter.strokeText(text, 0, 0)
115
- this.painter.restore()
116
- return this
117
- }
118
-
119
- // 多行文字
120
- fillTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
121
- let h = 0
122
- if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
123
-
124
- if (this.__isPainter && this.__onlyRegion) return h
125
-
126
- this.painter.save()
127
- initText(this.painter, this.__specialConfig, x, y, deg)
128
-
129
- const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
130
- this.painter.fillText(content, 0, top)
131
- })
132
-
133
- this.painter.restore()
134
- return height
135
- }
136
- strokeTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
137
- let h = 0
138
- if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
139
-
140
- if (this.__isPainter && this.__onlyRegion) return h
141
-
142
- this.painter.save()
143
- initText(this.painter, this.__specialConfig, x, y, deg)
144
-
145
- const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
146
- this.painter.strokeText(content, 0, top)
147
- })
148
-
149
- this.painter.restore()
150
- return height
151
- }
152
- fullTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
153
- let h = 0
154
- if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
155
-
156
- if (this.__isPainter && this.__onlyRegion) return h
157
-
158
- this.painter.save()
159
- initText(this.painter, this.__specialConfig, x, y, deg)
160
-
161
- const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
162
- this.painter.fillText(content, 0, top)
163
- this.painter.strokeText(content, 0, top)
164
- })
165
-
166
- this.painter.restore()
167
- return height
168
- }
169
-
170
- // 路径
171
- beginPath() {
172
- if (this.__region && !this.__onlyView) this.__region.beginPath()
173
-
174
- if (this.__isPainter && this.__onlyRegion) return this
175
-
176
- this.painter.beginPath()
177
- return this
178
- }
179
- closePath() {
180
- if (this.__region && !this.__onlyView) this.__region.closePath()
181
-
182
- if (this.__isPainter && this.__onlyRegion) return this
183
-
184
- this.painter.closePath()
185
- return this
186
- }
187
- moveTo(x: number, y: number) {
188
- if (this.__region && !this.__onlyView) this.__region.moveTo(x, y)
189
-
190
- if (this.__isPainter && this.__onlyRegion) return this
191
-
192
- // 解决1px模糊问题,别的地方类似原因
193
- this.painter.moveTo(Math.round(x) + 0.5, Math.round(y) + 0.5)
194
- return this
195
- }
196
- lineTo(x: number, y: number) {
197
- if (this.__region && !this.__onlyView) this.__region.lineTo(x, y)
198
-
199
- if (this.__isPainter && this.__onlyRegion) return this
200
-
201
- this.painter.lineTo(Math.round(x) + 0.5, Math.round(y) + 0.5)
202
- return this
203
- }
204
- arc(x: number, y: number, r: number, beginDeg: number, deg: number) {
205
- if (this.__region && !this.__onlyView) this.__region.arc(x, y, r, beginDeg, deg)
206
-
207
- if (this.__isPainter && this.__onlyRegion) return this
208
-
209
- this.painter.arc(x, y, r, beginDeg, beginDeg + deg, deg < 0)
210
- return this
211
- }
212
- fill() {
213
- if (this.__region && !this.__onlyView) this.__region.fill()
214
-
215
- if (this.__isPainter && this.__onlyRegion) return this
216
-
217
- this.painter.fill()
218
- return this
219
- }
220
- stroke() {
221
- if (this.__region && !this.__onlyView) this.__region.stroke()
222
-
223
- if (this.__isPainter && this.__onlyRegion) return this
224
-
225
- this.painter.stroke()
226
- return this
227
- }
228
- full() {
229
- if (this.__region && !this.__onlyView) this.__region.full()
230
-
231
- if (this.__isPainter && this.__onlyRegion) return this
232
-
233
- this.painter.fill()
234
- this.painter.stroke()
235
- return this
236
- }
237
-
238
- save() {
239
- if (this.__region && !this.__onlyView) this.__region.save()
240
-
241
- if (this.__isPainter && this.__onlyRegion) return this
242
-
243
- this.painter.save()
244
- return this
245
- }
246
- restore() {
247
- if (this.__region && !this.__onlyView) this.__region.restore()
248
-
249
- if (this.__isPainter && this.__onlyRegion) return this
250
-
251
- this.painter.restore()
252
- return this
253
- }
254
- clip() {
255
- if (this.__region && !this.__onlyView) this.__region.clip()
256
-
257
- if (this.__isPainter && this.__onlyRegion) return this
258
-
259
- this.painter.clip()
260
- return this
261
- }
262
-
263
- // 路径 - 贝塞尔曲线
264
- quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
265
- if (this.__region && !this.__onlyView) this.__region.quadraticCurveTo(cpx, cpy, x, y)
266
-
267
- if (this.__isPainter && this.__onlyRegion) return this
268
-
269
- this.painter.quadraticCurveTo(cpx, cpy, x, y)
270
- return this
271
- }
272
- bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number) {
273
- if (this.__region && !this.__onlyView) this.__region.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
274
-
275
- if (this.__isPainter && this.__onlyRegion) return this
276
-
277
- this.painter.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
278
- return this
279
- }
280
-
281
- // 擦除画面
282
- clearRect(x: number, y: number, w: number, h: number) {
283
- if (this.__region && !this.__onlyView) this.__region.clearRect(x, y, w, h)
284
-
285
- if (this.__isPainter && this.__onlyRegion) return this
286
-
287
- this.painter.clearRect(x, y, w, h)
288
- return this
289
- }
290
-
291
- // 弧
292
- fillArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
293
- if (this.__region && !this.__onlyView) this.__region.fillArc(cx, cy, r1, r2, beginDeg, deg)
294
-
295
- if (this.__isPainter && this.__onlyRegion) return this
296
-
297
- initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg).fill()
298
- return this
299
- }
300
- strokeArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
301
- if (this.__region && !this.__onlyView) this.__region.strokeArc(cx, cy, r1, r2, beginDeg, deg)
302
-
303
- if (this.__isPainter && this.__onlyRegion) return this
304
-
305
- initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg).stroke()
306
- return this
307
- }
308
- fullArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
309
- if (this.__region && !this.__onlyView) this.__region.fullArc(cx, cy, r1, r2, beginDeg, deg)
310
-
311
- if (this.__isPainter && this.__onlyRegion) return this
312
-
313
- initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg)
314
- this.painter.fill()
315
- this.painter.stroke()
316
- return this
317
- }
318
-
319
- // 圆形
320
- fillCircle(cx: number, cy: number, r: number) {
321
- if (this.__region && !this.__onlyView) this.__region.fillCircle(cx, cy, r)
322
-
323
- if (this.__isPainter && this.__onlyRegion) return this
324
-
325
- initCircle(this.painter, cx, cy, r).fill()
326
- return this
327
- }
328
- strokeCircle(cx: number, cy: number, r: number) {
329
- if (this.__region && !this.__onlyView) this.__region.strokeCircle(cx, cy, r)
330
-
331
- if (this.__isPainter && this.__onlyRegion) return this
332
-
333
- initCircle(this.painter, cx, cy, r).stroke()
334
- return this
335
- }
336
- fullCircle(cx: number, cy: number, r: number) {
337
- if (this.__region && !this.__onlyView) this.__region.fullCircle(cx, cy, r)
338
-
339
- if (this.__isPainter && this.__onlyRegion) return this
340
-
341
- initCircle(this.painter, cx, cy, r)
342
- this.painter.fill()
343
- this.painter.stroke()
344
- return this
345
- }
346
-
347
- // 矩形
348
- fillRect(x: number, y: number, width: number, height: number) {
349
- if (this.__region && !this.__onlyView) this.__region.fillRect(x, y, width, height)
350
-
351
- if (this.__isPainter && this.__onlyRegion) return this
352
-
353
- initRect(this.painter, x, y, width, height).fill()
354
- return this
355
- }
356
- strokeRect(x: number, y: number, width: number, height: number) {
357
- if (this.__region && !this.__onlyView) this.__region.strokeRect(x, y, width, height)
358
-
359
- if (this.__isPainter && this.__onlyRegion) return this
360
-
361
- initRect(this.painter, x, y, width, height).stroke()
362
- return this
363
- }
364
- fullRect(x: number, y: number, width: number, height: number) {
365
- if (this.__region && !this.__onlyView) this.__region.fullRect(x, y, width, height)
366
-
367
- if (this.__isPainter && this.__onlyRegion) return this
368
-
369
- initRect(this.painter, x, y, width, height)
370
- this.painter.fill()
371
- this.painter.stroke()
372
- return this
373
- }
374
-
375
- // 渲染绘制(uniapp独有)
376
- draw() {
377
-
378
- // 兼容非uniapp环境,防止误用
379
- // 2024年4月3日 于南京
380
- return Promise.resolve()
381
- }
382
-
383
- // 绘制图片
384
- drawImage(img: CanvasImageSource | string, x: number, y: number, w: number, h: number, isImage: boolean = false) {
385
- return new Promise((resolve) => {
386
- if (this.__region && !this.__onlyView) {
387
- this.__region.fillRect(x, y, w, h)
388
- }
389
-
390
- if (this.__isPainter && this.__onlyRegion) {
391
- resolve({})
392
- return
393
- }
394
-
395
- if (typeof img == 'string' && !isImage) {
396
- const imgInstance = new Image()
397
- imgInstance.onload = () => {
398
- this.painter.drawImage(imgInstance, x, y, w, h)
399
- resolve({})
400
- }
401
- imgInstance.src = img
402
- } else {
403
- this.painter.drawImage(img as CanvasImageSource, x, y, w, h)
404
- resolve({})
405
- }
406
-
407
- })
408
- }
409
-
410
- // 扩展绘制方法
411
- install(methods: {
412
- [key: string]: Function
413
- }): any {
414
- for (let key in methods) {
415
-
416
- if (key in this) {
417
- throw new Error("VISLite Canvas:Method already exists and cannot be overwritten.")
418
- } else {
419
- (this as any)[key] = (...args: any) => {
420
- let value = methods[key].apply(this, args)
421
- if (value != void 0) return value
422
- return this
423
- }
424
- }
425
-
426
- }
427
- return this
428
- }
429
- }
430
-
1
+ import type CanvasOptsType from '../../../types/CanvasOpts'
2
+
3
+ import { initText, initArc, initCircle, initRect } from './config'
4
+ import texts from './texts'
5
+ import defaultFactory from "./default"
6
+
7
+ class Painter {
8
+
9
+ painter: CanvasRenderingContext2D
10
+ __region: Painter | null | undefined = null
11
+
12
+ __onlyRegion: boolean = false
13
+ __onlyView: boolean = false
14
+
15
+ __isPainter: boolean
16
+
17
+ // 用于记录配置
18
+ // 因为部分配置的设置比较特殊,只先记录意图
19
+ __specialConfig = defaultFactory("special") as {
20
+ [key: string]: any
21
+ }
22
+
23
+ private __initConfig = defaultFactory("init")
24
+
25
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
+ constructor(canvas: HTMLCanvasElement, opts: CanvasOptsType = {}, region?: Painter, isPainter = false, scaleSize = 1) {
27
+ this.painter = canvas.getContext("2d", opts) as CanvasRenderingContext2D
28
+ this.__region = region
29
+ this.__isPainter = isPainter
30
+
31
+ // 默认配置canvas2D对象已经存在的属性
32
+ this.painter.textBaseline = 'middle'
33
+ this.painter.textAlign = 'left'
34
+ }
35
+
36
+ useConfig(key: string, value: any) {
37
+ if (this.__region && !this.__onlyView) {
38
+ if (['fillStyle', 'strokeStyle', 'shadowBlur', 'shadowColor'].indexOf(key) < 0) {
39
+ this.__region.useConfig(key, value)
40
+ }
41
+ }
42
+
43
+ if (this.__isPainter && this.__onlyRegion) return this
44
+
45
+ /**
46
+ * -----------------------------
47
+ * 特殊的设置开始
48
+ * -----------------------------
49
+ */
50
+
51
+ if (key == 'lineDash') {
52
+ if (this.painter.setLineDash) this.painter.setLineDash(value)
53
+ }
54
+
55
+ /**
56
+ * -----------------------------
57
+ * 常规的配置开始
58
+ * -----------------------------
59
+ */
60
+
61
+ // 如果已经存在默认配置中,说明只需要缓存起来即可
62
+ else if (key in this.__specialConfig) {
63
+
64
+ // 文字非整数可能存在问题,修复一下
65
+ if (key == 'fontSize') {
66
+ value = Math.round(value)
67
+ }
68
+
69
+ this.__specialConfig[key] = value
70
+ }
71
+
72
+ // 其它情况直接生效即可
73
+ else if (key in this.__initConfig) {
74
+ (this.painter as any)[key] = value
75
+ }
76
+
77
+ // 如果属性未被定义
78
+ else {
79
+ throw new Error('Illegal configuration item of painter : ' + key + " !")
80
+ }
81
+
82
+ return this
83
+ }
84
+
85
+ // 文字
86
+ fillText(text: string, x: number, y: number, deg: number = 0) {
87
+ if (this.__region && !this.__onlyView) this.__region.fillText(text, x, y, deg)
88
+
89
+ if (this.__isPainter && this.__onlyRegion) return this
90
+
91
+ this.painter.save()
92
+ initText(this.painter, this.__specialConfig, x, y, deg).fillText(text, 0, 0)
93
+ this.painter.restore()
94
+ return this
95
+ }
96
+ strokeText(text: string, x: number, y: number, deg: number = 0) {
97
+ if (this.__region && !this.__onlyView) this.__region.strokeText(text, x, y, deg)
98
+
99
+ if (this.__isPainter && this.__onlyRegion) return this
100
+
101
+ this.painter.save()
102
+ initText(this.painter, this.__specialConfig, x, y, deg).strokeText(text, 0, 0)
103
+ this.painter.restore()
104
+ return this
105
+ }
106
+ fullText(text: string, x: number, y: number, deg: number = 0) {
107
+ if (this.__region && !this.__onlyView) this.__region.fullText(text, x, y, deg)
108
+
109
+ if (this.__isPainter && this.__onlyRegion) return this
110
+
111
+ this.painter.save()
112
+ initText(this.painter, this.__specialConfig, x, y, deg)
113
+ this.painter.fillText(text, 0, 0)
114
+ this.painter.strokeText(text, 0, 0)
115
+ this.painter.restore()
116
+ return this
117
+ }
118
+
119
+ // 多行文字
120
+ fillTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
121
+ let h = 0
122
+ if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
123
+
124
+ if (this.__isPainter && this.__onlyRegion) return h
125
+
126
+ this.painter.save()
127
+ initText(this.painter, this.__specialConfig, x, y, deg)
128
+
129
+ const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
130
+ this.painter.fillText(content, 0, top)
131
+ })
132
+
133
+ this.painter.restore()
134
+ return height
135
+ }
136
+ strokeTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
137
+ let h = 0
138
+ if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
139
+
140
+ if (this.__isPainter && this.__onlyRegion) return h
141
+
142
+ this.painter.save()
143
+ initText(this.painter, this.__specialConfig, x, y, deg)
144
+
145
+ const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
146
+ this.painter.strokeText(content, 0, top)
147
+ })
148
+
149
+ this.painter.restore()
150
+ return height
151
+ }
152
+ fullTexts(contents: string, x: number, y: number, width: number, lineHeight: number = 1.2, deg: number = 0) {
153
+ let h = 0
154
+ if (this.__region && !this.__onlyView) h = this.__region.fillTexts(contents, x, y, width, lineHeight)
155
+
156
+ if (this.__isPainter && this.__onlyRegion) return h
157
+
158
+ this.painter.save()
159
+ initText(this.painter, this.__specialConfig, x, y, deg)
160
+
161
+ const height = texts(this.painter, contents, width, this.__specialConfig.fontSize * lineHeight, (content, top) => {
162
+ this.painter.fillText(content, 0, top)
163
+ this.painter.strokeText(content, 0, top)
164
+ })
165
+
166
+ this.painter.restore()
167
+ return height
168
+ }
169
+
170
+ // 路径
171
+ beginPath() {
172
+ if (this.__region && !this.__onlyView) this.__region.beginPath()
173
+
174
+ if (this.__isPainter && this.__onlyRegion) return this
175
+
176
+ this.painter.beginPath()
177
+ return this
178
+ }
179
+ closePath() {
180
+ if (this.__region && !this.__onlyView) this.__region.closePath()
181
+
182
+ if (this.__isPainter && this.__onlyRegion) return this
183
+
184
+ this.painter.closePath()
185
+ return this
186
+ }
187
+ moveTo(x: number, y: number) {
188
+ if (this.__region && !this.__onlyView) this.__region.moveTo(x, y)
189
+
190
+ if (this.__isPainter && this.__onlyRegion) return this
191
+
192
+ // 解决1px模糊问题,别的地方类似原因
193
+ this.painter.moveTo(Math.round(x) + 0.5, Math.round(y) + 0.5)
194
+ return this
195
+ }
196
+ lineTo(x: number, y: number) {
197
+ if (this.__region && !this.__onlyView) this.__region.lineTo(x, y)
198
+
199
+ if (this.__isPainter && this.__onlyRegion) return this
200
+
201
+ this.painter.lineTo(Math.round(x) + 0.5, Math.round(y) + 0.5)
202
+ return this
203
+ }
204
+ arc(x: number, y: number, r: number, beginDeg: number, deg: number) {
205
+ if (this.__region && !this.__onlyView) this.__region.arc(x, y, r, beginDeg, deg)
206
+
207
+ if (this.__isPainter && this.__onlyRegion) return this
208
+
209
+ this.painter.arc(x, y, r, beginDeg, beginDeg + deg, deg < 0)
210
+ return this
211
+ }
212
+ fill() {
213
+ if (this.__region && !this.__onlyView) this.__region.fill()
214
+
215
+ if (this.__isPainter && this.__onlyRegion) return this
216
+
217
+ this.painter.fill()
218
+ return this
219
+ }
220
+ stroke() {
221
+ if (this.__region && !this.__onlyView) this.__region.stroke()
222
+
223
+ if (this.__isPainter && this.__onlyRegion) return this
224
+
225
+ this.painter.stroke()
226
+ return this
227
+ }
228
+ full() {
229
+ if (this.__region && !this.__onlyView) this.__region.full()
230
+
231
+ if (this.__isPainter && this.__onlyRegion) return this
232
+
233
+ this.painter.fill()
234
+ this.painter.stroke()
235
+ return this
236
+ }
237
+
238
+ save() {
239
+ if (this.__region && !this.__onlyView) this.__region.save()
240
+
241
+ if (this.__isPainter && this.__onlyRegion) return this
242
+
243
+ this.painter.save()
244
+ return this
245
+ }
246
+ restore() {
247
+ if (this.__region && !this.__onlyView) this.__region.restore()
248
+
249
+ if (this.__isPainter && this.__onlyRegion) return this
250
+
251
+ this.painter.restore()
252
+ return this
253
+ }
254
+ clip() {
255
+ if (this.__region && !this.__onlyView) this.__region.clip()
256
+
257
+ if (this.__isPainter && this.__onlyRegion) return this
258
+
259
+ this.painter.clip()
260
+ return this
261
+ }
262
+
263
+ // 路径 - 贝塞尔曲线
264
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
265
+ if (this.__region && !this.__onlyView) this.__region.quadraticCurveTo(cpx, cpy, x, y)
266
+
267
+ if (this.__isPainter && this.__onlyRegion) return this
268
+
269
+ this.painter.quadraticCurveTo(cpx, cpy, x, y)
270
+ return this
271
+ }
272
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number) {
273
+ if (this.__region && !this.__onlyView) this.__region.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
274
+
275
+ if (this.__isPainter && this.__onlyRegion) return this
276
+
277
+ this.painter.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
278
+ return this
279
+ }
280
+
281
+ // 擦除画面
282
+ clearRect(x: number, y: number, w: number, h: number) {
283
+ if (this.__region && !this.__onlyView) this.__region.clearRect(x, y, w, h)
284
+
285
+ if (this.__isPainter && this.__onlyRegion) return this
286
+
287
+ this.painter.clearRect(x, y, w, h)
288
+ return this
289
+ }
290
+
291
+ // 弧
292
+ fillArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
293
+ if (this.__region && !this.__onlyView) this.__region.fillArc(cx, cy, r1, r2, beginDeg, deg)
294
+
295
+ if (this.__isPainter && this.__onlyRegion) return this
296
+
297
+ initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg).fill()
298
+ return this
299
+ }
300
+ strokeArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
301
+ if (this.__region && !this.__onlyView) this.__region.strokeArc(cx, cy, r1, r2, beginDeg, deg)
302
+
303
+ if (this.__isPainter && this.__onlyRegion) return this
304
+
305
+ initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg).stroke()
306
+ return this
307
+ }
308
+ fullArc(cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) {
309
+ if (this.__region && !this.__onlyView) this.__region.fullArc(cx, cy, r1, r2, beginDeg, deg)
310
+
311
+ if (this.__isPainter && this.__onlyRegion) return this
312
+
313
+ initArc(this.painter, this.__specialConfig, cx, cy, r1, r2, beginDeg, deg)
314
+ this.painter.fill()
315
+ this.painter.stroke()
316
+ return this
317
+ }
318
+
319
+ // 圆形
320
+ fillCircle(cx: number, cy: number, r: number) {
321
+ if (this.__region && !this.__onlyView) this.__region.fillCircle(cx, cy, r)
322
+
323
+ if (this.__isPainter && this.__onlyRegion) return this
324
+
325
+ initCircle(this.painter, cx, cy, r).fill()
326
+ return this
327
+ }
328
+ strokeCircle(cx: number, cy: number, r: number) {
329
+ if (this.__region && !this.__onlyView) this.__region.strokeCircle(cx, cy, r)
330
+
331
+ if (this.__isPainter && this.__onlyRegion) return this
332
+
333
+ initCircle(this.painter, cx, cy, r).stroke()
334
+ return this
335
+ }
336
+ fullCircle(cx: number, cy: number, r: number) {
337
+ if (this.__region && !this.__onlyView) this.__region.fullCircle(cx, cy, r)
338
+
339
+ if (this.__isPainter && this.__onlyRegion) return this
340
+
341
+ initCircle(this.painter, cx, cy, r)
342
+ this.painter.fill()
343
+ this.painter.stroke()
344
+ return this
345
+ }
346
+
347
+ // 矩形
348
+ fillRect(x: number, y: number, width: number, height: number) {
349
+ if (this.__region && !this.__onlyView) this.__region.fillRect(x, y, width, height)
350
+
351
+ if (this.__isPainter && this.__onlyRegion) return this
352
+
353
+ initRect(this.painter, x, y, width, height).fill()
354
+ return this
355
+ }
356
+ strokeRect(x: number, y: number, width: number, height: number) {
357
+ if (this.__region && !this.__onlyView) this.__region.strokeRect(x, y, width, height)
358
+
359
+ if (this.__isPainter && this.__onlyRegion) return this
360
+
361
+ initRect(this.painter, x, y, width, height).stroke()
362
+ return this
363
+ }
364
+ fullRect(x: number, y: number, width: number, height: number) {
365
+ if (this.__region && !this.__onlyView) this.__region.fullRect(x, y, width, height)
366
+
367
+ if (this.__isPainter && this.__onlyRegion) return this
368
+
369
+ initRect(this.painter, x, y, width, height)
370
+ this.painter.fill()
371
+ this.painter.stroke()
372
+ return this
373
+ }
374
+
375
+ // 渲染绘制(uniapp独有)
376
+ draw() {
377
+
378
+ // 兼容非uniapp环境,防止误用
379
+ // 2024年4月3日 于南京
380
+ return Promise.resolve()
381
+ }
382
+
383
+ // 绘制图片
384
+ drawImage(img: CanvasImageSource | string, x: number, y: number, w: number, h: number, isImage: boolean = false) {
385
+ return new Promise((resolve) => {
386
+ if (this.__region && !this.__onlyView) {
387
+ this.__region.fillRect(x, y, w, h)
388
+ }
389
+
390
+ if (this.__isPainter && this.__onlyRegion) {
391
+ resolve({})
392
+ return
393
+ }
394
+
395
+ if (typeof img == 'string' && !isImage) {
396
+ const imgInstance = new Image()
397
+ imgInstance.onload = () => {
398
+ this.painter.drawImage(imgInstance, x, y, w, h)
399
+ resolve({})
400
+ }
401
+ imgInstance.src = img
402
+ } else {
403
+ this.painter.drawImage(img as CanvasImageSource, x, y, w, h)
404
+ resolve({})
405
+ }
406
+
407
+ })
408
+ }
409
+
410
+ // 扩展绘制方法
411
+ install(methods: {
412
+ [key: string]: Function
413
+ }): any {
414
+ for (let key in methods) {
415
+
416
+ if (key in this) {
417
+ throw new Error("VISLite Canvas:Method already exists and cannot be overwritten.")
418
+ } else {
419
+ (this as any)[key] = (...args: any) => {
420
+ let value = methods[key].apply(this, args)
421
+ if (value != void 0) return value
422
+ return this
423
+ }
424
+ }
425
+
426
+ }
427
+ return this
428
+ }
429
+ }
430
+
431
431
  export default Painter