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