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