@leafer-ui/display 1.0.0-rc.2 → 1.0.0-rc.21

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/src/Leafer.ts ADDED
@@ -0,0 +1,443 @@
1
+ import { ILeaferCanvas, IRenderer, ILayouter, ISelector, IWatcher, IInteraction, ILeaferConfig, ICanvasManager, IHitCanvasManager, IAutoBounds, IScreenSizeData, IResizeEvent, IEventListenerId, ITimer, IValue, IObject, IControl, IPointData, ILeaferType, ICursorType, IBoundsData, INumber, IZoomType, IFourNumber, IBounds } from '@leafer/interface'
2
+ import { AutoBounds, LayoutEvent, ResizeEvent, LeaferEvent, CanvasManager, ImageManager, DataHelper, Creator, Run, Debug, RenderEvent, registerUI, boundsType, canvasSizeAttrs, dataProcessor, WaitHelper, WatchEvent, Bounds, LeafList } from '@leafer/core'
3
+
4
+ import { ILeaferInputData, ILeaferData, IFunction, IUIInputData, ILeafer, IApp, IEditorBase } from '@leafer-ui/interface'
5
+ import { LeaferData } from '@leafer-ui/data'
6
+ import { Group } from './Group'
7
+
8
+
9
+ const debug = Debug.get('Leafer')
10
+
11
+ @registerUI()
12
+ export class Leafer extends Group implements ILeafer {
13
+
14
+
15
+ static get version() { return '1.0.0-rc.21' }
16
+
17
+ static list = new LeafList() // 所有leafer实例
18
+
19
+
20
+ public get __tag() { return 'Leafer' }
21
+
22
+ @dataProcessor(LeaferData)
23
+ declare public __: ILeaferData
24
+
25
+ @boundsType()
26
+ declare public pixelRatio: INumber
27
+
28
+ public get isApp(): boolean { return false }
29
+ public get app(): ILeafer { return this.parent || this }
30
+
31
+ public get isLeafer(): boolean { return true }
32
+
33
+ declare public parent?: IApp
34
+
35
+ public running: boolean
36
+ public created: boolean
37
+ public ready: boolean
38
+ public viewReady: boolean
39
+ public viewCompleted: boolean
40
+ public get imageReady(): boolean { return this.viewReady && ImageManager.isComplete }
41
+ public get layoutLocked() { return !this.layouter.running }
42
+
43
+ public transforming: boolean
44
+
45
+ public view: unknown
46
+
47
+ // manager
48
+ public canvas: ILeaferCanvas
49
+ public renderer: IRenderer
50
+
51
+ public watcher: IWatcher
52
+ public layouter: ILayouter
53
+
54
+ public selector?: ISelector
55
+ public interaction?: IInteraction
56
+
57
+ public canvasManager: ICanvasManager
58
+ public hitCanvasManager?: IHitCanvasManager
59
+
60
+ // plugin
61
+ public editor: IEditorBase
62
+
63
+ public userConfig: ILeaferConfig
64
+ public config: ILeaferConfig = {
65
+ type: 'design',
66
+ start: true,
67
+ hittable: true,
68
+ smooth: true,
69
+ lazySpeard: 100,
70
+ zoom: {
71
+ min: 0.01,
72
+ max: 256
73
+ },
74
+ move: {
75
+ holdSpaceKey: true,
76
+ holdMiddleKey: true,
77
+ autoDistance: 2
78
+ }
79
+ }
80
+
81
+ public autoLayout?: IAutoBounds
82
+ public lazyBounds: IBounds
83
+
84
+ public get FPS(): number { return this.renderer ? this.renderer.FPS : 60 }
85
+ public get cursorPoint(): IPointData { return (this.interaction && this.interaction.hoverData) || { x: this.width / 2, y: this.height / 2 } }
86
+ public leafs = 0
87
+
88
+ public __eventIds: IEventListenerId[] = []
89
+ protected __startTimer: ITimer
90
+ protected __controllers: IControl[] = []
91
+
92
+ protected __initWait: IFunction[] // assign in waitInit()
93
+ protected __readyWait: IFunction[] = []
94
+ protected __viewReadyWait: IFunction[] = []
95
+ protected __viewCompletedWait: IFunction[] = []
96
+ public __nextRenderWait: IFunction[] = []
97
+
98
+ constructor(userConfig?: ILeaferConfig, data?: ILeaferInputData) {
99
+ super(data)
100
+ this.userConfig = userConfig
101
+ if (userConfig && (userConfig.view || userConfig.width)) this.init(userConfig)
102
+ Leafer.list.add(this)
103
+ }
104
+
105
+ public init(userConfig?: ILeaferConfig, parentApp?: IApp): void {
106
+ if (this.canvas) return
107
+
108
+ this.__setLeafer(this)
109
+ if (userConfig) DataHelper.assign(this.config, userConfig)
110
+
111
+ let start: boolean
112
+ const { config } = this
113
+
114
+ this.initType(config.type) // LeaferType
115
+
116
+ // render / layout
117
+ const canvas = this.canvas = Creator.canvas(config)
118
+ this.__controllers.push(
119
+ this.renderer = Creator.renderer(this, canvas, config),
120
+ this.watcher = Creator.watcher(this, config),
121
+ this.layouter = Creator.layouter(this, config)
122
+ )
123
+
124
+ if (this.isApp) this.__setApp()
125
+ this.__checkAutoLayout(config)
126
+ this.updateLazyBounds()
127
+ this.view = canvas.view
128
+
129
+ // interaction / manager
130
+ if (parentApp) {
131
+ this.__bindApp(parentApp)
132
+ start = parentApp.running
133
+ } else {
134
+ this.selector = Creator.selector(this)
135
+ this.interaction = Creator.interaction(this, canvas, this.selector, config)
136
+
137
+ if (this.interaction) {
138
+ this.__controllers.unshift(this.interaction)
139
+ this.hitCanvasManager = Creator.hitCanvasManager()
140
+ }
141
+
142
+ this.canvasManager = new CanvasManager()
143
+
144
+ start = config.start
145
+ }
146
+
147
+ this.hittable = config.hittable
148
+ this.fill = config.fill
149
+ this.canvasManager.add(canvas)
150
+
151
+
152
+ this.__listenEvents()
153
+
154
+ if (start) this.__startTimer = setTimeout(this.start.bind(this))
155
+
156
+ WaitHelper.run(this.__initWait)
157
+ this.onInit() // can rewrite init event
158
+ }
159
+
160
+ public onInit(): void { }
161
+
162
+ public initType(_type: ILeaferType): void { } // rewrite in @leafer-ui/type
163
+
164
+ public set(data: IUIInputData): void {
165
+ this.waitInit(() => { super.set(data) })
166
+ }
167
+
168
+ public start(): void {
169
+ clearTimeout(this.__startTimer)
170
+ if (!this.running && this.canvas) {
171
+ this.ready ? this.emitLeafer(LeaferEvent.RESTART) : this.emitLeafer(LeaferEvent.START)
172
+ this.__controllers.forEach(item => item.start())
173
+ if (!this.isApp) this.renderer.render()
174
+ this.running = true
175
+ }
176
+ }
177
+
178
+ public stop(): void {
179
+ clearTimeout(this.__startTimer)
180
+ if (this.running && this.canvas) {
181
+ this.__controllers.forEach(item => item.stop())
182
+ this.running = false
183
+ this.emitLeafer(LeaferEvent.STOP)
184
+ }
185
+ }
186
+
187
+ public unlockLayout(): void {
188
+ this.layouter.start()
189
+ this.updateLayout()
190
+ }
191
+
192
+ public lockLayout(): void {
193
+ this.updateLayout()
194
+ this.layouter.stop()
195
+ }
196
+
197
+ public resize(size: IScreenSizeData): void {
198
+ const data = DataHelper.copyAttrs({}, size, canvasSizeAttrs)
199
+ Object.keys(data).forEach(key => (this as any)[key] = data[key])
200
+ }
201
+
202
+ public forceFullRender(): void {
203
+ this.forceRender()
204
+ }
205
+
206
+ public forceRender(bounds?: IBoundsData): void {
207
+ this.renderer.addBlock(bounds ? new Bounds(bounds) : this.canvas.bounds)
208
+ if (this.viewReady) this.renderer.update()
209
+ }
210
+
211
+ public updateCursor(cursor?: ICursorType): void {
212
+ const i = this.interaction
213
+ if (i) cursor ? i.setCursor(cursor) : i.updateCursor()
214
+ }
215
+
216
+ public updateLazyBounds(): void {
217
+ this.lazyBounds = this.canvas.bounds.clone().spread(this.config.lazySpeard)
218
+ }
219
+
220
+ protected __doResize(size: IScreenSizeData): void {
221
+ const { canvas } = this
222
+ if (!canvas || canvas.isSameSize(size)) return
223
+ const old = DataHelper.copyAttrs({}, this.canvas, canvasSizeAttrs) as IScreenSizeData
224
+ canvas.resize(size)
225
+ this.updateLazyBounds()
226
+ this.__onResize(new ResizeEvent(size, old))
227
+ }
228
+
229
+ protected __onResize(event: IResizeEvent): void {
230
+ this.emitEvent(event)
231
+ DataHelper.copyAttrs(this.__, event, canvasSizeAttrs)
232
+ setTimeout(() => { if (this.canvasManager) this.canvasManager.clearRecycled() }, 0)
233
+ }
234
+
235
+ protected __setApp(): void { }
236
+
237
+ protected __bindApp(app: IApp): void {
238
+ this.selector = app.selector
239
+ this.interaction = app.interaction
240
+
241
+ this.canvasManager = app.canvasManager
242
+ this.hitCanvasManager = app.hitCanvasManager
243
+ }
244
+
245
+ public __setLeafer(leafer: ILeafer): void {
246
+ this.leafer = leafer
247
+ this.__level = 1
248
+ }
249
+
250
+ protected __checkAutoLayout(config: ILeaferConfig): void {
251
+ if (!config.width || !config.height) {
252
+ this.autoLayout = new AutoBounds(config)
253
+ this.canvas.startAutoLayout(this.autoLayout, this.__onResize.bind(this))
254
+ }
255
+ }
256
+
257
+ public __setAttr(attrName: string, newValue: IValue): boolean {
258
+ if (this.canvas) {
259
+ if (canvasSizeAttrs.includes(attrName)) {
260
+ this.__changeCanvasSize(attrName, newValue as number)
261
+ } else if (attrName === 'fill') {
262
+ this.__changeFill(newValue as string)
263
+ } else if (attrName === 'hittable') {
264
+ this.canvas.hittable = newValue as boolean
265
+ }
266
+ }
267
+ return super.__setAttr(attrName, newValue)
268
+ }
269
+
270
+ public __getAttr(attrName: string): IValue {
271
+ if (this.canvas && canvasSizeAttrs.includes(attrName)) return this.canvas[attrName]
272
+ return super.__getAttr(attrName)
273
+ }
274
+
275
+ protected __changeCanvasSize(attrName: string, newValue: number): void {
276
+ const data = DataHelper.copyAttrs({}, this.canvas, canvasSizeAttrs)
277
+ data[attrName] = (this.config as IObject)[attrName] = newValue
278
+ if (newValue) this.canvas.stopAutoLayout()
279
+ this.__doResize(data as IScreenSizeData)
280
+ }
281
+
282
+ protected __changeFill(newValue: string): void {
283
+ this.config.fill = newValue as string
284
+ if (this.canvas.allowBackgroundColor) {
285
+ this.canvas.backgroundColor = newValue as string
286
+ } else {
287
+ this.forceFullRender()
288
+ }
289
+ }
290
+
291
+ protected __onCreated(): void {
292
+ this.created = true
293
+ }
294
+
295
+ protected __onReady(): void {
296
+ if (this.ready) return
297
+ this.ready = true
298
+ this.emitLeafer(LeaferEvent.BEFORE_READY)
299
+ this.emitLeafer(LeaferEvent.READY)
300
+ this.emitLeafer(LeaferEvent.AFTER_READY)
301
+ WaitHelper.run(this.__readyWait)
302
+ }
303
+
304
+ protected __onViewReady(): void {
305
+ if (this.viewReady) return
306
+ this.viewReady = true
307
+ this.emitLeafer(LeaferEvent.VIEW_READY)
308
+ WaitHelper.run(this.__viewReadyWait)
309
+ }
310
+
311
+ protected __onNextRender(): void {
312
+ if (this.viewReady) {
313
+ WaitHelper.run(this.__nextRenderWait)
314
+
315
+ const { imageReady } = this
316
+ if (imageReady && !this.viewCompleted) this.__checkViewCompleted()
317
+ if (!imageReady) this.viewCompleted = false
318
+ }
319
+ }
320
+
321
+ protected __checkViewCompleted(emit: boolean = true): void {
322
+ this.nextRender(() => {
323
+ if (this.imageReady) {
324
+ if (emit) this.emitLeafer(LeaferEvent.VIEW_COMPLETED)
325
+ WaitHelper.run(this.__viewCompletedWait)
326
+ this.viewCompleted = true
327
+ }
328
+ })
329
+ }
330
+
331
+ protected __onWatchData(): void {
332
+ if (this.watcher.childrenChanged && this.interaction) {
333
+ this.nextRender(() => this.interaction.updateCursor())
334
+ }
335
+ }
336
+
337
+ public waitInit(item: IFunction, bind?: IObject): void {
338
+ if (bind) item = item.bind(bind)
339
+ if (!this.__initWait) this.__initWait = [] // set() use
340
+ this.canvas ? item() : this.__initWait.push(item)
341
+ }
342
+
343
+ public waitReady(item: IFunction, bind?: IObject): void {
344
+ if (bind) item = item.bind(bind)
345
+ this.ready ? item() : this.__readyWait.push(item)
346
+ }
347
+
348
+ public waitViewReady(item: IFunction, bind?: IObject): void {
349
+ if (bind) item = item.bind(bind)
350
+ this.viewReady ? item() : this.__viewReadyWait.push(item)
351
+ }
352
+
353
+ public waitViewCompleted(item: IFunction, bind?: IObject): void {
354
+ if (bind) item = item.bind(bind)
355
+ this.__viewCompletedWait.push(item)
356
+ if (this.viewCompleted) {
357
+ this.__checkViewCompleted(false)
358
+ } else {
359
+ if (!this.running) this.start()
360
+ }
361
+ }
362
+
363
+ public nextRender(item: IFunction, bind?: IObject, off?: 'off'): void {
364
+ if (bind) item = item.bind(bind)
365
+ const list = this.__nextRenderWait
366
+ if (off) {
367
+ for (let i = 0; i < list.length; i++) {
368
+ if (list[i] === item) { list.splice(i, 1); break }
369
+ }
370
+ } else {
371
+ list.push(item)
372
+ }
373
+ }
374
+
375
+ // need view plugin
376
+ public zoom(_zoomType: IZoomType, _padding?: IFourNumber, _fixedScale?: boolean): IBoundsData { return undefined }
377
+
378
+ // interaction window rewrite
379
+ public getValidMove(moveX: number, moveY: number): IPointData { return { x: moveX, y: moveY } }
380
+ public getValidScale(changeScale: number): number { return changeScale }
381
+
382
+ protected __checkUpdateLayout(): void {
383
+ this.__layout.update()
384
+ }
385
+
386
+ protected emitLeafer(type: string): void {
387
+ this.emitEvent(new LeaferEvent(type, this))
388
+ }
389
+
390
+ protected __listenEvents(): void {
391
+ const runId = Run.start('FirstCreate ' + this.innerName)
392
+ this.once(LeaferEvent.START, () => Run.end(runId))
393
+ this.once(LayoutEvent.END, () => this.__onReady())
394
+ this.once(RenderEvent.START, () => this.__onCreated())
395
+ this.once(RenderEvent.END, () => this.__onViewReady())
396
+ this.__eventIds.push(
397
+ this.on_(WatchEvent.DATA, this.__onWatchData, this),
398
+ this.on_(RenderEvent.NEXT, this.__onNextRender, this),
399
+ this.on_(LayoutEvent.CHECK_UPDATE, this.__checkUpdateLayout, this)
400
+ )
401
+ }
402
+
403
+ protected __removeListenEvents(): void {
404
+ this.off_(this.__eventIds)
405
+ this.__eventIds.length = 0
406
+ }
407
+
408
+ public destroy(sync?: boolean): void {
409
+ const doDestory = () => {
410
+ if (!this.destroyed) {
411
+ Leafer.list.remove(this)
412
+ try {
413
+ this.stop()
414
+ this.emitEvent(new LeaferEvent(LeaferEvent.END, this))
415
+ this.__removeListenEvents()
416
+
417
+ this.__controllers.forEach(item => {
418
+ if (!(this.parent && item === this.interaction)) item.destroy()
419
+ })
420
+ this.__controllers.length = 0
421
+
422
+ if (!this.parent) {
423
+ if (this.selector) this.selector.destroy()
424
+ if (this.hitCanvasManager) this.hitCanvasManager.destroy()
425
+ this.canvasManager.destroy()
426
+ }
427
+
428
+ this.canvas.destroy()
429
+
430
+ this.config.view = this.view = null
431
+ if (this.userConfig) this.userConfig.view = null
432
+
433
+ super.destroy()
434
+
435
+ setTimeout(() => { ImageManager.clearRecycled() }, 100)
436
+ } catch (e) {
437
+ debug.error(e)
438
+ }
439
+ }
440
+ }
441
+ sync ? doDestory() : setTimeout(doDestory)
442
+ }
443
+ }
package/src/Line.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { IPointData, __Number } from '@leafer/interface'
2
- import { PathBounds, PathCommandDataHelper, PointHelper, boundsType, pathType, affectStrokeBoundsType, dataProcessor, registerUI } from '@leafer/core'
1
+ import { IPointData, INumber } from '@leafer/interface'
2
+ import { PathBounds, PathCommandDataHelper, PointHelper, boundsType, pathType, affectStrokeBoundsType, dataProcessor, registerUI, getPointData } from '@leafer/core'
3
3
 
4
4
  import { ILine, ILineData, ILineInputData, IStrokeAlign } from '@leafer-ui/interface'
5
5
  import { LineData } from '@leafer-ui/data'
6
6
 
7
7
  import { UI } from './UI'
8
+ import { PathArrow } from '@leafer-ui/external'
8
9
 
9
10
 
10
11
  const { moveTo, lineTo, drawPoints } = PathCommandDataHelper
@@ -13,7 +14,7 @@ const { toBounds } = PathBounds
13
14
 
14
15
 
15
16
  @registerUI()
16
- export class Line extends UI implements ILine {
17
+ export class Line extends UI implements ILine { // tip: rewrited Polygon
17
18
 
18
19
  public get __tag() { return 'Line' }
19
20
 
@@ -24,7 +25,7 @@ export class Line extends UI implements ILine {
24
25
  declare public strokeAlign: IStrokeAlign
25
26
 
26
27
  @boundsType(0)
27
- declare public height: __Number
28
+ declare public height: INumber
28
29
 
29
30
  @pathType()
30
31
  public points: number[]
@@ -32,12 +33,12 @@ export class Line extends UI implements ILine {
32
33
  @pathType(0)
33
34
  public curve: boolean | number
34
35
 
35
- public get resizeable(): boolean { return !this.points }
36
-
36
+ @pathType(false)
37
+ declare public closed: boolean
37
38
 
38
39
  public get toPoint(): IPointData {
39
40
  const { width, rotation } = this.__
40
- const to: IPointData = { x: 0, y: 0 }
41
+ const to: IPointData = getPointData()
41
42
 
42
43
  if (width) to.x = width
43
44
  if (rotation) rotate(to, rotation)
@@ -62,7 +63,7 @@ export class Line extends UI implements ILine {
62
63
 
63
64
  if (this.__.points) {
64
65
 
65
- drawPoints(path, this.__.points, false)
66
+ drawPoints(path, this.__.points, this.__.closed)
66
67
 
67
68
  } else {
68
69
 
@@ -73,8 +74,10 @@ export class Line extends UI implements ILine {
73
74
  }
74
75
 
75
76
  public __updateRenderPath(): void {
76
- if (this.__.points && this.__.curve) {
77
- drawPoints(this.__.__pathForRender = [], this.__.points, this.__.curve, false)
77
+ const data = this.__
78
+ if (!this.pathInputed && data.points && data.curve) {
79
+ drawPoints(data.__pathForRender = [], data.points, data.curve, data.closed)
80
+ if (data.__useArrow) PathArrow.addArrows(this, false)
78
81
  } else {
79
82
  super.__updateRenderPath()
80
83
  }
@@ -82,8 +85,7 @@ export class Line extends UI implements ILine {
82
85
 
83
86
  public __updateBoxBounds(): void {
84
87
  if (this.points) {
85
- toBounds(this.__.path, this.__layout.boxBounds)
86
- this.__updateNaturalSize()
88
+ toBounds(this.__.__pathForRender, this.__layout.boxBounds)
87
89
  } else {
88
90
  super.__updateBoxBounds()
89
91
  }
package/src/Path.ts CHANGED
@@ -1,14 +1,11 @@
1
- import { IPathCommandData, IWindingRule } from '@leafer/interface'
2
- import { PathBounds, dataProcessor, pathType, affectStrokeBoundsType, registerUI } from '@leafer/core'
1
+ import { dataProcessor, affectStrokeBoundsType, registerUI } from '@leafer/core'
3
2
 
4
- import { IPath, IPathData, IPathInputData, IPathString, IStrokeAlign } from '@leafer-ui/interface'
3
+ import { IPath, IPathData, IPathInputData, IStrokeAlign } from '@leafer-ui/interface'
5
4
  import { PathData } from '@leafer-ui/data'
6
5
 
7
6
  import { UI } from './UI'
8
7
 
9
8
 
10
- const { toBounds } = PathBounds
11
-
12
9
  @registerUI()
13
10
  export class Path extends UI implements IPath {
14
11
 
@@ -17,24 +14,12 @@ export class Path extends UI implements IPath {
17
14
  @dataProcessor(PathData)
18
15
  declare public __: IPathData
19
16
 
20
- @pathType()
21
- public path: IPathCommandData | IPathString
22
-
23
- @pathType()
24
- public windingRule: IWindingRule
25
-
26
17
  @affectStrokeBoundsType('center')
27
18
  declare public strokeAlign: IStrokeAlign
28
19
 
29
- public get resizeable(): boolean { return false }
30
-
31
20
  constructor(data?: IPathInputData) {
32
21
  super(data)
33
- }
34
-
35
- public __updateBoxBounds(): void {
36
- toBounds(this.__.path, this.__layout.boxBounds)
37
- this.__updateNaturalSize()
22
+ this.__.__pathInputed = 2
38
23
  }
39
24
 
40
25
  }
package/src/Pen.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { PathCreator, dataProcessor, registerUI, useModule } from '@leafer/core'
1
+ import { PathCreator, dataProcessor, defineKey, registerUI, useModule } from '@leafer/core'
2
2
 
3
3
  import { IPenData, IPenInputData, IPathInputData, IPathCommandData, IPath, IPen } from '@leafer-ui/interface'
4
4
  import { PenData } from '@leafer-ui/data'
@@ -7,7 +7,7 @@ import { Group } from './Group'
7
7
  import { Path } from './Path'
8
8
 
9
9
 
10
- @useModule(PathCreator, ['beginPath'])
10
+ @useModule(PathCreator, ['set', 'beginPath', 'path'])
11
11
  @registerUI()
12
12
  export class Pen extends Group implements IPen {
13
13
 
@@ -18,7 +18,11 @@ export class Pen extends Group implements IPen {
18
18
 
19
19
  public pathElement: IPath
20
20
  public pathStyle: IPathInputData
21
- public path: IPathCommandData
21
+
22
+ @penPathType()
23
+ declare public path: IPathCommandData // use __path, readonly
24
+
25
+ public __path: IPathCommandData
22
26
 
23
27
  constructor(data?: IPenInputData) {
24
28
  super(data)
@@ -27,13 +31,13 @@ export class Pen extends Group implements IPen {
27
31
  public setStyle(data: IPathInputData): Pen {
28
32
  const path = this.pathElement = new Path(data)
29
33
  this.pathStyle = data
30
- this.path = path.path as IPathCommandData || (path.path = [])
34
+ this.__path = path.path as IPathCommandData || (path.path = [])
31
35
  this.add(path)
32
36
  return this
33
37
  }
34
38
 
35
39
  public beginPath(): Pen {
36
- this.path.length = 0
40
+ this.__path.length = 0
37
41
  this.paint()
38
42
  return this
39
43
  }
@@ -72,13 +76,19 @@ export class Pen extends Group implements IPen {
72
76
 
73
77
  public drawPoints(_points: number[], _curve?: boolean | number, _close?: boolean): Pen { return this }
74
78
 
79
+ public clearPath(): Pen { return this }
75
80
 
76
81
  public paint(): void {
77
82
  this.pathElement.forceUpdate('path')
78
83
  }
79
84
 
80
- public clear(): void {
81
- this.removeAll(true)
82
- }
83
85
 
86
+ }
87
+
88
+ function penPathType() {
89
+ return (target: IPen, key: string) => {
90
+ defineKey(target, key, {
91
+ get() { return this.__path }
92
+ })
93
+ }
84
94
  }
package/src/Polygon.ts CHANGED
@@ -1,16 +1,18 @@
1
- import { __Number } from '@leafer/interface'
2
- import { PathBounds, PathCommandDataHelper, dataProcessor, pathType, registerUI } from '@leafer/core'
1
+ import { INumber } from '@leafer/interface'
2
+ import { PathCommandDataHelper, dataProcessor, pathType, registerUI, rewrite, rewriteAble } from '@leafer/core'
3
3
 
4
4
  import { IPolygon, IPolygonData, IPolygonInputData } from '@leafer-ui/interface'
5
5
  import { PolygonData } from '@leafer-ui/data'
6
6
 
7
7
  import { UI } from './UI'
8
+ import { Line } from './Line'
8
9
 
9
10
 
10
11
  const { sin, cos, PI } = Math
11
12
  const { moveTo, lineTo, closePath, drawPoints } = PathCommandDataHelper
12
- const { toBounds } = PathBounds
13
+ const line = Line.prototype
13
14
 
15
+ @rewriteAble()
14
16
  @registerUI()
15
17
  export class Polygon extends UI implements IPolygon {
16
18
 
@@ -20,7 +22,7 @@ export class Polygon extends UI implements IPolygon {
20
22
  declare public __: IPolygonData
21
23
 
22
24
  @pathType(3)
23
- sides: number
25
+ sides: INumber
24
26
 
25
27
  @pathType()
26
28
  points: number[]
@@ -28,8 +30,6 @@ export class Polygon extends UI implements IPolygon {
28
30
  @pathType(0)
29
31
  curve: boolean | number
30
32
 
31
- public get resizeable(): boolean { return !this.points }
32
-
33
33
  constructor(data?: IPolygonInputData) {
34
34
  super(data)
35
35
  }
@@ -58,18 +58,10 @@ export class Polygon extends UI implements IPolygon {
58
58
  closePath(path)
59
59
  }
60
60
 
61
+ @rewrite(line.__updateRenderPath)
62
+ public __updateRenderPath(): void { }
61
63
 
62
- public __updateRenderPath(): void {
63
- if (this.__.points && this.__.curve) {
64
- drawPoints(this.__.__pathForRender = [], this.__.points, this.__.curve, true)
65
- this.__updateNaturalSize()
66
- } else {
67
- super.__updateRenderPath()
68
- }
69
- }
70
-
71
- public __updateBoxBounds(): void {
72
- this.__.points ? toBounds(this.__.path, this.__layout.boxBounds) : super.__updateBoxBounds()
73
- }
64
+ @rewrite(line.__updateBoxBounds)
65
+ public __updateBoxBounds(): void { }
74
66
 
75
67
  }