@leafer/canvas-web 1.0.0-alpha.21 → 1.0.0-alpha.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer/canvas-web",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "@leafer/canvas-web",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -19,11 +19,11 @@
19
19
  "leaferjs"
20
20
  ],
21
21
  "dependencies": {
22
- "@leafer/math": "1.0.0-alpha.21",
23
- "@leafer/event": "1.0.0-alpha.21",
24
- "@leafer/debug": "1.0.0-alpha.21"
22
+ "@leafer/math": "1.0.0-alpha.30",
23
+ "@leafer/event": "1.0.0-alpha.30",
24
+ "@leafer/debug": "1.0.0-alpha.30"
25
25
  },
26
26
  "devDependencies": {
27
- "@leafer/interface": "1.0.0-alpha.21"
27
+ "@leafer/interface": "1.0.0-alpha.30"
28
28
  }
29
29
  }
@@ -1,71 +1,47 @@
1
- import { IBounds, ILeaferCanvas, ICanvasStrokeOptions, ICanvasContext2D, ILeaferCanvasConfig, IMatrixData, IBoundsData, IAutoBounds, ISizeData, IScreenSizeData, IResizeEventListener, IMatrixWithBoundsData, IPointData, InnerId, ICanvasManager, IWindingRule } from '@leafer/interface'
2
- import { Bounds, BoundsHelper, IncrementId } from '@leafer/math'
1
+ import { ICanvasContext2D, IAutoBounds, ISizeData, IScreenSizeData, IResizeEventListener } from '@leafer/interface'
3
2
  import { ResizeEvent } from '@leafer/event'
4
- import { Platform } from '@leafer/platform'
3
+ import { LeaferCanvasBase } from '@leafer/canvas'
5
4
  import { Debug } from '@leafer/debug'
6
5
 
7
- import { CanvasBase } from './CanvasBase'
8
-
9
6
 
10
7
  const debug = Debug.get('LeaferCanvas')
11
8
 
12
- const temp = new Bounds()
13
- const minSize: IScreenSizeData = {
14
- width: 1,
15
- height: 1,
16
- pixelRatio: 1
17
- }
18
-
19
- export class LeaferCanvas extends CanvasBase implements ILeaferCanvas {
20
-
21
- public manager: ICanvasManager
22
-
23
- public readonly innerId: InnerId
24
-
25
- public pixelRatio: number
26
- public get pixelWidth(): number { return this.width * this.pixelRatio }
27
- public get pixelHeight(): number { return this.height * this.pixelRatio }
28
-
29
- public bounds: IBounds
9
+ export class LeaferCanvas extends LeaferCanvasBase {
30
10
 
31
11
  public view: HTMLCanvasElement | OffscreenCanvas
32
- public offscreen: boolean
33
-
34
- public recycled?: boolean
12
+ public parentView: HTMLElement
35
13
 
36
14
  protected resizeObserver: ResizeObserver
37
15
 
38
- constructor(config?: ILeaferCanvasConfig, manager?: ICanvasManager) {
39
- super()
40
-
41
- if (!config) config = minSize
42
-
43
- this.manager = manager
44
- this.innerId = IncrementId.create(IncrementId.CNAVAS)
45
-
46
- const { view, width, height, pixelRatio, fill, hittable: hitable } = config
47
- const autoLayout = !width || !height
48
-
49
- this.pixelRatio = pixelRatio
50
- this.offscreen = Platform.isWorker || config.offscreen
16
+ public init(): void {
17
+ const { view } = this.config
51
18
 
52
19
  if (this.offscreen) {
53
20
  view ? this.view = view as OffscreenCanvas : this.__createView()
54
21
  } else {
55
22
  view ? this.__createViewFrom(view) : this.__createView()
56
23
  const { style } = this.view as HTMLCanvasElement
57
- if (fill) style.backgroundColor = fill
58
- if (!hitable) style.pointerEvents = 'none'
59
- if (autoLayout) style.display || (style.display = 'block')
24
+ if (this.autoLayout) style.display || (style.display = 'block')
25
+ this.parentView = (this.view as HTMLCanvasElement).parentElement
60
26
  }
61
27
 
62
- this.__init()
63
- if (!autoLayout) this.resize(config as IScreenSizeData)
28
+ this.__createContext()
29
+
30
+ if (!this.autoLayout) this.resize(this.config as IScreenSizeData)
64
31
  }
65
32
 
66
- protected __init(): void {
33
+ public setBackgroundColor(color: string): void {
34
+ const view = this.view as HTMLElement
35
+ view.style.backgroundColor = color
36
+ }
37
+
38
+ public setHittable(hittable: boolean): void {
39
+ const view = this.view as HTMLElement
40
+ view.style.pointerEvents = hittable ? 'auto' : 'none'
41
+ }
42
+
43
+ protected __createContext(): void {
67
44
  this.context = this.view.getContext('2d') as ICanvasContext2D
68
- this.smooth = true
69
45
  this.__bindContext()
70
46
  }
71
47
 
@@ -88,7 +64,6 @@ export class LeaferCanvas extends CanvasBase implements ILeaferCanvas {
88
64
  const { style } = div
89
65
  style.position = 'absolute'
90
66
  style.top = style.bottom = style.left = style.right = '0px'
91
- style.overflow = 'hidden'
92
67
  document.body.appendChild(div)
93
68
  parent = div
94
69
  }
@@ -106,12 +81,23 @@ export class LeaferCanvas extends CanvasBase implements ILeaferCanvas {
106
81
  parent.appendChild(view)
107
82
  }
108
83
  } else {
109
- debug.error(`can't find view by id: ${inputView}`)
84
+ debug.error(`no id: ${inputView}`)
110
85
  this.__createView()
111
86
  }
112
87
  }
113
88
 
114
- public pixel(num: number): number { return num * this.pixelRatio }
89
+ public setViewSize(size: IScreenSizeData): void {
90
+ const { width, height, pixelRatio } = size
91
+
92
+ if (!this.offscreen) {
93
+ const { style } = this.view as HTMLCanvasElement
94
+ style.width = width + 'px'
95
+ style.height = height + 'px'
96
+ }
97
+
98
+ this.view.width = width * pixelRatio
99
+ this.view.height = height * pixelRatio
100
+ }
115
101
 
116
102
  public startAutoLayout(autoBounds: IAutoBounds, listener: IResizeEventListener): void {
117
103
  if (!this.offscreen) {
@@ -137,7 +123,7 @@ export class LeaferCanvas extends CanvasBase implements ILeaferCanvas {
137
123
  }
138
124
  })
139
125
 
140
- const parent = view.parentElement
126
+ const parent = this.parentView
141
127
  if (parent) {
142
128
  this.resizeObserver.observe(parent)
143
129
  check(parent.getBoundingClientRect())
@@ -149,224 +135,28 @@ export class LeaferCanvas extends CanvasBase implements ILeaferCanvas {
149
135
  if (this.resizeObserver) {
150
136
  this.resizeObserver.disconnect()
151
137
  this.resizeObserver = null
138
+ this.autoLayout = false
152
139
  }
153
140
  }
154
141
 
155
- public resize(size: IScreenSizeData): void {
156
- const { width, height, pixelRatio } = size
157
- if (this.isSameSize(size)) return
158
-
159
- let takeCanvas: ILeaferCanvas
160
- if (this.context && this.width) {
161
- takeCanvas = this.getSameCanvas()
162
- takeCanvas.copyWorld(this)
163
- }
164
-
165
- Object.assign(this, { width, height, pixelRatio })
166
- this.bounds = new Bounds(0, 0, width, height)
167
-
168
- if (!this.offscreen) {
169
- const { style } = this.view as HTMLCanvasElement
170
- style.width = width + 'px'
171
- style.height = height + 'px'
172
- }
173
-
174
- this.view.width = width * pixelRatio
175
- this.view.height = height * pixelRatio
176
-
177
- if (this.context && takeCanvas) {
178
- this.copyWorld(takeCanvas)
179
- takeCanvas.recycle()
180
- }
181
- }
182
-
183
- public setWorld(matrix: IMatrixData, parentMatrix?: IMatrixData, onlyTranslate?: boolean): void {
184
- const { pixelRatio } = this
185
- if (parentMatrix) {
186
-
187
- if (onlyTranslate) {
188
- this.setTransform(
189
- matrix.a * pixelRatio,
190
- matrix.b * pixelRatio,
191
- matrix.c * pixelRatio,
192
- matrix.d * pixelRatio,
193
- (matrix.e + parentMatrix.e) * pixelRatio,
194
- (matrix.f + parentMatrix.f) * pixelRatio
195
- )
196
- } else {
197
- const { a, b, c, d, e, f } = parentMatrix
198
- this.setTransform(
199
- ((matrix.a * a) + (matrix.b * c)) * pixelRatio,
200
- ((matrix.a * b) + (matrix.b * d)) * pixelRatio,
201
- ((matrix.c * a) + (matrix.d * c)) * pixelRatio,
202
- ((matrix.c * b) + (matrix.d * d)) * pixelRatio,
203
- (((matrix.e * a) + (matrix.f * c) + e)) * pixelRatio,
204
- (((matrix.e * b) + (matrix.f * d) + f)) * pixelRatio
205
- )
206
- }
207
-
208
- } else {
209
-
210
- this.setTransform(
211
- matrix.a * pixelRatio,
212
- matrix.b * pixelRatio,
213
- matrix.c * pixelRatio,
214
- matrix.d * pixelRatio,
215
- matrix.e * pixelRatio,
216
- matrix.f * pixelRatio
217
- )
218
- }
219
- }
220
-
221
- public useSameTransform(canvas: ILeaferCanvas): void {
222
- this.setTransform(canvas.getTransform())
223
- }
224
-
225
-
226
- public setStroke(strokeStyle: string | object, strokeWidth: number, options?: ICanvasStrokeOptions): void {
227
-
228
- if (strokeWidth) this.strokeWidth = strokeWidth
229
- if (strokeStyle) this.strokeStyle = strokeStyle
230
- if (options) {
231
- this.strokeCap = options.strokeCap
232
- this.strokeJoin = options.strokeJoin
233
- this.dashPattern = options.dashPattern
234
- this.miterLimit = options.miterLimit
235
- }
236
- }
237
-
238
- public hitPath(point: IPointData, fillRule?: IWindingRule): boolean {
239
- return this.context.isPointInPath(point.x, point.y, fillRule)
240
- }
241
-
242
- public hitStroke(point: IPointData): boolean {
243
- return this.context.isPointInStroke(point.x, point.y)
244
- }
245
-
246
-
247
- public setWorldShadow(x: number, y: number, blur: number, color?: string): void {
248
- const { pixelRatio } = this
249
- this.shadowOffsetX = x * pixelRatio
250
- this.shadowOffsetY = y * pixelRatio
251
- this.shadowBlur = blur * pixelRatio
252
- this.shadowColor = color || 'black'
253
- }
254
-
255
- public setWorldBlur(blur: number): void {
256
- const { pixelRatio } = this
257
- this.filter = `blur(${blur * pixelRatio}px)`
258
- }
259
-
260
-
261
- public copyWorld(canvas: ILeaferCanvas, from?: IBoundsData, to?: IBoundsData, blendMode?: string): void {
262
- if (from) {
263
- if (!to) to = from
264
- const { pixelRatio } = this
265
- if (blendMode) this.blendMode = blendMode
266
- this.drawImage(canvas.view as HTMLCanvasElement, from.x * pixelRatio, from.y * pixelRatio, from.width * pixelRatio, from.height * pixelRatio, to.x * pixelRatio, to.y * pixelRatio, to.width * pixelRatio, to.height * pixelRatio)
267
- if (blendMode) this.blendMode = 'normal'
268
- } else {
269
- this.drawImage(canvas.view as HTMLCanvasElement, 0, 0)
270
- }
271
-
272
- }
142
+ public unrealCanvas(): void { // App needs to use
143
+ if (!this.unreal && this.parentView) {
144
+ const view = this.view as HTMLCanvasElement
145
+ if (view) view.remove()
273
146
 
274
- public copyWorldToLocal(canvas: ILeaferCanvas, fromWorld: IMatrixWithBoundsData, toLocalBounds: IBoundsData, blendMode?: string): void {
275
- const { pixelRatio } = this
276
- if (blendMode) this.blendMode = blendMode
277
- if (fromWorld.b || fromWorld.c) {
278
- this.save()
279
- this.resetTransform()
280
- this.copyWorld(canvas, fromWorld, BoundsHelper.tempToWorld(toLocalBounds, fromWorld))
281
- this.restore()
282
- } else {
283
- this.drawImage(canvas.view as HTMLCanvasElement, fromWorld.x * pixelRatio, fromWorld.y * pixelRatio, fromWorld.width * pixelRatio, fromWorld.height * pixelRatio, toLocalBounds.x, toLocalBounds.y, toLocalBounds.width, toLocalBounds.height)
147
+ this.view = this.parentView as HTMLCanvasElement
148
+ this.unreal = true
284
149
  }
285
- if (blendMode) this.blendMode = 'normal'
286
150
  }
287
151
 
288
- public fillWorld(bounds: IBoundsData, color: string | object, blendMode?: string): void {
289
- const { pixelRatio } = this
290
- if (blendMode) this.blendMode = blendMode
291
- this.fillStyle = color
292
- this.fillRect(bounds.x * pixelRatio, bounds.y * pixelRatio, bounds.width * pixelRatio, bounds.height * pixelRatio)
293
- if (blendMode) this.blendMode = 'normal'
294
- }
295
-
296
- public strokeWorld(bounds: IBoundsData, color: string | object, blendMode?: string): void {
297
- const { pixelRatio } = this
298
- if (blendMode) this.blendMode = blendMode
299
- this.strokeStyle = color
300
- this.strokeRect(bounds.x * pixelRatio, bounds.y * pixelRatio, bounds.width * pixelRatio, bounds.height * pixelRatio)
301
- if (blendMode) this.blendMode = 'normal'
302
- }
303
-
304
- public clearWorld(bounds: IBoundsData, ceilPixel?: boolean): void {
305
- const { pixelRatio } = this
306
- temp.copy(bounds).scale(pixelRatio)
307
- if (ceilPixel) temp.ceil()
308
- this.clearRect(temp.x, temp.y, temp.width, temp.height)
309
- }
310
-
311
- public clipWorld(bounds: IBoundsData, ceilPixel?: boolean): void {
312
- const { pixelRatio } = this
313
- this.beginPath()
314
- temp.copy(bounds).scale(pixelRatio)
315
- if (ceilPixel) temp.ceil()
316
- this.rect(temp.x, temp.y, temp.width, temp.height)
317
- this.clip()
318
-
319
- }
320
-
321
- public clear(): void {
322
- const { pixelRatio } = this
323
- this.clearRect(0, 0, this.width * pixelRatio, this.height * pixelRatio)
324
- }
325
-
326
-
327
- // other
328
-
329
- public isSameSize(size: IScreenSizeData): boolean {
330
- return this.width === size.width && this.height === size.height && this.pixelRatio === size.pixelRatio
331
- }
332
-
333
- // 需要有 manager变量
334
- public getSameCanvas(useSameTransform?: boolean): ILeaferCanvas {
335
- const { width, height, pixelRatio } = this
336
- const canvas = this.manager.get({ width, height, pixelRatio })
337
- canvas.manager || (canvas.manager = this.manager)
338
- canvas.save()
339
- if (useSameTransform) canvas.useSameTransform(this)
340
- return canvas
341
- }
342
-
343
- public getBiggerCanvas(addWidth: number, addHeight: number): ILeaferCanvas {
344
- let { width, height, pixelRatio } = this
345
- if (addWidth) width += addWidth
346
- if (addHeight) height += addHeight
347
- const canvas = this.manager.get({ width, height, pixelRatio })
348
- canvas.manager || (canvas.manager = this.manager)
349
- canvas.save()
350
- return canvas
351
- }
352
-
353
- public recycle(): void {
354
- this.restore()
355
- this.manager.recycle(this)
356
- }
357
-
358
-
359
152
  public destroy(): void {
360
153
  if (this.view) {
361
- super.destroy()
362
154
  this.stopAutoLayout()
363
- if (!this.offscreen) {
155
+ if (!this.unreal && !this.offscreen) {
364
156
  const view = this.view as HTMLCanvasElement
365
157
  if (view.parentElement) view.remove()
366
158
  }
367
- this.manager = null
368
- this.view = null
369
- this.context = null
159
+ super.destroy()
370
160
  }
371
161
  }
372
162
 
@@ -1,61 +1,16 @@
1
- import { IObject } from '@leafer/interface'
1
+ import { IObject, IPathDrawer } from '@leafer/interface'
2
+ import { RectHelper } from '@leafer/path'
2
3
 
3
4
 
5
+ const { drawRoundRect } = RectHelper
6
+
4
7
  export function roundRect(): void {
5
8
 
6
9
  if (!(CanvasRenderingContext2D.prototype as IObject).roundRect) {
7
10
 
8
- (CanvasRenderingContext2D.prototype as IObject).roundRect = (Path2D.prototype as IObject).roundRect = function (x: number, y: number, w: number, h: number, r: number | number[]): void {
9
-
10
- let topLeft: number, topRight: number, bottomRight: number, bottomLeft: number
11
-
12
- if (r instanceof Array) {
13
- switch (r.length) {
14
- case 4:
15
- topLeft = r[0]
16
- topRight = r[1]
17
- bottomRight = r[2]
18
- bottomLeft = r[3]
19
- break
20
- case 2:
21
- topLeft = bottomRight = r[0]
22
- topRight = bottomLeft = r[1]
23
- break
24
- case 3:
25
- topLeft = r[0]
26
- topRight = bottomLeft = r[1]
27
- bottomRight = r[2]
28
- break
29
- case 1:
30
- r = r[0]
31
- break
32
- default:
33
- r = 0
34
- }
35
- }
36
-
37
- if (topLeft === undefined) {
38
- if (r) {
39
- topLeft = topRight = bottomRight = bottomLeft = r as number
40
- } else {
41
- this.rect(x, y, w, h)
42
- return
43
- }
44
- }
45
-
46
- const max = Math.min(w / 2, h / 2)
47
- if (topLeft > max) topLeft = max
48
- if (topRight > max) topRight = max
49
- if (bottomRight > max) bottomRight = max
50
- if (bottomLeft > max) bottomLeft = max
51
-
52
- const R = this
53
- topLeft ? R.moveTo(x + topLeft, y) : R.moveTo(x, y)
54
- topRight ? R.arcTo(x + w, y, x + w, y + h, topRight) : R.lineTo(x + w, y)
55
- bottomRight ? R.arcTo(x + w, y + h, x, y + h, bottomRight) : R.lineTo(x + w, y + h)
56
- bottomLeft ? R.arcTo(x, y + h, x, y, bottomLeft) : R.lineTo(x, y + h)
57
- topLeft ? R.arcTo(x, y, x + w, y, topLeft) : R.lineTo(x, y)
58
- R.closePath()
11
+ (CanvasRenderingContext2D.prototype as IObject).roundRect = (Path2D.prototype as IObject).roundRect = function (x: number, y: number, width: number, height: number, cornerRadius: number | number[]): void {
12
+
13
+ drawRoundRect(this as IPathDrawer, x, y, width, height, cornerRadius)
59
14
  }
60
15
  }
61
16
 
package/src/CanvasBase.ts DELETED
@@ -1,272 +0,0 @@
1
- import { ICanvasAttr, ITextMetrics, ICanvasContext2D, IPath2D, IObject, InnerId, IMatrixData, IFunction, IWindingRule } from '@leafer/interface'
2
-
3
-
4
- function contextAttr(realName?: string) {
5
- return (target: CanvasBase, key: string) => {
6
- if (!realName) realName = key
7
- const property: IObject & ThisType<CanvasBase> = {
8
- get() { return (this.context as IObject)[realName] },
9
- set(value: unknown) { (this.context as IObject)[realName] = value }
10
- }
11
- Object.defineProperty(target, key, property)
12
- }
13
- }
14
-
15
- const contextMethodNameList: string[] = []
16
- function contextMethod() {
17
- return (_target: CanvasBase, key: string) => {
18
- contextMethodNameList.push(key)
19
- }
20
- }
21
-
22
-
23
- export class CanvasBase {
24
-
25
- public readonly innerId: InnerId
26
-
27
- public width: number
28
- public height: number
29
-
30
- public __: ICanvasAttr
31
-
32
- public context: ICanvasContext2D
33
-
34
- // canvas attr
35
-
36
- @contextAttr('imageSmoothingEnabled')
37
- public smooth: boolean
38
-
39
- @contextAttr('imageSmoothingQuality')
40
- public smoothLevel: ImageSmoothingQuality
41
-
42
- @contextAttr('globalAlpha')
43
- public opacity: number
44
-
45
- @contextAttr('globalCompositeOperation')
46
- public blendMode: string
47
-
48
-
49
- @contextAttr()
50
- public fillStyle: string | object
51
-
52
- @contextAttr()
53
- public strokeStyle: string | object
54
-
55
-
56
- @contextAttr('lineWidth')
57
- public strokeWidth: number
58
-
59
- @contextAttr('lineCap')
60
- public strokeCap: string
61
-
62
- @contextAttr('lineJoin')
63
- public strokeJoin: string
64
-
65
- @contextAttr('lineDash')
66
- public dashPattern: Array<number>
67
-
68
- @contextAttr('lineDashOffset')
69
- public dashOffset: number
70
-
71
- @contextAttr()
72
- public miterLimit: number
73
-
74
-
75
- @contextAttr()
76
- public shadowBlur: number
77
-
78
- @contextAttr()
79
- public shadowColor: string
80
-
81
- @contextAttr()
82
- public shadowOffsetX: number
83
-
84
- @contextAttr()
85
- public shadowOffsetY: number
86
-
87
- @contextAttr()
88
- public filter: string
89
-
90
-
91
- @contextAttr()
92
- public font: string
93
-
94
- @contextAttr()
95
- public fontKerning: string
96
-
97
- @contextAttr()
98
- public fontStretch: string
99
-
100
- @contextAttr()
101
- public fontVariantCaps: string
102
-
103
-
104
- @contextAttr()
105
- public textAlign: string
106
-
107
- @contextAttr()
108
- public textBaseline: string
109
-
110
- @contextAttr()
111
- public textRendering: string
112
-
113
- @contextAttr()
114
- public wordSpacing: string
115
-
116
- @contextAttr()
117
- public letterSpacing: string
118
-
119
-
120
- @contextAttr()
121
- public direction: string
122
-
123
- // end
124
-
125
- public __bindContext(): void {
126
- let method: IFunction
127
- contextMethodNameList.forEach(name => {
128
- method = (this.context as IObject)[name]
129
- if (method) (this as IObject)[name] = method.bind(this.context)
130
- })
131
- }
132
-
133
- // canvas method
134
-
135
- @contextMethod()
136
- public setTransform(_a: number | IMatrixData, _b?: number, _c?: number, _d?: number, _e?: number, _f?: number): void { }
137
-
138
- @contextMethod()
139
- public resetTransform(): void { }
140
-
141
- @contextMethod()
142
- public getTransform(): IMatrixData { return void 0 }
143
-
144
- @contextMethod()
145
- public save(): void { }
146
-
147
- @contextMethod()
148
- public restore(): void { }
149
-
150
- @contextMethod()
151
- public translate(_x: number, _y: number): void { }
152
-
153
- @contextMethod()
154
- public scale(_x: number, _y: number): void { }
155
-
156
- @contextMethod()
157
- public rotate(_angle: number): void { }
158
-
159
- @contextMethod()
160
- public fill(_path2d?: IPath2D | IWindingRule, _rule?: IWindingRule): void { }
161
-
162
- @contextMethod()
163
- public stroke(_path2d?: IPath2D): void { }
164
-
165
- @contextMethod()
166
- public clip(_path2d?: IPath2D | IWindingRule, _rule?: IWindingRule): void { }
167
-
168
- @contextMethod()
169
- public fillRect(_x: number, _y: number, _width: number, _height: number): void { }
170
-
171
- @contextMethod()
172
- public strokeRect(_x: number, _y: number, _width: number, _height: number): void { }
173
-
174
- @contextMethod()
175
- public clearRect(_x: number, _y: number, _width: number, _height: number): void { }
176
-
177
- public drawImage(image: CanvasImageSource, sx: number, sy: number, sw?: number, sh?: number, dx?: number, dy?: number, dw?: number, dh?: number): void {
178
- switch (arguments.length) {
179
- case 9:
180
-
181
- // safari: drawimage裁剪画布外的坐标会有问题, 必须是不小于0的坐标点
182
- if (sx < 0) {
183
- const d = (-sx / sw) * dw
184
- sw += sx
185
- sx = 0
186
- dx += d
187
- dw -= d
188
- }
189
-
190
- if (sy < 0) {
191
- const d = (-sy / sh) * dh
192
- sh += sy
193
- sy = 0
194
- dy += d
195
- dh -= d
196
- }
197
-
198
- this.context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
199
- break
200
- case 5:
201
- this.context.drawImage(image, sx, sy, sw, sh) // = dx, dy, dw, dh
202
- break
203
- case 3:
204
- this.context.drawImage(image, sx, sy)
205
- }
206
- }
207
-
208
-
209
- // canvas draw
210
- @contextMethod()
211
- public beginPath(): void { }
212
-
213
- @contextMethod()
214
- public moveTo(_x: number, _y: number): void { }
215
-
216
- @contextMethod()
217
- public lineTo(_x: number, _y: number): void { }
218
-
219
- @contextMethod()
220
- public bezierCurveTo(_cp1x: number, _cp1y: number, _cp2x: number, _cp2y: number, _x: number, _y: number): void { }
221
-
222
- @contextMethod()
223
- public quadraticCurveTo(_cpx: number, _cpy: number, _x: number, _y: number): void { }
224
-
225
- @contextMethod()
226
- public closePath(): void { }
227
-
228
- @contextMethod()
229
- public arc(_x: number, _y: number, _radius: number, _startAngle: number, _endAngle: number, _counterclockwise?: boolean): void { }
230
-
231
- @contextMethod()
232
- public arcTo(_x1: number, _y1: number, _x2: number, _y2: number, _radius: number): void { }
233
-
234
- @contextMethod()
235
- public ellipse(_x: number, _y: number, _radiusX: number, _radiusY: number, _rotation: number, _startAngle: number, _endAngle: number, _counterclockwise?: boolean): void { }
236
-
237
- @contextMethod()
238
- public rect(_x: number, _y: number, _width: number, _height: number): void { }
239
-
240
- @contextMethod()
241
- public roundRect(_x: number, _y: number, _width: number, _height: number, _radius?: number | number[]): void { }
242
-
243
- // end canvas draw
244
-
245
- // paint
246
-
247
- @contextMethod()
248
- public createConicGradient(_startAngle: number, _x: number, _y: number): CanvasGradient { return void 0 }
249
-
250
- @contextMethod()
251
- public createLinearGradient(_x0: number, _y0: number, _x1: number, _y1: number): CanvasGradient { return void 0 }
252
-
253
- @contextMethod()
254
- public createPattern(_image: CanvasImageSource, _repetition: string | null): CanvasPattern | null { return void 0 }
255
-
256
- @contextMethod()
257
- public createRadialGradient(_x0: number, _y0: number, _r0: number, _x1: number, _y1: number, _r1: number): CanvasGradient { return void 0 }
258
-
259
- // text
260
- @contextMethod()
261
- public fillText(_text: string, _x: number, _y: number, _maxWidth?: number): void { }
262
-
263
- @contextMethod()
264
- public measureText(_text: string): ITextMetrics { return void 0 }
265
-
266
- @contextMethod()
267
- public strokeText(_text: string, _x: number, _y: number, _maxWidth?: number): void { }
268
-
269
- public destroy(): void {
270
- this.context = null
271
- }
272
- }