@leafer/selector 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/selector",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "@leafer/selector",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -19,11 +19,11 @@
19
19
  "leaferjs"
20
20
  ],
21
21
  "dependencies": {
22
- "@leafer/event": "1.0.0-alpha.21",
23
- "@leafer/math": "1.0.0-alpha.21",
24
- "@leafer/list": "1.0.0-alpha.21"
22
+ "@leafer/event": "1.0.0-alpha.30",
23
+ "@leafer/math": "1.0.0-alpha.30",
24
+ "@leafer/list": "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
  }
@@ -0,0 +1,141 @@
1
+ import { ILeaf, ILeafList, IPointData, IRadiusPointData, ISelectPathResult, ISelectPathOptions, ISelector } from '@leafer/interface'
2
+ import { BoundsHelper } from '@leafer/math'
3
+ import { LeafList } from '@leafer/list'
4
+
5
+
6
+ const { hitRadiusPoint } = BoundsHelper
7
+
8
+ export class FindPath {
9
+
10
+ protected target: ILeaf
11
+ protected selector: ISelector
12
+
13
+ protected findList: ILeaf[]
14
+ protected exclude: ILeafList
15
+
16
+ protected point: IRadiusPointData
17
+
18
+ constructor(target: ILeaf, selector: ISelector) {
19
+ this.target = target
20
+ this.selector = selector
21
+ }
22
+
23
+ public getByPoint(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
24
+ if (!hitRadius) hitRadius = 0
25
+ if (!options) options = {}
26
+
27
+ const through = options.through || false
28
+ const ignoreHittable = options.ignoreHittable || false
29
+ this.exclude = options.exclude || null
30
+
31
+ this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius }
32
+ this.findList = []
33
+
34
+ // path
35
+ this.eachFind(this.target.children, this.target.__onlyHitMask)
36
+
37
+ const list = this.findList
38
+ const leaf = this.getBestMatchLeaf()
39
+ const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf)
40
+
41
+ this.clear()
42
+
43
+ return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf }
44
+ }
45
+
46
+ public getBestMatchLeaf(): ILeaf {
47
+ const { findList: targets } = this
48
+ if (targets.length > 1) {
49
+ let find: ILeaf
50
+ this.findList = []
51
+ const { x, y } = this.point
52
+ const point = { x, y, radiusX: 0, radiusY: 0 }
53
+ for (let i = 0, len = targets.length; i < len; i++) {
54
+ find = targets[i]
55
+ this.hitChild(find, point)
56
+ if (this.findList.length) return this.findList[0]
57
+ }
58
+ }
59
+ return targets[0]
60
+ }
61
+
62
+ public getPath(leaf: ILeaf): LeafList {
63
+ const path = new LeafList()
64
+ while (leaf) {
65
+ path.push(leaf)
66
+ leaf = leaf.parent
67
+ }
68
+ path.push(this.target)
69
+ return path
70
+ }
71
+
72
+ public getHitablePath(leaf: ILeaf): LeafList {
73
+ const path = this.getPath(leaf)
74
+ let item: ILeaf, hittablePath = new LeafList()
75
+ for (let i = path.list.length - 1; i > -1; i--) {
76
+ item = path.list[i]
77
+ if (!item.__.hittable) break
78
+ hittablePath.unshift(item)
79
+ if (!item.__.hitChildren) break
80
+ }
81
+ return hittablePath
82
+ }
83
+
84
+ public getThroughPath(list: ILeaf[]): LeafList {
85
+ const throughPath = new LeafList()
86
+ const pathList: ILeafList[] = []
87
+
88
+ for (let i = list.length - 1; i > -1; i--) {
89
+ pathList.push(this.getPath(list[i]))
90
+ }
91
+
92
+ let path: ILeafList, nextPath: ILeafList, leaf: ILeaf
93
+ for (let i = 0, len = pathList.length; i < len; i++) {
94
+ path = pathList[i], nextPath = pathList[i + 1]
95
+ for (let j = 0, jLen = path.length; j < jLen; j++) {
96
+ leaf = path.list[j]
97
+ if (nextPath && nextPath.has(leaf)) break
98
+ throughPath.push(leaf)
99
+ }
100
+ }
101
+
102
+ return throughPath
103
+ }
104
+
105
+
106
+ protected eachFind(children: Array<ILeaf>, hitMask: boolean): void {
107
+ let child: ILeaf, hit: boolean
108
+ const { point } = this, len = children.length
109
+ for (let i = len - 1; i > -1; i--) {
110
+ child = children[i]
111
+ if (hitMask && !child.isMask) continue
112
+ hit = hitRadiusPoint(child.__world, point)
113
+
114
+ if (child.isBranch) {
115
+ if (hit || child.__ignoreHitWorld) {
116
+ this.eachFind(child.children, child.__onlyHitMask)
117
+ if (child.isBranchLeaf && !this.findList.length) this.hitChild(child, point) // like frame
118
+ }
119
+ } else {
120
+ if (hit) this.hitChild(child, point)
121
+ }
122
+ }
123
+ }
124
+
125
+ protected hitChild(child: ILeaf, point: IRadiusPointData): void {
126
+ if (this.exclude && this.exclude.has(child)) return
127
+ if (child.__hitWorld(point)) this.findList.push(child)
128
+ }
129
+
130
+ protected clear(): void {
131
+ this.point = null
132
+ this.findList = null
133
+ this.exclude = null
134
+ }
135
+
136
+ public destroy(): void {
137
+ this.target = null
138
+ this.selector = null
139
+ }
140
+
141
+ }
package/src/Selector.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { ILeaf, ILeafArrayMap, ILeafMap, ISelector, ISelectPathResult, ISelectPathOptions, IPointData, ILeafList, IEventListenerId } from '@leafer/interface'
2
- import { ChildEvent } from '@leafer/event'
3
- import { LeafList } from '@leafer/list'
1
+ import { ILeaf, ILeafArrayMap, ILeafMap, ISelector, ISelectPathResult, ISelectPathOptions, IPointData, IEventListenerId, ISelectorConfig } from '@leafer/interface'
2
+ import { ChildEvent, LayoutEvent } from '@leafer/event'
3
+ import { DataHelper } from '@leafer/data'
4
4
 
5
- import { PathFinder } from './PathFinder'
5
+ import { FindPath } from './FindPath'
6
6
 
7
7
 
8
8
  interface IFind {
@@ -13,9 +13,10 @@ interface IFind {
13
13
  export class Selector implements ISelector {
14
14
 
15
15
  public target: ILeaf
16
- public defaultPath: ILeafList
17
16
 
18
- protected pathFinder: PathFinder
17
+ public config: ISelectorConfig = {}
18
+
19
+ protected findPath: FindPath
19
20
 
20
21
  protected innerIdList: ILeafMap = {}
21
22
  protected idList: ILeafMap = {}
@@ -24,18 +25,18 @@ export class Selector implements ISelector {
24
25
 
25
26
  protected __eventIds: IEventListenerId[]
26
27
 
27
- constructor(target: ILeaf) {
28
+ constructor(target: ILeaf, userConfig?: ISelectorConfig) {
28
29
  this.target = target
29
- this.defaultPath = new LeafList(target)
30
- this.pathFinder = new PathFinder(target, this)
30
+ if (userConfig) this.config = DataHelper.default(userConfig, this.config)
31
+ this.findPath = new FindPath(target, this)
31
32
  this.__listenEvents()
32
33
  }
33
34
 
34
- public getHitPointPath(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
35
- return this.pathFinder.getHitPointPath(hitPoint, hitRadius, options)
35
+ public getByPoint(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
36
+ this.target.emit(LayoutEvent.CHECK_UPDATE)
37
+ return this.findPath.getByPoint(hitPoint, hitRadius, options)
36
38
  }
37
39
 
38
-
39
40
  public find(name: number | string, branch?: ILeaf): ILeaf | ILeaf[] {
40
41
  if (typeof name === 'number') {
41
42
  return this.getByInnerId(name, branch)
@@ -96,7 +97,7 @@ export class Selector implements ISelector {
96
97
  if (!branch) branch = this.target
97
98
  let find: Array<ILeaf | ILeaf> = []
98
99
  this.loopFind(branch, (leaf) => {
99
- if (leaf.tag === name) find.push(leaf)
100
+ if (leaf.__tag === name) find.push(leaf)
100
101
  return false
101
102
  })
102
103
  return find
@@ -108,7 +109,7 @@ export class Selector implements ISelector {
108
109
  for (let i = 0, len = children.length; i < len; i++) {
109
110
  branch = children[i] as ILeaf
110
111
  if (find(branch)) return
111
- if (branch.__isBranch) this.loopFind(branch, find)
112
+ if (branch.isBranch) this.loopFind(branch, find)
112
113
  }
113
114
  }
114
115
 
@@ -132,10 +133,10 @@ export class Selector implements ISelector {
132
133
  public destroy(): void {
133
134
  if (this.target) {
134
135
  this.__removeListenEvents()
135
- this.pathFinder.destroy()
136
+ this.findPath.destroy()
136
137
 
137
138
  this.target = null
138
- this.pathFinder = null
139
+ this.findPath = null
139
140
  this.innerIdList = null
140
141
  this.idList = null
141
142
  this.classNameList = null
package/src/PathFinder.ts DELETED
@@ -1,128 +0,0 @@
1
- import { ILeaf, ILeafList, IPointData, IRadiusPointData, ISelectPathResult, ISelectPathOptions, ISelector } from '@leafer/interface'
2
- import { BoundsHelper } from '@leafer/math'
3
- import { LeafList } from '@leafer/list'
4
-
5
- const { hitRadiusPoint } = BoundsHelper
6
-
7
-
8
- export class PathFinder {
9
-
10
- protected target: ILeaf
11
- protected selector: ISelector
12
-
13
- protected leaf?: ILeaf
14
- protected throughPath: ILeafList
15
- protected exclude: ILeafList
16
-
17
- protected point: IRadiusPointData
18
- protected isStop: boolean
19
-
20
- constructor(target: ILeaf, selector: ISelector) {
21
- this.target = target
22
- this.selector = selector
23
- }
24
-
25
- public getHitPointPath(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
26
- const through = options ? options.through : false
27
- this.exclude = options ? options.exclude : null
28
-
29
- this.isStop = false
30
- this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius }
31
-
32
- // path
33
- this.eachFind(this.target.children)
34
-
35
- const { leaf } = this
36
- const { defaultPath } = this.selector
37
- const path = this.getPath(leaf)
38
- path.pushList(defaultPath.list)
39
-
40
- let result: ISelectPathResult
41
-
42
- // throughPath
43
- if (through) {
44
- const throughPath = this.throughPath = new LeafList()
45
- this.eachThroughFind(this.target.children)
46
- throughPath.pushList(defaultPath.list)
47
- result = { path, leaf, throughPath }
48
- } else {
49
- result = { path, leaf }
50
- }
51
-
52
- this.clear()
53
-
54
- return result
55
-
56
- }
57
-
58
- public getPath(leaf: ILeaf): LeafList {
59
- const list: LeafList = new LeafList()
60
- while (leaf) {
61
- list.push(leaf)
62
- leaf = leaf.parent
63
- }
64
- return list
65
- }
66
-
67
- protected eachThroughFind(children: Array<ILeaf>): void {
68
- let child: ILeaf
69
- const { point } = this, len = children.length
70
- for (let i = len - 1; i > -1; i--) {
71
- child = children[i]
72
- if (child.__.hittable) {
73
- if (hitRadiusPoint(child.__world, point)) {
74
- if (child.__isBranch && child.__.hitChildren) this.eachThroughFind(child.children)
75
-
76
- if (this.exclude && this.exclude.has(child)) continue
77
- if (child.__hitWorld(point)) this.throughPath.push(child)
78
- }
79
- }
80
- }
81
- }
82
-
83
- protected eachFind(children: Array<ILeaf>): void {
84
- let child: ILeaf
85
- const { point } = this, len = children.length
86
- for (let i = len - 1; i > -1; i--) {
87
- child = children[i]
88
- if (child.__.hittable) {
89
- if (hitRadiusPoint(child.__world, point)) {
90
- if (child.__isBranch) {
91
-
92
- if (child.__.hitChildren) this.eachFind(child.children)
93
-
94
- if (child.__isBranchLeaf) { // 填充了背景色的Group, 如画板/Frame元素
95
- if (!this.isStop) this.hitChild(child, point)
96
- }
97
-
98
- } else {
99
- this.hitChild(child, point)
100
- }
101
- }
102
-
103
- if (this.isStop) break
104
- }
105
- }
106
- }
107
-
108
- protected hitChild(child: ILeaf, point: IRadiusPointData): void {
109
- if (this.exclude && this.exclude.has(child)) return
110
- if (child.__hitWorld(point)) {
111
- this.leaf = child
112
- this.isStop = true
113
- }
114
- }
115
-
116
- protected clear(): void {
117
- this.point = null
118
- this.leaf = null
119
- this.throughPath = null
120
- this.exclude = null
121
- }
122
-
123
- public destroy(): void {
124
- this.target = null
125
- this.selector = null
126
- }
127
-
128
- }