uview-plus 3.8.130 → 3.8.136

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.
@@ -0,0 +1,394 @@
1
+ function parseFontSize(font) {
2
+ const matched = String(font || '').match(/(\d+(?:\.\d+)?)px/)
3
+ return matched ? Number(matched[1]) : 10
4
+ }
5
+
6
+ export function createHarmonyCanvasAdapter(options = {}) {
7
+ const legacy = options.context
8
+ if (!legacy) {
9
+ throw new Error('harmony canvas context is required')
10
+ }
11
+
12
+ const width = Number(options.width) > 0 ? Number(options.width) : 1
13
+ const height = Number(options.height) > 0 ? Number(options.height) : 1
14
+
15
+ const state = {
16
+ fillStyle: '#000000',
17
+ strokeStyle: '#000000',
18
+ lineWidth: 1,
19
+ lineCap: 'butt',
20
+ lineJoin: 'miter',
21
+ miterLimit: 10,
22
+ lineDashOffset: 0,
23
+ lineDash: [],
24
+ globalAlpha: 1,
25
+ globalCompositeOperation: 'source-over',
26
+ font: '10px sans-serif'
27
+ }
28
+ const stack = []
29
+ const rafIds = new Set()
30
+ let dirty = false
31
+ let flushing = false
32
+ let destroyed = false
33
+ let flushTimer = null
34
+
35
+ const flush = () => {
36
+ if (destroyed || !dirty || flushing) return
37
+ dirty = false
38
+ flushing = true
39
+ let released = false
40
+ const release = () => {
41
+ if (released) return
42
+ released = true
43
+ flushing = false
44
+ if (dirty) scheduleFlush()
45
+ }
46
+ try {
47
+ if (typeof legacy.draw === 'function') {
48
+ legacy.draw(false, release)
49
+ setTimeout(release, 80)
50
+ } else {
51
+ release()
52
+ }
53
+ } catch (error) {
54
+ release()
55
+ }
56
+ }
57
+
58
+ const scheduleFlush = () => {
59
+ if (destroyed || flushTimer !== null) return
60
+ const timer = setTimeout(() => {
61
+ rafIds.delete(timer)
62
+ if (flushTimer === timer) flushTimer = null
63
+ flush()
64
+ }, 0)
65
+ flushTimer = timer
66
+ rafIds.add(timer)
67
+ }
68
+
69
+ const markDirty = () => {
70
+ dirty = true
71
+ scheduleFlush()
72
+ }
73
+
74
+ const sync = () => {
75
+ if (typeof legacy.setFillStyle === 'function') {
76
+ legacy.setFillStyle(state.fillStyle)
77
+ }
78
+ if (typeof legacy.setStrokeStyle === 'function') {
79
+ legacy.setStrokeStyle(state.strokeStyle)
80
+ }
81
+ if (typeof legacy.setLineWidth === 'function') {
82
+ legacy.setLineWidth(state.lineWidth)
83
+ }
84
+ if (typeof legacy.setLineCap === 'function') {
85
+ legacy.setLineCap(state.lineCap)
86
+ }
87
+ if (typeof legacy.setLineJoin === 'function') {
88
+ legacy.setLineJoin(state.lineJoin)
89
+ }
90
+ if (typeof legacy.setMiterLimit === 'function') {
91
+ legacy.setMiterLimit(state.miterLimit)
92
+ }
93
+ if (typeof legacy.setGlobalAlpha === 'function') {
94
+ legacy.setGlobalAlpha(state.globalAlpha)
95
+ }
96
+ if (typeof legacy.setGlobalCompositeOperation === 'function') {
97
+ legacy.setGlobalCompositeOperation(state.globalCompositeOperation)
98
+ }
99
+ if (typeof legacy.setLineDash === 'function') {
100
+ legacy.setLineDash(state.lineDash, state.lineDashOffset)
101
+ }
102
+ if (typeof legacy.setFontSize === 'function') {
103
+ legacy.setFontSize(parseFontSize(state.font))
104
+ }
105
+ }
106
+
107
+ const canvas = {
108
+ width,
109
+ height,
110
+ getContext() {
111
+ return context
112
+ },
113
+ requestAnimationFrame(callback) {
114
+ const timer = setTimeout(() => {
115
+ rafIds.delete(timer)
116
+ if (destroyed) return
117
+ try {
118
+ callback(Date.now())
119
+ } finally {
120
+ flush()
121
+ }
122
+ }, 33)
123
+ rafIds.add(timer)
124
+ return timer
125
+ },
126
+ cancelAnimationFrame(timer) {
127
+ if (rafIds.has(timer)) {
128
+ clearTimeout(timer)
129
+ rafIds.delete(timer)
130
+ }
131
+ },
132
+ createImage() {
133
+ const image = {
134
+ width: 0,
135
+ height: 0,
136
+ _src: '',
137
+ _localPath: '',
138
+ onload: null,
139
+ onerror: null,
140
+ addEventListener(type, callback) {
141
+ if (type === 'load') image.onload = callback
142
+ if (type === 'error') image.onerror = callback
143
+ }
144
+ }
145
+ Object.defineProperty(image, 'src', {
146
+ get() {
147
+ return image._src
148
+ },
149
+ set(value) {
150
+ image._src = value
151
+ uni.getImageInfo({
152
+ src: value,
153
+ success(result) {
154
+ image.width = result.width || 0
155
+ image.height = result.height || 0
156
+ image._localPath = result.path || value
157
+ if (typeof image.onload === 'function') image.onload()
158
+ },
159
+ fail() {
160
+ if (typeof image.onerror === 'function') image.onerror()
161
+ }
162
+ })
163
+ }
164
+ })
165
+ return image
166
+ }
167
+ }
168
+
169
+ const context = {
170
+ canvas,
171
+ get fillStyle() {
172
+ return state.fillStyle
173
+ },
174
+ set fillStyle(value) {
175
+ state.fillStyle = value
176
+ },
177
+ get strokeStyle() {
178
+ return state.strokeStyle
179
+ },
180
+ set strokeStyle(value) {
181
+ state.strokeStyle = value
182
+ },
183
+ get lineWidth() {
184
+ return state.lineWidth
185
+ },
186
+ set lineWidth(value) {
187
+ state.lineWidth = value
188
+ },
189
+ get lineCap() {
190
+ return state.lineCap
191
+ },
192
+ set lineCap(value) {
193
+ state.lineCap = value
194
+ },
195
+ get lineJoin() {
196
+ return state.lineJoin
197
+ },
198
+ set lineJoin(value) {
199
+ state.lineJoin = value
200
+ },
201
+ get miterLimit() {
202
+ return state.miterLimit
203
+ },
204
+ set miterLimit(value) {
205
+ state.miterLimit = value
206
+ },
207
+ get lineDashOffset() {
208
+ return state.lineDashOffset
209
+ },
210
+ set lineDashOffset(value) {
211
+ state.lineDashOffset = value
212
+ },
213
+ get globalAlpha() {
214
+ return state.globalAlpha
215
+ },
216
+ set globalAlpha(value) {
217
+ state.globalAlpha = value
218
+ },
219
+ get globalCompositeOperation() {
220
+ return state.globalCompositeOperation
221
+ },
222
+ set globalCompositeOperation(value) {
223
+ state.globalCompositeOperation = value
224
+ },
225
+ get font() {
226
+ return state.font
227
+ },
228
+ set font(value) {
229
+ state.font = value
230
+ },
231
+ save() {
232
+ stack.push(Object.assign({}, state))
233
+ if (typeof legacy.save === 'function') legacy.save()
234
+ },
235
+ restore() {
236
+ if (stack.length) Object.assign(state, stack.pop())
237
+ if (typeof legacy.restore === 'function') legacy.restore()
238
+ sync()
239
+ },
240
+ translate(x, y) {
241
+ legacy.translate(x, y)
242
+ },
243
+ scale(x, y) {
244
+ legacy.scale(x, y)
245
+ },
246
+ rotate(angle) {
247
+ legacy.rotate(angle)
248
+ },
249
+ transform(a, b, c, d, e, f) {
250
+ if (typeof legacy.transform === 'function') {
251
+ legacy.transform(a, b, c, d, e, f)
252
+ }
253
+ },
254
+ setTransform(a, b, c, d, e, f) {
255
+ if (typeof legacy.setTransform === 'function') {
256
+ legacy.setTransform(a, b, c, d, e, f)
257
+ } else if (typeof legacy.transform === 'function') {
258
+ legacy.transform(a, b, c, d, e, f)
259
+ }
260
+ },
261
+ beginPath() {
262
+ legacy.beginPath()
263
+ },
264
+ closePath() {
265
+ legacy.closePath()
266
+ },
267
+ moveTo(x, y) {
268
+ legacy.moveTo(x, y)
269
+ },
270
+ lineTo(x, y) {
271
+ legacy.lineTo(x, y)
272
+ },
273
+ bezierCurveTo(a, b, c, d, e, f) {
274
+ legacy.bezierCurveTo(a, b, c, d, e, f)
275
+ },
276
+ quadraticCurveTo(a, b, c, d) {
277
+ if (typeof legacy.quadraticCurveTo === 'function') {
278
+ legacy.quadraticCurveTo(a, b, c, d)
279
+ }
280
+ },
281
+ rect(x, y, w, h) {
282
+ legacy.rect(x, y, w, h)
283
+ },
284
+ arc(x, y, radius, start, end, anticlockwise) {
285
+ if (typeof legacy.arc === 'function') {
286
+ legacy.arc(x, y, radius, start, end, anticlockwise)
287
+ }
288
+ },
289
+ fill() {
290
+ sync()
291
+ legacy.fill()
292
+ markDirty()
293
+ },
294
+ stroke() {
295
+ sync()
296
+ legacy.stroke()
297
+ markDirty()
298
+ },
299
+ clip() {
300
+ if (typeof legacy.clip === 'function') {
301
+ legacy.clip()
302
+ }
303
+ },
304
+ clearRect(x, y, w, h) {
305
+ if (typeof legacy.clearRect === 'function') {
306
+ legacy.clearRect(x, y, w, h)
307
+ }
308
+ markDirty()
309
+ },
310
+ fillRect(x, y, w, h) {
311
+ sync()
312
+ if (typeof legacy.fillRect === 'function') {
313
+ legacy.fillRect(x, y, w, h)
314
+ }
315
+ markDirty()
316
+ },
317
+ strokeRect(x, y, w, h) {
318
+ sync()
319
+ if (typeof legacy.strokeRect === 'function') {
320
+ legacy.strokeRect(x, y, w, h)
321
+ }
322
+ markDirty()
323
+ },
324
+ drawImage() {
325
+ const image = arguments[0]
326
+ const source = image && (image._localPath || image._src || image.src)
327
+ if (!source) return
328
+ sync()
329
+ const args = Array.prototype.slice.call(arguments, 1)
330
+ try {
331
+ if (args.length >= 8) {
332
+ legacy.drawImage(source, args[4], args[5], args[6], args[7])
333
+ } else if (args.length >= 4) {
334
+ legacy.drawImage(source, args[0], args[1], args[2], args[3])
335
+ } else {
336
+ legacy.drawImage(
337
+ source,
338
+ args[0] || 0,
339
+ args[1] || 0,
340
+ image.width || 0,
341
+ image.height || 0
342
+ )
343
+ }
344
+ markDirty()
345
+ } catch (error) {
346
+ // 单张图片绘制失败时跳过,避免中断整个动画
347
+ }
348
+ },
349
+ createLinearGradient(x0, y0, x1, y1) {
350
+ return legacy.createLinearGradient(x0, y0, x1, y1)
351
+ },
352
+ createRadialGradient(x0, y0, r0, x1, y1, r1) {
353
+ return legacy.createRadialGradient(x0, y0, r0, x1, y1, r1)
354
+ },
355
+ setLineDash(segments, offset) {
356
+ state.lineDash = Array.isArray(segments) ? segments.slice() : []
357
+ if (typeof offset === 'number') {
358
+ state.lineDashOffset = offset
359
+ }
360
+ },
361
+ fillText(text, x, y) {
362
+ sync()
363
+ if (typeof legacy.fillText === 'function') {
364
+ legacy.fillText(text, x, y)
365
+ }
366
+ markDirty()
367
+ },
368
+ strokeText(text, x, y) {
369
+ sync()
370
+ if (typeof legacy.strokeText === 'function') {
371
+ legacy.strokeText(text, x, y)
372
+ }
373
+ markDirty()
374
+ },
375
+ measureText(text) {
376
+ const fontSize = parseFontSize(state.font)
377
+ return { width: String(text == null ? '' : text).length * fontSize * 0.6 }
378
+ }
379
+ }
380
+
381
+ return {
382
+ canvas,
383
+ context,
384
+ flush,
385
+ destroy() {
386
+ destroyed = true
387
+ rafIds.forEach((timer) => clearTimeout(timer))
388
+ rafIds.clear()
389
+ flushTimer = null
390
+ dirty = false
391
+ stack.length = 0
392
+ }
393
+ }
394
+ }