@leafer/selector 1.0.0-rc.9 → 1.0.1
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 +4 -4
- package/src/{Pather.ts → Picker.ts} +37 -22
- package/src/Selector.ts +27 -17
- package/types/index.d.ts +11 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer/selector",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "@leafer/selector",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
"type": "git",
|
|
16
16
|
"url": "https://github.com/leaferjs/leafer.git"
|
|
17
17
|
},
|
|
18
|
-
"homepage": "https://github.com/leaferjs/leafer/tree/main/packages/selector",
|
|
18
|
+
"homepage": "https://github.com/leaferjs/leafer/tree/main/packages/partner/selector",
|
|
19
19
|
"bugs": "https://github.com/leaferjs/leafer/issues",
|
|
20
20
|
"keywords": [
|
|
21
21
|
"leafer",
|
|
22
22
|
"leaferjs"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@leafer/core": "1.0.
|
|
25
|
+
"@leafer/core": "1.0.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@leafer/interface": "1.0.
|
|
28
|
+
"@leafer/interface": "1.0.1"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { ILeaf, ILeafList, IPointData, IRadiusPointData,
|
|
1
|
+
import { ILeaf, ILeafList, IPointData, IRadiusPointData, IPickResult, IPickOptions, ISelector, IPickBottom } from '@leafer/interface'
|
|
2
2
|
import { BoundsHelper, LeafList, LeafHelper } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const { hitRadiusPoint } = BoundsHelper
|
|
6
6
|
|
|
7
|
-
export class
|
|
7
|
+
export class Picker {
|
|
8
8
|
|
|
9
9
|
protected target: ILeaf
|
|
10
10
|
protected selector: ISelector
|
|
11
11
|
|
|
12
|
-
protected findList:
|
|
12
|
+
protected findList: ILeafList
|
|
13
13
|
protected exclude: ILeafList
|
|
14
14
|
|
|
15
15
|
protected point: IRadiusPointData
|
|
@@ -19,45 +19,53 @@ export class Pather {
|
|
|
19
19
|
this.selector = selector
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
public getByPoint(hitPoint: IPointData, hitRadius: number, options?:
|
|
22
|
+
public getByPoint(hitPoint: IPointData, hitRadius: number, options?: IPickOptions): IPickResult {
|
|
23
23
|
if (!hitRadius) hitRadius = 0
|
|
24
24
|
if (!options) options = {}
|
|
25
25
|
|
|
26
26
|
const through = options.through || false
|
|
27
27
|
const ignoreHittable = options.ignoreHittable || false
|
|
28
|
+
const target = options.target || this.target
|
|
28
29
|
this.exclude = options.exclude || null
|
|
29
30
|
|
|
30
31
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius }
|
|
31
|
-
this.findList =
|
|
32
|
+
this.findList = new LeafList(options.findList)
|
|
32
33
|
|
|
33
34
|
// path
|
|
34
|
-
|
|
35
|
+
if (!options.findList) this.hitBranch(target) // 包含through元素
|
|
35
36
|
|
|
36
|
-
const list = this.findList
|
|
37
|
-
const leaf = this.getBestMatchLeaf()
|
|
37
|
+
const { list } = this.findList
|
|
38
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable)
|
|
38
39
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf)
|
|
39
40
|
|
|
40
41
|
this.clear()
|
|
41
42
|
|
|
42
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf }
|
|
43
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf }
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
public getBestMatchLeaf(): ILeaf {
|
|
46
|
-
|
|
47
|
-
if (targets.length > 1) {
|
|
46
|
+
public getBestMatchLeaf(list: ILeaf[], bottomList: IPickBottom[], ignoreHittable: boolean): ILeaf {
|
|
47
|
+
if (list.length) {
|
|
48
48
|
let find: ILeaf
|
|
49
|
-
this.findList =
|
|
49
|
+
this.findList = new LeafList()
|
|
50
50
|
const { x, y } = this.point
|
|
51
51
|
const point = { x, y, radiusX: 0, radiusY: 0 }
|
|
52
|
-
for (let i = 0, len =
|
|
53
|
-
find =
|
|
54
|
-
if (LeafHelper.worldHittable(find)) {
|
|
52
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
53
|
+
find = list[i]
|
|
54
|
+
if (ignoreHittable || LeafHelper.worldHittable(find)) {
|
|
55
55
|
this.hitChild(find, point)
|
|
56
|
-
if (this.findList.length) return this.findList[0]
|
|
56
|
+
if (this.findList.length) return this.findList.list[0]
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
|
+
if (bottomList) { // 底部虚拟元素
|
|
62
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
63
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy)
|
|
64
|
+
if (this.findList.length) return this.findList.list[0]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return list[0]
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
public getPath(leaf: ILeaf): LeafList {
|
|
@@ -71,7 +79,7 @@ export class Pather {
|
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
public getHitablePath(leaf: ILeaf): LeafList {
|
|
74
|
-
const path = this.getPath(leaf)
|
|
82
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null)
|
|
75
83
|
let item: ILeaf, hittablePath = new LeafList()
|
|
76
84
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
77
85
|
item = path.list[i]
|
|
@@ -103,13 +111,16 @@ export class Pather {
|
|
|
103
111
|
return throughPath
|
|
104
112
|
}
|
|
105
113
|
|
|
114
|
+
protected hitBranch(branch: ILeaf): void {
|
|
115
|
+
this.eachFind(branch.children, branch.__onlyHitMask)
|
|
116
|
+
}
|
|
106
117
|
|
|
107
118
|
protected eachFind(children: ILeaf[], hitMask: boolean): void {
|
|
108
119
|
let child: ILeaf, hit: boolean
|
|
109
120
|
const { point } = this, len = children.length
|
|
110
121
|
for (let i = len - 1; i > -1; i--) {
|
|
111
122
|
child = children[i]
|
|
112
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
123
|
+
if (!child.__.visible || (hitMask && !child.__.mask)) continue
|
|
113
124
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point)
|
|
114
125
|
|
|
115
126
|
if (child.isBranch) {
|
|
@@ -123,9 +134,13 @@ export class Pather {
|
|
|
123
134
|
}
|
|
124
135
|
}
|
|
125
136
|
|
|
126
|
-
protected hitChild(child: ILeaf, point: IRadiusPointData): void {
|
|
137
|
+
protected hitChild(child: ILeaf, point: IRadiusPointData, proxy?: ILeaf): void {
|
|
127
138
|
if (this.exclude && this.exclude.has(child)) return
|
|
128
|
-
if (child.__hitWorld(point))
|
|
139
|
+
if (child.__hitWorld(point)) {
|
|
140
|
+
const { parent } = child
|
|
141
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point))) return
|
|
142
|
+
this.findList.add(proxy || child)
|
|
143
|
+
}
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
protected clear(): void {
|
package/src/Selector.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ILeaf, ILeafMap, ISelector, ISelectorProxy,
|
|
2
|
-
import { ChildEvent, LayoutEvent, DataHelper, Platform, PropertyEvent, LeafHelper } from '@leafer/core'
|
|
1
|
+
import { ILeaf, ILeafMap, ISelector, ISelectorProxy, IPickResult, IPickOptions, IPointData, IEventListenerId, ISelectorConfig, IFindMethod, IAnswer, IFindCondition, IBooleanMap } from '@leafer/interface'
|
|
2
|
+
import { ChildEvent, LayoutEvent, DataHelper, Answer, Platform, PropertyEvent, LeafHelper } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { Picker } from './Picker'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
const { Yes, NoAndSkip, YesAndSkip } =
|
|
8
|
-
|
|
7
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer
|
|
8
|
+
const idCondition = {} as IFindCondition, classNameCondition = {} as IFindCondition, tagCondition = {} as IFindCondition
|
|
9
9
|
export class Selector implements ISelector {
|
|
10
10
|
|
|
11
11
|
public target: ILeaf
|
|
@@ -14,7 +14,7 @@ export class Selector implements ISelector {
|
|
|
14
14
|
|
|
15
15
|
public config: ISelectorConfig = {}
|
|
16
16
|
|
|
17
|
-
protected
|
|
17
|
+
protected picker: Picker
|
|
18
18
|
|
|
19
19
|
protected innerIdMap: ILeafMap = {}
|
|
20
20
|
protected idMap: ILeafMap = {}
|
|
@@ -25,7 +25,8 @@ export class Selector implements ISelector {
|
|
|
25
25
|
id: (leaf: ILeaf, name: string) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
26
26
|
innerId: (leaf: ILeaf, innerId: number) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
27
27
|
className: (leaf: ILeaf, name: string) => leaf.className === name ? 1 : 0,
|
|
28
|
-
tag: (leaf: ILeaf, name: string) => leaf.__tag === name ? 1 : 0
|
|
28
|
+
tag: (leaf: ILeaf, name: string) => leaf.__tag === name ? 1 : 0,
|
|
29
|
+
tags: (leaf: ILeaf, nameMap: IBooleanMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
protected __eventIds: IEventListenerId[]
|
|
@@ -34,11 +35,11 @@ export class Selector implements ISelector {
|
|
|
34
35
|
constructor(target: ILeaf, userConfig?: ISelectorConfig) {
|
|
35
36
|
this.target = target
|
|
36
37
|
if (userConfig) this.config = DataHelper.default(userConfig, this.config)
|
|
37
|
-
this.
|
|
38
|
+
this.picker = new Picker(target, this)
|
|
38
39
|
this.__listenEvents()
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
public getBy(condition: number | string | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[] {
|
|
42
|
+
public getBy(condition: number | string | IFindCondition | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[] {
|
|
42
43
|
switch (typeof condition) {
|
|
43
44
|
case 'number':
|
|
44
45
|
const leaf = this.getByInnerId(condition, branch)
|
|
@@ -46,21 +47,30 @@ export class Selector implements ISelector {
|
|
|
46
47
|
case 'string':
|
|
47
48
|
switch (condition[0]) {
|
|
48
49
|
case '#':
|
|
49
|
-
|
|
50
|
-
return one ? leaf : (leaf ? [leaf] : [])
|
|
50
|
+
idCondition.id = condition.substring(1), condition = idCondition; break
|
|
51
51
|
case '.':
|
|
52
|
-
|
|
52
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition; break
|
|
53
53
|
default:
|
|
54
|
-
|
|
54
|
+
tagCondition.tag = condition, condition = tagCondition
|
|
55
|
+
}
|
|
56
|
+
case 'object':
|
|
57
|
+
if (condition.id !== undefined) {
|
|
58
|
+
const leaf = this.getById(condition.id as string, branch)
|
|
59
|
+
return one ? leaf : (leaf ? [leaf] : [])
|
|
60
|
+
} else if (condition.tag) {
|
|
61
|
+
const { tag } = condition, isArray = tag instanceof Array
|
|
62
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag)
|
|
63
|
+
} else {
|
|
64
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className)
|
|
55
65
|
}
|
|
56
66
|
case 'function':
|
|
57
67
|
return this.getByMethod(condition as IFindMethod, branch, one, options)
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
public getByPoint(hitPoint: IPointData, hitRadius: number, options?:
|
|
71
|
+
public getByPoint(hitPoint: IPointData, hitRadius: number, options?: IPickOptions): IPickResult {
|
|
62
72
|
if (Platform.name === 'node') this.target.emit(LayoutEvent.CHECK_UPDATE)
|
|
63
|
-
return this.
|
|
73
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options)
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
public getByInnerId(innerId: number, branch?: ILeaf): ILeaf {
|
|
@@ -93,7 +103,7 @@ export class Selector implements ISelector {
|
|
|
93
103
|
|
|
94
104
|
|
|
95
105
|
protected eachFind(children: ILeaf[], method: IFindMethod, list?: ILeaf[], options?: any): void {
|
|
96
|
-
let child: ILeaf, result:
|
|
106
|
+
let child: ILeaf, result: IAnswer
|
|
97
107
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
98
108
|
child = children[i]
|
|
99
109
|
result = method(child, options)
|
|
@@ -144,7 +154,7 @@ export class Selector implements ISelector {
|
|
|
144
154
|
public destroy(): void {
|
|
145
155
|
if (this.__eventIds.length) {
|
|
146
156
|
this.__removeListenEvents()
|
|
147
|
-
this.
|
|
157
|
+
this.picker.destroy()
|
|
148
158
|
this.findLeaf = null
|
|
149
159
|
this.innerIdMap = {}
|
|
150
160
|
this.idMap = {}
|
package/types/index.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { ILeaf, ISelector, ILeafList, IRadiusPointData, IPointData,
|
|
1
|
+
import { ILeaf, ISelector, ILeafList, IRadiusPointData, IPointData, IPickOptions, IPickResult, IPickBottom, ISelectorProxy, ISelectorConfig, ILeafMap, IBooleanMap, IEventListenerId, IFindCondition, IFindMethod } from '@leafer/interface';
|
|
2
2
|
import { LeafList, ChildEvent, PropertyEvent } from '@leafer/core';
|
|
3
3
|
|
|
4
|
-
declare class
|
|
4
|
+
declare class Picker {
|
|
5
5
|
protected target: ILeaf;
|
|
6
6
|
protected selector: ISelector;
|
|
7
|
-
protected findList:
|
|
7
|
+
protected findList: ILeafList;
|
|
8
8
|
protected exclude: ILeafList;
|
|
9
9
|
protected point: IRadiusPointData;
|
|
10
10
|
constructor(target: ILeaf, selector: ISelector);
|
|
11
|
-
getByPoint(hitPoint: IPointData, hitRadius: number, options?:
|
|
12
|
-
getBestMatchLeaf(): ILeaf;
|
|
11
|
+
getByPoint(hitPoint: IPointData, hitRadius: number, options?: IPickOptions): IPickResult;
|
|
12
|
+
getBestMatchLeaf(list: ILeaf[], bottomList: IPickBottom[], ignoreHittable: boolean): ILeaf;
|
|
13
13
|
getPath(leaf: ILeaf): LeafList;
|
|
14
14
|
getHitablePath(leaf: ILeaf): LeafList;
|
|
15
15
|
getThroughPath(list: ILeaf[]): LeafList;
|
|
16
|
+
protected hitBranch(branch: ILeaf): void;
|
|
16
17
|
protected eachFind(children: ILeaf[], hitMask: boolean): void;
|
|
17
|
-
protected hitChild(child: ILeaf, point: IRadiusPointData): void;
|
|
18
|
+
protected hitChild(child: ILeaf, point: IRadiusPointData, proxy?: ILeaf): void;
|
|
18
19
|
protected clear(): void;
|
|
19
20
|
destroy(): void;
|
|
20
21
|
}
|
|
@@ -23,7 +24,7 @@ declare class Selector implements ISelector {
|
|
|
23
24
|
target: ILeaf;
|
|
24
25
|
proxy?: ISelectorProxy;
|
|
25
26
|
config: ISelectorConfig;
|
|
26
|
-
protected
|
|
27
|
+
protected picker: Picker;
|
|
27
28
|
protected innerIdMap: ILeafMap;
|
|
28
29
|
protected idMap: ILeafMap;
|
|
29
30
|
protected findLeaf: ILeaf;
|
|
@@ -32,11 +33,12 @@ declare class Selector implements ISelector {
|
|
|
32
33
|
innerId: (leaf: ILeaf, innerId: number) => 1 | 0;
|
|
33
34
|
className: (leaf: ILeaf, name: string) => 1 | 0;
|
|
34
35
|
tag: (leaf: ILeaf, name: string) => 1 | 0;
|
|
36
|
+
tags: (leaf: ILeaf, nameMap: IBooleanMap) => 1 | 0;
|
|
35
37
|
};
|
|
36
38
|
protected __eventIds: IEventListenerId[];
|
|
37
39
|
constructor(target: ILeaf, userConfig?: ISelectorConfig);
|
|
38
|
-
getBy(condition: number | string | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[];
|
|
39
|
-
getByPoint(hitPoint: IPointData, hitRadius: number, options?:
|
|
40
|
+
getBy(condition: number | string | IFindCondition | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[];
|
|
41
|
+
getByPoint(hitPoint: IPointData, hitRadius: number, options?: IPickOptions): IPickResult;
|
|
40
42
|
getByInnerId(innerId: number, branch?: ILeaf): ILeaf;
|
|
41
43
|
getById(id: string, branch?: ILeaf): ILeaf;
|
|
42
44
|
getByClassName(className: string, branch?: ILeaf): ILeaf[];
|