@leafer/canvas 1.0.0-alpha.9 → 1.0.0-beta

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",
3
- "version": "1.0.0-alpha.9",
3
+ "version": "1.0.0-beta",
4
4
  "description": "@leafer/canvas",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -19,9 +19,12 @@
19
19
  "leaferjs"
20
20
  ],
21
21
  "dependencies": {
22
- "@leafer/list": "1.0.0-alpha.9"
22
+ "@leafer/list": "1.0.0-beta",
23
+ "@leafer/math": "1.0.0-beta",
24
+ "@leafer/data": "1.0.0-beta",
25
+ "@leafer/platform": "1.0.0-beta"
23
26
  },
24
27
  "devDependencies": {
25
- "@leafer/interface": "1.0.0-alpha.9"
28
+ "@leafer/interface": "1.0.0-beta"
26
29
  }
27
30
  }
package/src/Canvas.ts ADDED
@@ -0,0 +1,283 @@
1
+ import { ICanvasAttr, ITextMetrics, ICanvasContext2D, IPath2D, IObject, InnerId, IMatrixData, IFunction, IWindingRule, IBlendMode } from '@leafer/interface'
2
+
3
+ function contextAttr(realName?: string) {
4
+ return (target: Canvas, key: string) => {
5
+ if (!realName) realName = key
6
+ const property: IObject & ThisType<Canvas> = {
7
+ get() { return (this.context as IObject)[realName] },
8
+ set(value: unknown) { (this.context as IObject)[realName] = value }
9
+ }
10
+ Object.defineProperty(target, key, property)
11
+ }
12
+ }
13
+
14
+ const contextMethodNameList: string[] = []
15
+ function contextMethod() {
16
+ return (_target: Canvas, key: string) => {
17
+ contextMethodNameList.push(key)
18
+ }
19
+ }
20
+
21
+ const emptyArray: number[] = []
22
+
23
+
24
+ export class Canvas implements ICanvasAttr {
25
+
26
+ public readonly innerId: InnerId
27
+
28
+ public width: number
29
+ public height: number
30
+
31
+ public context: ICanvasContext2D
32
+
33
+ // canvas attr
34
+
35
+ @contextAttr('imageSmoothingEnabled')
36
+ public smooth: boolean
37
+
38
+ @contextAttr('imageSmoothingQuality')
39
+ public smoothLevel: ImageSmoothingQuality
40
+
41
+ @contextAttr('globalAlpha')
42
+ public opacity: number
43
+
44
+ public set blendMode(value: IBlendMode) {
45
+ if (value === 'normal') value = 'source-over'
46
+ this.context.globalCompositeOperation = value as any
47
+ }
48
+
49
+ public get blendMode(): IBlendMode {
50
+ return this.context.globalCompositeOperation as IBlendMode
51
+ }
52
+
53
+ @contextAttr()
54
+ public fillStyle: string | object
55
+
56
+ @contextAttr()
57
+ public strokeStyle: string | object
58
+
59
+
60
+ @contextAttr('lineWidth')
61
+ public strokeWidth: number
62
+
63
+ @contextAttr('lineCap')
64
+ public strokeCap: string
65
+
66
+ @contextAttr('lineJoin')
67
+ public strokeJoin: string
68
+
69
+ public set dashPattern(value: number[]) {
70
+ this.context.setLineDash(value || emptyArray)
71
+ }
72
+ public get dashPattern(): number[] {
73
+ return this.context.getLineDash()
74
+ }
75
+
76
+ @contextAttr('lineDashOffset')
77
+ public dashOffset: number
78
+
79
+ @contextAttr()
80
+ public miterLimit: number
81
+
82
+
83
+ @contextAttr()
84
+ public shadowBlur: number
85
+
86
+ @contextAttr()
87
+ public shadowColor: string
88
+
89
+ @contextAttr()
90
+ public shadowOffsetX: number
91
+
92
+ @contextAttr()
93
+ public shadowOffsetY: number
94
+
95
+ @contextAttr()
96
+ public filter: string
97
+
98
+
99
+ @contextAttr()
100
+ public font: string
101
+
102
+ @contextAttr()
103
+ public fontKerning: string
104
+
105
+ @contextAttr()
106
+ public fontStretch: string
107
+
108
+ @contextAttr()
109
+ public fontVariantCaps: string
110
+
111
+
112
+ @contextAttr()
113
+ public textAlign: string
114
+
115
+ @contextAttr()
116
+ public textBaseline: string
117
+
118
+ @contextAttr()
119
+ public textRendering: string
120
+
121
+ @contextAttr()
122
+ public wordSpacing: string
123
+
124
+ @contextAttr()
125
+ public letterSpacing: string
126
+
127
+
128
+ @contextAttr()
129
+ public direction: string
130
+
131
+ // end
132
+
133
+ public __bindContext(): void {
134
+ let method: IFunction
135
+ contextMethodNameList.forEach(name => {
136
+ method = (this.context as IObject)[name]
137
+ if (method) (this as IObject)[name] = method.bind(this.context)
138
+ })
139
+ }
140
+
141
+ // canvas method
142
+
143
+ @contextMethod()
144
+ public setTransform(_a: number | IMatrixData, _b?: number, _c?: number, _d?: number, _e?: number, _f?: number): void { }
145
+
146
+ @contextMethod()
147
+ public resetTransform(): void { }
148
+
149
+ @contextMethod()
150
+ public getTransform(): IMatrixData { return void 0 }
151
+
152
+ @contextMethod()
153
+ public save(): void { }
154
+
155
+ @contextMethod()
156
+ public restore(): void { }
157
+
158
+ @contextMethod()
159
+ public transform(_a: number, _b: number, _c: number, _d: number, _e: number, _f: number): void { }
160
+
161
+ @contextMethod()
162
+ public translate(_x: number, _y: number): void { }
163
+
164
+ @contextMethod()
165
+ public scale(_x: number, _y: number): void { }
166
+
167
+ @contextMethod()
168
+ public rotate(_angle: number): void { }
169
+
170
+ @contextMethod()
171
+ public fill(_path2d?: IPath2D | IWindingRule, _rule?: IWindingRule): void { }
172
+
173
+ @contextMethod()
174
+ public stroke(_path2d?: IPath2D): void { }
175
+
176
+ @contextMethod()
177
+ public clip(_path2d?: IPath2D | IWindingRule, _rule?: IWindingRule): void { }
178
+
179
+ @contextMethod()
180
+ public fillRect(_x: number, _y: number, _width: number, _height: number): void { }
181
+
182
+ @contextMethod()
183
+ public strokeRect(_x: number, _y: number, _width: number, _height: number): void { }
184
+
185
+ @contextMethod()
186
+ public clearRect(_x: number, _y: number, _width: number, _height: number): void { }
187
+
188
+ public drawImage(image: CanvasImageSource, sx: number, sy: number, sw?: number, sh?: number, dx?: number, dy?: number, dw?: number, dh?: number): void {
189
+ switch (arguments.length) {
190
+ case 9:
191
+
192
+ // safari: drawimage裁剪画布外的坐标会有问题, 必须是不小于0的坐标点
193
+ if (sx < 0) {
194
+ const d = (-sx / sw) * dw
195
+ sw += sx
196
+ sx = 0
197
+ dx += d
198
+ dw -= d
199
+ }
200
+
201
+ if (sy < 0) {
202
+ const d = (-sy / sh) * dh
203
+ sh += sy
204
+ sy = 0
205
+ dy += d
206
+ dh -= d
207
+ }
208
+
209
+ this.context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
210
+ break
211
+ case 5:
212
+ this.context.drawImage(image, sx, sy, sw, sh) // = dx, dy, dw, dh
213
+ break
214
+ case 3:
215
+ this.context.drawImage(image, sx, sy)
216
+ }
217
+ }
218
+
219
+
220
+ // canvas draw
221
+ @contextMethod()
222
+ public beginPath(): void { }
223
+
224
+ @contextMethod()
225
+ public moveTo(_x: number, _y: number): void { }
226
+
227
+ @contextMethod()
228
+ public lineTo(_x: number, _y: number): void { }
229
+
230
+ @contextMethod()
231
+ public bezierCurveTo(_cp1x: number, _cp1y: number, _cp2x: number, _cp2y: number, _x: number, _y: number): void { }
232
+
233
+ @contextMethod()
234
+ public quadraticCurveTo(_cpx: number, _cpy: number, _x: number, _y: number): void { }
235
+
236
+ @contextMethod()
237
+ public closePath(): void { }
238
+
239
+ @contextMethod()
240
+ public arc(_x: number, _y: number, _radius: number, _startAngle: number, _endAngle: number, _anticlockwise?: boolean): void { }
241
+
242
+ @contextMethod()
243
+ public arcTo(_x1: number, _y1: number, _x2: number, _y2: number, _radius: number): void { }
244
+
245
+ @contextMethod()
246
+ public ellipse(_x: number, _y: number, _radiusX: number, _radiusY: number, _rotation: number, _startAngle: number, _endAngle: number, _anticlockwise?: boolean): void { }
247
+
248
+ @contextMethod()
249
+ public rect(_x: number, _y: number, _width: number, _height: number): void { }
250
+
251
+ @contextMethod()
252
+ public roundRect(_x: number, _y: number, _width: number, _height: number, _radius?: number | number[]): void { }
253
+
254
+ // end canvas draw
255
+
256
+ // paint
257
+
258
+ @contextMethod()
259
+ public createConicGradient(_startAngle: number, _x: number, _y: number): CanvasGradient { return void 0 }
260
+
261
+ @contextMethod()
262
+ public createLinearGradient(_x0: number, _y0: number, _x1: number, _y1: number): CanvasGradient { return void 0 }
263
+
264
+ @contextMethod()
265
+ public createPattern(_image: CanvasImageSource, _repetition: string | null): CanvasPattern | null { return void 0 }
266
+
267
+ @contextMethod()
268
+ public createRadialGradient(_x0: number, _y0: number, _r0: number, _x1: number, _y1: number, _r1: number): CanvasGradient { return void 0 }
269
+
270
+ // text
271
+ @contextMethod()
272
+ public fillText(_text: string, _x: number, _y: number, _maxWidth?: number): void { }
273
+
274
+ @contextMethod()
275
+ public measureText(_text: string): ITextMetrics { return void 0 }
276
+
277
+ @contextMethod()
278
+ public strokeText(_text: string, _x: number, _y: number, _maxWidth?: number): void { }
279
+
280
+ public destroy(): void {
281
+ this.context = null
282
+ }
283
+ }
@@ -1,16 +1,10 @@
1
- import { ILeaferCanvas, IScreenSizeData, ILeafer, ICanvasManager } from '@leafer/interface'
2
-
1
+ import { ILeaferCanvas, IScreenSizeData, ICanvasManager } from '@leafer/interface'
2
+ import { Creator } from '@leafer/platform'
3
3
 
4
4
  export class CanvasManager implements ICanvasManager {
5
5
 
6
- public leafer: ILeafer
7
-
8
6
  public list: ILeaferCanvas[] = []
9
7
 
10
- constructor(leafer: ILeafer) {
11
- this.leafer = leafer
12
- }
13
-
14
8
  public add(canvas: ILeaferCanvas): void {
15
9
  canvas.manager = this
16
10
  this.list.push(canvas)
@@ -23,11 +17,12 @@ export class CanvasManager implements ICanvasManager {
23
17
  old = list[i]
24
18
  if (old.recycled && old.isSameSize(size)) {
25
19
  old.recycled = false
20
+ old.manager || (old.manager = this)
26
21
  return old
27
22
  }
28
23
  }
29
24
 
30
- const canvas = this.leafer.creator.canvas(size)
25
+ const canvas = Creator.canvas(size)
31
26
  this.add(canvas)
32
27
  return canvas
33
28
  }
@@ -56,7 +51,6 @@ export class CanvasManager implements ICanvasManager {
56
51
 
57
52
  public destory(): void {
58
53
  this.clear()
59
- this.leafer = undefined
60
54
  }
61
55
 
62
56
  }
@@ -1,5 +1,6 @@
1
1
  import { IScreenSizeData, IHitCanvasManager, ILeaf, IHitCanvas, ILeaferCanvas, ILeafList } from '@leafer/interface'
2
2
  import { LeafList } from '@leafer/list'
3
+ import { Creator } from '@leafer/platform'
3
4
 
4
5
  import { CanvasManager } from './CanvasManager'
5
6
 
@@ -13,12 +14,12 @@ export class HitCanvasManager extends CanvasManager implements IHitCanvasManager
13
14
 
14
15
  public getImageType(leaf: ILeaf, size: IScreenSizeData): IHitCanvas {
15
16
  this.imageTypeList.push(leaf)
16
- return this.leafer.creator.hitCanvas(size)
17
+ return Creator.hitCanvas(size)
17
18
  }
18
19
 
19
20
  public getPathType(leaf: ILeaf): IHitCanvas {
20
21
  this.pathTypeList.push(leaf)
21
- return this.leafer.creator.hitCanvas()
22
+ return Creator.hitCanvas()
22
23
  }
23
24
 
24
25
  public clearImageType(): void {
@@ -33,7 +34,7 @@ export class HitCanvasManager extends CanvasManager implements IHitCanvasManager
33
34
  leafList.forEach(leaf => {
34
35
  if (leaf.__hitCanvas) {
35
36
  leaf.__hitCanvas.destroy()
36
- leaf.__hitCanvas = undefined
37
+ leaf.__hitCanvas = null
37
38
  }
38
39
  })
39
40
  leafList.reset()
@@ -0,0 +1,302 @@
1
+ import { IBounds, ILeaferCanvas, ICanvasStrokeOptions, ILeaferCanvasConfig, IMatrixData, IBoundsData, IAutoBounds, IScreenSizeData, IResizeEventListener, IMatrixWithBoundsData, IPointData, InnerId, ICanvasManager, IWindingRule, IBlendMode } from '@leafer/interface'
2
+ import { Bounds, BoundsHelper, IncrementId } from '@leafer/math'
3
+ import { Creator, Platform } from '@leafer/platform'
4
+ import { DataHelper } from '@leafer/data'
5
+
6
+ import { Canvas } from './Canvas'
7
+
8
+
9
+ const temp = new Bounds()
10
+ const minSize: IScreenSizeData = { width: 1, height: 1, pixelRatio: 1 }
11
+
12
+ export const canvasSizeAttrs = ['width', 'height', 'pixelRatio']
13
+
14
+ export class LeaferCanvasBase extends Canvas implements ILeaferCanvas {
15
+
16
+ public readonly innerId: InnerId
17
+
18
+ public name: string
19
+
20
+ public manager: ICanvasManager
21
+
22
+ public pixelRatio: number
23
+ public get pixelWidth(): number { return this.width * this.pixelRatio }
24
+ public get pixelHeight(): number { return this.height * this.pixelRatio }
25
+ public get allowBackgroundColor(): boolean { return this.view && this.parentView && !this.offscreen }
26
+
27
+ public bounds: IBounds
28
+
29
+ public config: ILeaferCanvasConfig
30
+
31
+ public autoLayout: boolean
32
+
33
+ public view: unknown
34
+ public parentView: unknown
35
+
36
+ public unreal?: boolean
37
+
38
+ public offscreen: boolean
39
+
40
+ public recycled?: boolean
41
+
42
+ public worldTransform: IMatrixData = {} as IMatrixData
43
+
44
+ protected savedBlendMode: IBlendMode
45
+
46
+ constructor(config?: ILeaferCanvasConfig, manager?: ICanvasManager) {
47
+ super()
48
+ if (!config) config = minSize
49
+ if (!config.pixelRatio) config.pixelRatio = Platform.devicePixelRatio
50
+
51
+ this.manager = manager
52
+ this.innerId = IncrementId.create(IncrementId.CNAVAS)
53
+
54
+ const { width, height, pixelRatio } = config
55
+ this.autoLayout = !width || !height
56
+
57
+ this.pixelRatio = pixelRatio
58
+ this.offscreen = Platform.isWorker || config.offscreen
59
+ this.config = config
60
+
61
+ this.init()
62
+
63
+ this.textBaseline = "alphabetic"
64
+ }
65
+
66
+ public init(): void { }
67
+ public setBackgroundColor(_color: string): void { }
68
+ public setHittable(_hittable: boolean): void { }
69
+
70
+ public resize(size: IScreenSizeData): void {
71
+ if (this.isSameSize(size)) return
72
+
73
+ const { width, height } = size
74
+
75
+ let takeCanvas: ILeaferCanvas
76
+ if (this.context && !this.unreal && this.width) {
77
+ takeCanvas = this.getSameCanvas()
78
+ takeCanvas.copyWorld(this)
79
+ }
80
+
81
+ DataHelper.copyAttrs(this, size, canvasSizeAttrs)
82
+ this.bounds = new Bounds(0, 0, width, height)
83
+
84
+ if (!this.unreal) {
85
+ this.setViewSize(size)
86
+ this.smooth = this.config.smooth
87
+ }
88
+
89
+ if (this.context && !this.unreal && takeCanvas) {
90
+ this.clearWorld(takeCanvas.bounds)
91
+ this.copyWorld(takeCanvas)
92
+ takeCanvas.recycle()
93
+ }
94
+ }
95
+
96
+ public setViewSize(_size: IScreenSizeData): void { }
97
+ public startAutoLayout(_autoBounds: IAutoBounds, _listener: IResizeEventListener): void { }
98
+ public stopAutoLayout(): void { }
99
+
100
+ public setWorld(matrix: IMatrixData, parentMatrix?: IMatrixData, onlyTranslate?: boolean): void {
101
+ const { pixelRatio } = this
102
+ const w = this.worldTransform
103
+ if (parentMatrix) {
104
+
105
+ if (onlyTranslate) {
106
+ this.setTransform(
107
+ w.a = matrix.a * pixelRatio,
108
+ w.b = matrix.b * pixelRatio,
109
+ w.c = matrix.c * pixelRatio,
110
+ w.d = matrix.d * pixelRatio,
111
+ w.e = (matrix.e + parentMatrix.e) * pixelRatio,
112
+ w.f = (matrix.f + parentMatrix.f) * pixelRatio
113
+ )
114
+ } else {
115
+ const { a, b, c, d, e, f } = parentMatrix
116
+ this.setTransform(
117
+ w.a = ((matrix.a * a) + (matrix.b * c)) * pixelRatio,
118
+ w.b = ((matrix.a * b) + (matrix.b * d)) * pixelRatio,
119
+ w.c = ((matrix.c * a) + (matrix.d * c)) * pixelRatio,
120
+ w.d = ((matrix.c * b) + (matrix.d * d)) * pixelRatio,
121
+ w.e = (((matrix.e * a) + (matrix.f * c) + e)) * pixelRatio,
122
+ w.f = (((matrix.e * b) + (matrix.f * d) + f)) * pixelRatio
123
+ )
124
+ }
125
+
126
+ } else {
127
+
128
+ this.setTransform(
129
+ w.a = matrix.a * pixelRatio,
130
+ w.b = matrix.b * pixelRatio,
131
+ w.c = matrix.c * pixelRatio,
132
+ w.d = matrix.d * pixelRatio,
133
+ w.e = matrix.e * pixelRatio,
134
+ w.f = matrix.f * pixelRatio
135
+ )
136
+ }
137
+ }
138
+
139
+ public setStroke(color: string | object, strokeWidth: number, options?: ICanvasStrokeOptions): void {
140
+ if (strokeWidth) this.strokeWidth = strokeWidth
141
+ if (color) this.strokeStyle = color
142
+ if (options) this.setStrokeOptions(options)
143
+ }
144
+
145
+ public setStrokeOptions(options: ICanvasStrokeOptions): void {
146
+ this.strokeCap = options.strokeCap
147
+ this.strokeJoin = options.strokeJoin
148
+ this.dashPattern = options.dashPattern
149
+ this.dashOffset = options.dashOffset
150
+ this.miterLimit = options.miterLimit
151
+ }
152
+
153
+ public saveBlendMode(blendMode: IBlendMode): void {
154
+ this.savedBlendMode = this.blendMode
155
+ this.blendMode = blendMode
156
+ }
157
+
158
+ public restoreBlendMode(): void {
159
+ this.blendMode = this.savedBlendMode
160
+ }
161
+
162
+ public hitFill(point: IPointData, fillRule?: IWindingRule): boolean {
163
+ return this.context.isPointInPath(point.x, point.y, fillRule)
164
+ }
165
+
166
+ public hitStroke(point: IPointData, strokeWidth?: number): boolean {
167
+ this.strokeWidth = strokeWidth
168
+ return this.context.isPointInStroke(point.x, point.y)
169
+ }
170
+
171
+
172
+ public setWorldShadow(x: number, y: number, blur: number, color?: string): void {
173
+ const { pixelRatio } = this
174
+ this.shadowOffsetX = x * pixelRatio
175
+ this.shadowOffsetY = y * pixelRatio
176
+ this.shadowBlur = blur * pixelRatio
177
+ this.shadowColor = color || 'black'
178
+ }
179
+
180
+ public setWorldBlur(blur: number): void {
181
+ const { pixelRatio } = this
182
+ this.filter = `blur(${blur * pixelRatio}px)`
183
+ }
184
+
185
+
186
+ public copyWorld(canvas: ILeaferCanvas, from?: IBoundsData, to?: IBoundsData, blendMode?: IBlendMode): void {
187
+ if (blendMode) this.blendMode = blendMode
188
+ if (from) {
189
+ const { pixelRatio } = this
190
+ if (!to) to = from
191
+ 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)
192
+ } else {
193
+ this.drawImage(canvas.view as HTMLCanvasElement, 0, 0)
194
+ }
195
+ if (blendMode) this.blendMode = 'source-over'
196
+ }
197
+
198
+ public copyWorldToInner(canvas: ILeaferCanvas, fromWorld: IMatrixWithBoundsData, toInnerBounds: IBoundsData, blendMode?: IBlendMode): void {
199
+ if (blendMode) this.blendMode = blendMode
200
+ if (fromWorld.b || fromWorld.c) {
201
+ this.save()
202
+ this.resetTransform()
203
+ this.copyWorld(canvas, fromWorld, BoundsHelper.tempToOuterOf(toInnerBounds, fromWorld))
204
+ this.restore()
205
+ } else {
206
+ const { pixelRatio } = this
207
+ this.drawImage(canvas.view as HTMLCanvasElement, fromWorld.x * pixelRatio, fromWorld.y * pixelRatio, fromWorld.width * pixelRatio, fromWorld.height * pixelRatio, toInnerBounds.x, toInnerBounds.y, toInnerBounds.width, toInnerBounds.height)
208
+ }
209
+ if (blendMode) this.blendMode = 'source-over'
210
+ }
211
+
212
+ public useMask(maskCanvas: ILeaferCanvas, fromBounds?: IBoundsData, toBounds?: IBoundsData): void {
213
+ this.copyWorld(maskCanvas, fromBounds, toBounds, 'destination-in')
214
+ }
215
+
216
+ public fillWorld(bounds: IBoundsData, color: string | object, blendMode?: IBlendMode): void {
217
+ if (blendMode) this.blendMode = blendMode
218
+ this.fillStyle = color
219
+ temp.copy(bounds).scale(this.pixelRatio)
220
+ this.fillRect(temp.x, temp.y, temp.width, temp.height)
221
+ if (blendMode) this.blendMode = 'source-over'
222
+ }
223
+
224
+ public strokeWorld(bounds: IBoundsData, color: string | object, blendMode?: IBlendMode): void {
225
+ if (blendMode) this.blendMode = blendMode
226
+ this.strokeStyle = color
227
+ temp.copy(bounds).scale(this.pixelRatio)
228
+ this.strokeRect(temp.x, temp.y, temp.width, temp.height)
229
+ if (blendMode) this.blendMode = 'source-over'
230
+ }
231
+
232
+ public clearWorld(bounds: IBoundsData, ceilPixel?: boolean): void {
233
+ temp.copy(bounds).scale(this.pixelRatio)
234
+ if (ceilPixel) temp.ceil()
235
+ this.clearRect(temp.x, temp.y, temp.width, temp.height)
236
+ }
237
+
238
+ public clipWorld(bounds: IBoundsData, ceilPixel?: boolean): void {
239
+ this.beginPath()
240
+ temp.copy(bounds).scale(this.pixelRatio)
241
+ if (ceilPixel) temp.ceil()
242
+ this.rect(temp.x, temp.y, temp.width, temp.height)
243
+ this.clip()
244
+
245
+ }
246
+
247
+ public clear(): void {
248
+ const { pixelRatio } = this
249
+ this.clearRect(0, 0, this.width * pixelRatio, this.height * pixelRatio)
250
+ }
251
+
252
+
253
+ // other
254
+
255
+ public isSameSize(size: IScreenSizeData): boolean {
256
+ return this.width === size.width && this.height === size.height && this.pixelRatio === size.pixelRatio
257
+ }
258
+
259
+ // 需要有 manager变量
260
+ public getSameCanvas(useSameWorldTransform?: boolean): ILeaferCanvas {
261
+ const { width, height, pixelRatio } = this
262
+
263
+ const options = { width, height, pixelRatio }
264
+ const canvas = this.manager ? this.manager.get(options) : Creator.canvas(options)
265
+
266
+ canvas.save()
267
+
268
+ if (useSameWorldTransform) {
269
+ const w = this.worldTransform
270
+ canvas.setTransform(w.a, w.b, w.c, w.d, w.e, w.f)
271
+ }
272
+
273
+ return canvas
274
+ }
275
+
276
+ public getBiggerCanvas(addWidth: number, addHeight: number): ILeaferCanvas {
277
+ let { width, height, pixelRatio } = this
278
+ if (addWidth) width += addWidth
279
+ if (addHeight) height += addHeight
280
+
281
+ const options = { width, height, pixelRatio }
282
+ const canvas = this.manager ? this.manager.get(options) : Creator.canvas(options)
283
+
284
+ canvas.save()
285
+ return canvas
286
+ }
287
+
288
+ public recycle(): void {
289
+ this.restore()
290
+ this.manager ? this.manager.recycle(this) : this.destroy()
291
+ }
292
+
293
+ public unrealCanvas(): void { }
294
+
295
+ public destroy(): void {
296
+ this.manager = null
297
+ this.view = null
298
+ this.parentView = null
299
+ this.context = null
300
+ this.config = null
301
+ }
302
+ }
package/src/index.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export { CanvasManager } from './CanvasManager'
2
2
  export { HitCanvasManager } from './HitCanvasManager'
3
+ export { LeaferCanvasBase, canvasSizeAttrs } from './LeaferCanvasBase'
4
+