@flighthq/interaction 0.1.0
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/dist/displayHitTests.d.ts +13 -0
- package/dist/displayHitTests.d.ts.map +1 -0
- package/dist/displayHitTests.js +38 -0
- package/dist/displayHitTests.js.map +1 -0
- package/dist/displayObjectOverlap.d.ts +5 -0
- package/dist/displayObjectOverlap.d.ts.map +1 -0
- package/dist/displayObjectOverlap.js +21 -0
- package/dist/displayObjectOverlap.js.map +1 -0
- package/dist/hitTests.d.ts +38 -0
- package/dist/hitTests.d.ts.map +1 -0
- package/dist/hitTests.js +80 -0
- package/dist/hitTests.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/interactionManager.d.ts +38 -0
- package/dist/interactionManager.d.ts.map +1 -0
- package/dist/interactionManager.js +470 -0
- package/dist/interactionManager.js.map +1 -0
- package/dist/registerDefaultHitTestPoints.d.ts +2 -0
- package/dist/registerDefaultHitTestPoints.d.ts.map +1 -0
- package/dist/registerDefaultHitTestPoints.js +21 -0
- package/dist/registerDefaultHitTestPoints.js.map +1 -0
- package/dist/spatialQuery.d.ts +4 -0
- package/dist/spatialQuery.d.ts.map +1 -0
- package/dist/spatialQuery.js +37 -0
- package/dist/spatialQuery.js.map +1 -0
- package/dist/spriteHitTests.d.ts +5 -0
- package/dist/spriteHitTests.d.ts.map +1 -0
- package/dist/spriteHitTests.js +11 -0
- package/dist/spriteHitTests.js.map +1 -0
- package/package.json +43 -0
- package/src/displayHitTests.test.ts +137 -0
- package/src/displayObjectOverlap.test.ts +78 -0
- package/src/hitTests.test.ts +206 -0
- package/src/interactionManager.test.ts +635 -0
- package/src/registerDefaultHitTestPoints.test.ts +29 -0
- package/src/spatialQuery.test.ts +47 -0
- package/src/spriteHitTests.test.ts +76 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NodeAny } from '@flighthq/types';
|
|
2
|
+
export declare function defaultBitmapHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
3
|
+
export declare function defaultDisplayObjectHitTestPointHandler(_source: NodeAny, _x: number, _y: number, _shapeFlag: boolean): boolean;
|
|
4
|
+
export declare function defaultHtmlViewHitTestPointHandler(_source: NodeAny, _x: number, _y: number, _shapeFlag: boolean): boolean;
|
|
5
|
+
export declare function defaultMovieClipHitTestPointHandler(_source: NodeAny, _x: number, _y: number, _shapeFlag: boolean): boolean;
|
|
6
|
+
export declare function defaultRenderViewHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
7
|
+
export declare function defaultRichTextHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
8
|
+
export declare function defaultShapeHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
9
|
+
export declare function defaultStageHitTestPointHandler(_source: NodeAny, _x: number, _y: number, _shapeFlag: boolean): boolean;
|
|
10
|
+
export declare function defaultTextHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
11
|
+
export declare function defaultTextInputHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
12
|
+
export declare function defaultVideoHitTestPointHandler(source: NodeAny, x: number, y: number, _shapeFlag: boolean): boolean;
|
|
13
|
+
//# sourceMappingURL=displayHitTests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayHitTests.d.ts","sourceRoot":"","sources":["../src/displayHitTests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAI/C,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAEpH;AAED,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,OAAO,GAClB,OAAO,CAET;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,OAAO,GAClB,OAAO,CAGT;AAED,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,OAAO,GAClB,OAAO,CAGT;AAED,wBAAgB,oCAAoC,CAClD,MAAM,EAAE,OAAO,EACf,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,UAAU,EAAE,OAAO,GAClB,OAAO,CAET;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,OAAO,EACf,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,UAAU,EAAE,OAAO,GAClB,OAAO,CAET;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAEnH;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,OAAO,GAClB,OAAO,CAGT;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAElH;AAED,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,OAAO,EACf,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,UAAU,EAAE,OAAO,GAClB,OAAO,CAET;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAEnH"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { hitTestGraphLocalBounds } from './hitTests';
|
|
2
|
+
export function defaultBitmapHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
3
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
4
|
+
}
|
|
5
|
+
export function defaultDisplayObjectHitTestPointHandler(_source, _x, _y, _shapeFlag) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
export function defaultHtmlViewHitTestPointHandler(_source, _x, _y, _shapeFlag) {
|
|
9
|
+
// HtmlView elements handle pointer events through the browser — not the canvas interaction system.
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
export function defaultMovieClipHitTestPointHandler(_source, _x, _y, _shapeFlag) {
|
|
13
|
+
// Containers have no self hit area — findGraphHitTarget traverses children separately.
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
export function defaultRenderViewHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
17
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
18
|
+
}
|
|
19
|
+
export function defaultRichTextHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
20
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
21
|
+
}
|
|
22
|
+
export function defaultShapeHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
23
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
24
|
+
}
|
|
25
|
+
export function defaultStageHitTestPointHandler(_source, _x, _y, _shapeFlag) {
|
|
26
|
+
// Containers have no self hit area — findGraphHitTarget traverses children separately.
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
export function defaultTextHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
30
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
31
|
+
}
|
|
32
|
+
export function defaultTextInputHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
33
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
34
|
+
}
|
|
35
|
+
export function defaultVideoHitTestPointHandler(source, x, y, _shapeFlag) {
|
|
36
|
+
return hitTestGraphLocalBounds(source, x, y);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=displayHitTests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayHitTests.js","sourceRoot":"","sources":["../src/displayHitTests.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,UAAU,gCAAgC,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS,EAAE,UAAmB;IACzG,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,OAAgB,EAChB,EAAU,EACV,EAAU,EACV,UAAmB;IAEnB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,OAAgB,EAChB,EAAU,EACV,EAAU,EACV,UAAmB;IAEnB,mGAAmG;IACnG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,OAAgB,EAChB,EAAU,EACV,EAAU,EACV,UAAmB;IAEnB,uFAAuF;IACvF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oCAAoC,CAClD,MAAe,EACf,CAAS,EACT,CAAS,EACT,UAAmB;IAEnB,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,MAAe,EACf,CAAS,EACT,CAAS,EACT,UAAmB;IAEnB,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS,EAAE,UAAmB;IACxG,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,OAAgB,EAChB,EAAU,EACV,EAAU,EACV,UAAmB;IAEnB,uFAAuF;IACvF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS,EAAE,UAAmB;IACvG,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,MAAe,EACf,CAAS,EACT,CAAS,EACT,UAAmB;IAEnB,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS,EAAE,UAAmB;IACxG,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DisplayObject, Rectangle } from '@flighthq/types';
|
|
2
|
+
export declare function containsDisplayObject(outer: DisplayObject, inner: DisplayObject): boolean;
|
|
3
|
+
export declare function getDisplayObjectOverlapRectangle(source: DisplayObject, other: DisplayObject, out: Rectangle): Rectangle;
|
|
4
|
+
export declare function hitTestDisplayObjectsShape(source: DisplayObject, other: DisplayObject): boolean;
|
|
5
|
+
//# sourceMappingURL=displayObjectOverlap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayObjectOverlap.d.ts","sourceRoot":"","sources":["../src/displayObjectOverlap.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEhE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAEzF;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,SAAS,GACb,SAAS,CAGX;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAS/F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { computeRectangleIntersection, containsRectanglePointXY, enclosesRectangle, intersectsRectangle, } from '@flighthq/geometry';
|
|
2
|
+
import { getNodeWorldBoundsRectangle } from '@flighthq/node';
|
|
3
|
+
export function containsDisplayObject(outer, inner) {
|
|
4
|
+
return enclosesRectangle(getNodeWorldBoundsRectangle(outer), getNodeWorldBoundsRectangle(inner));
|
|
5
|
+
}
|
|
6
|
+
export function getDisplayObjectOverlapRectangle(source, other, out) {
|
|
7
|
+
computeRectangleIntersection(out, getNodeWorldBoundsRectangle(source), getNodeWorldBoundsRectangle(other));
|
|
8
|
+
return out;
|
|
9
|
+
}
|
|
10
|
+
export function hitTestDisplayObjectsShape(source, other) {
|
|
11
|
+
const a = getNodeWorldBoundsRectangle(source);
|
|
12
|
+
const b = getNodeWorldBoundsRectangle(other);
|
|
13
|
+
if (!intersectsRectangle(a, b))
|
|
14
|
+
return false;
|
|
15
|
+
const aCenterX = a.x + a.width * 0.5;
|
|
16
|
+
const aCenterY = a.y + a.height * 0.5;
|
|
17
|
+
const bCenterX = b.x + b.width * 0.5;
|
|
18
|
+
const bCenterY = b.y + b.height * 0.5;
|
|
19
|
+
return containsRectanglePointXY(a, bCenterX, bCenterY) || containsRectanglePointXY(b, aCenterX, aCenterY);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=displayObjectOverlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayObjectOverlap.js","sourceRoot":"","sources":["../src/displayObjectOverlap.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAG7D,MAAM,UAAU,qBAAqB,CAAC,KAAoB,EAAE,KAAoB;IAC9E,OAAO,iBAAiB,CAAC,2BAA2B,CAAC,KAAK,CAAC,EAAE,2BAA2B,CAAC,KAAK,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,MAAqB,EACrB,KAAoB,EACpB,GAAc;IAEd,4BAA4B,CAAC,GAAG,EAAE,2BAA2B,CAAC,MAAM,CAAC,EAAE,2BAA2B,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAqB,EAAE,KAAoB;IACpF,MAAM,CAAC,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;IACrC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;IACtC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;IACrC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;IACtC,OAAO,wBAAwB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,wBAAwB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC5G,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DisplayObject, HitTestFunction, Kind, Node } from '@flighthq/types';
|
|
2
|
+
/**
|
|
3
|
+
* Walks the scene graph depth-first in reverse child order (front-to-back) and
|
|
4
|
+
* returns the first node that registers a hit at the given world-space
|
|
5
|
+
* coordinates, or null if nothing was hit.
|
|
6
|
+
**/
|
|
7
|
+
export declare function findGraphHitTarget<Traits extends object>(source: Node<Traits>, x: number, y: number, shapeFlag?: boolean): Node<Traits> | null;
|
|
8
|
+
/**
|
|
9
|
+
* Evaluates the world bounding box of one node to see if it overlaps or
|
|
10
|
+
* intersects the world bounding box of another.
|
|
11
|
+
**/
|
|
12
|
+
export declare function hitTestDisplayObjects(source: DisplayObject, other: DisplayObject): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Tests whether world-space (x, y) falls within the node's local bounds rect,
|
|
15
|
+
* after inverting through the node's world transform.
|
|
16
|
+
**/
|
|
17
|
+
export declare function hitTestGraphLocalBounds<Traits extends object>(source: Node<Traits>, x: number, y: number): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Evaluates the node to see if it or any of its descendants register a hit at
|
|
20
|
+
* the given world-space coordinates.
|
|
21
|
+
*
|
|
22
|
+
* Traverses self first, then children in natural (back-to-front) order — the opposite of
|
|
23
|
+
* `findGraphHitTarget` which tests children in reverse order (front-to-back) to find the
|
|
24
|
+
* deepest topmost hit. This function answers "does anything hit?" rather than "which specific
|
|
25
|
+
* node is hit?", so traversal order does not affect the boolean result.
|
|
26
|
+
*
|
|
27
|
+
* Hit behavior for a given node kind must be registered via `registerHitTest`.
|
|
28
|
+
* Unregistered kinds are skipped for self-hit but children are still tested.
|
|
29
|
+
*
|
|
30
|
+
* @param shapeFlag Passed to the registered hit function; interpretation is kind-specific.
|
|
31
|
+
**/
|
|
32
|
+
export declare function hitTestGraphPoint<Traits extends object>(source: Node<Traits>, x: number, y: number, shapeFlag?: boolean): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Registers an interaction handler for nodes of the given kind.
|
|
35
|
+
* Call this once at startup to opt a node kind into interaction handling.
|
|
36
|
+
**/
|
|
37
|
+
export declare function registerHitTestPoint(kind: Kind, fn: HitTestFunction): void;
|
|
38
|
+
//# sourceMappingURL=hitTests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hitTests.d.ts","sourceRoot":"","sources":["../src/hitTests.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAW,MAAM,iBAAiB,CAAC;AAE3F;;;;IAII;AACJ,wBAAgB,kBAAkB,CAAC,MAAM,SAAS,MAAM,EACtD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EACpB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,GAAE,OAAe,GACzB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAerB;AAED;;;IAGI;AACJ,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAK1F;AAED;;;IAGI;AACJ,wBAAgB,uBAAuB,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAYlH;AAED;;;;;;;;;;;;;IAaI;AACJ,wBAAgB,iBAAiB,CAAC,MAAM,SAAS,MAAM,EACrD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EACpB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,GAAE,OAAe,GACzB,OAAO,CAcT;AAED;;;IAGI;AACJ,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,eAAe,GAAG,IAAI,CAE1E"}
|
package/dist/hitTests.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { containsRectanglePointXY, intersectsRectangle, inverseMatrixTransformPointXY } from '@flighthq/geometry';
|
|
2
|
+
import { getNodeLocalBoundsRectangle, getNodeParent, getNodeRuntime, getNodeWorldBoundsRectangle, getNodeWorldTransformMatrix, } from '@flighthq/node';
|
|
3
|
+
/**
|
|
4
|
+
* Walks the scene graph depth-first in reverse child order (front-to-back) and
|
|
5
|
+
* returns the first node that registers a hit at the given world-space
|
|
6
|
+
* coordinates, or null if nothing was hit.
|
|
7
|
+
**/
|
|
8
|
+
export function findGraphHitTarget(source, x, y, shapeFlag = false) {
|
|
9
|
+
if (!source.enabled)
|
|
10
|
+
return null;
|
|
11
|
+
const children = getNodeRuntime(source).children;
|
|
12
|
+
if (children !== null) {
|
|
13
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
14
|
+
const hit = findGraphHitTarget(children[i], x, y, shapeFlag);
|
|
15
|
+
if (hit !== null)
|
|
16
|
+
return hit;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const hitTestSelf = hitTestPointRegistry.get(source.kind);
|
|
20
|
+
if (hitTestSelf?.(source, x, y, shapeFlag))
|
|
21
|
+
return source;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Evaluates the world bounding box of one node to see if it overlaps or
|
|
26
|
+
* intersects the world bounding box of another.
|
|
27
|
+
**/
|
|
28
|
+
export function hitTestDisplayObjects(source, other) {
|
|
29
|
+
if (getNodeParent(source) !== null && getNodeParent(other) !== null) {
|
|
30
|
+
return intersectsRectangle(getNodeWorldBoundsRectangle(source), getNodeWorldBoundsRectangle(other));
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Tests whether world-space (x, y) falls within the node's local bounds rect,
|
|
36
|
+
* after inverting through the node's world transform.
|
|
37
|
+
**/
|
|
38
|
+
export function hitTestGraphLocalBounds(source, x, y) {
|
|
39
|
+
inverseMatrixTransformPointXY(hitTestLocalBoundsRectanglePoint, getNodeWorldTransformMatrix(source), x, y);
|
|
40
|
+
return containsRectanglePointXY(getNodeLocalBoundsRectangle(source), hitTestLocalBoundsRectanglePoint.x, hitTestLocalBoundsRectanglePoint.y);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Evaluates the node to see if it or any of its descendants register a hit at
|
|
44
|
+
* the given world-space coordinates.
|
|
45
|
+
*
|
|
46
|
+
* Traverses self first, then children in natural (back-to-front) order — the opposite of
|
|
47
|
+
* `findGraphHitTarget` which tests children in reverse order (front-to-back) to find the
|
|
48
|
+
* deepest topmost hit. This function answers "does anything hit?" rather than "which specific
|
|
49
|
+
* node is hit?", so traversal order does not affect the boolean result.
|
|
50
|
+
*
|
|
51
|
+
* Hit behavior for a given node kind must be registered via `registerHitTest`.
|
|
52
|
+
* Unregistered kinds are skipped for self-hit but children are still tested.
|
|
53
|
+
*
|
|
54
|
+
* @param shapeFlag Passed to the registered hit function; interpretation is kind-specific.
|
|
55
|
+
**/
|
|
56
|
+
export function hitTestGraphPoint(source, x, y, shapeFlag = false) {
|
|
57
|
+
if (!source.enabled)
|
|
58
|
+
return false;
|
|
59
|
+
const hitTestSelf = hitTestPointRegistry.get(source.kind);
|
|
60
|
+
if (hitTestSelf?.(source, x, y, shapeFlag))
|
|
61
|
+
return true;
|
|
62
|
+
const children = getNodeRuntime(source).children;
|
|
63
|
+
if (children !== null) {
|
|
64
|
+
for (const child of children) {
|
|
65
|
+
if (hitTestGraphPoint(child, x, y, shapeFlag))
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Registers an interaction handler for nodes of the given kind.
|
|
73
|
+
* Call this once at startup to opt a node kind into interaction handling.
|
|
74
|
+
**/
|
|
75
|
+
export function registerHitTestPoint(kind, fn) {
|
|
76
|
+
hitTestPointRegistry.set(kind, fn);
|
|
77
|
+
}
|
|
78
|
+
const hitTestLocalBoundsRectanglePoint = { x: 0, y: 0 };
|
|
79
|
+
const hitTestPointRegistry = new Map();
|
|
80
|
+
//# sourceMappingURL=hitTests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hitTests.js","sourceRoot":"","sources":["../src/hitTests.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './displayHitTests';
|
|
2
|
+
export * from './displayObjectOverlap';
|
|
3
|
+
export * from './hitTests';
|
|
4
|
+
export * from './interactionManager';
|
|
5
|
+
export * from './registerDefaultHitTestPoints';
|
|
6
|
+
export * from './spatialQuery';
|
|
7
|
+
export * from './spriteHitTests';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './displayHitTests';
|
|
2
|
+
export * from './displayObjectOverlap';
|
|
3
|
+
export * from './hitTests';
|
|
4
|
+
export * from './interactionManager';
|
|
5
|
+
export * from './registerDefaultHitTestPoints';
|
|
6
|
+
export * from './spatialQuery';
|
|
7
|
+
export * from './spriteHitTests';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { InteractionInputSource, InteractionManager, InteractionManagerOptions, InteractionPointerOptions, InteractionSignalName, InteractionSignals, KeyboardEventData, NodeAny, PointerEventData, SignalConnectOptions } from '@flighthq/types';
|
|
2
|
+
export declare function captureInteractionPointer<N extends NodeAny>(manager: InteractionManager<N>, pointerId: number, target: N): void;
|
|
3
|
+
/**
|
|
4
|
+
* Wires an input source's pointer/keyboard signals into an interaction manager, forwarding each
|
|
5
|
+
* event to the matching dispatch function.
|
|
6
|
+
*
|
|
7
|
+
* Coordinate space: the pointer coordinates on an `InputPointerData` from the DOM input backend are
|
|
8
|
+
* CSS pixels (see `attachPointerInput`), while hit testing runs in the scene's device-pixel space.
|
|
9
|
+
* `coordScale` bridges the two and is multiplied into every forwarded pointer coordinate; pass the
|
|
10
|
+
* canvas's backing-store scale — typically `window.devicePixelRatio`, matching how the renderer
|
|
11
|
+
* sizes its drawing buffer. The default `1` is correct only when the backing store is unscaled.
|
|
12
|
+
*
|
|
13
|
+
* This scales but does not translate: it assumes the pointer coordinates are already canvas-local
|
|
14
|
+
* (origin at the canvas's top-left). A backend delivering viewport-relative coordinates for a canvas
|
|
15
|
+
* not at the viewport origin must subtract the canvas bounding-rect offset per event before this
|
|
16
|
+
* point, since that offset moves with scroll and layout.
|
|
17
|
+
*/
|
|
18
|
+
export declare function connectInputToInteraction<N extends NodeAny>(input: InteractionInputSource, manager: InteractionManager<N>, coordScale?: number): () => void;
|
|
19
|
+
export declare function connectInteractionSignal<N extends NodeAny, Name extends InteractionSignalName>(manager: InteractionManager<N>, target: N, name: Name, slot: InteractionSignalSlot<Name>, options?: Readonly<SignalConnectOptions>): void;
|
|
20
|
+
export declare function createInteractionManager<N extends NodeAny>(root: N, options?: Readonly<InteractionManagerOptions>): InteractionManager<N>;
|
|
21
|
+
export declare function createInteractionSignals(): InteractionSignals;
|
|
22
|
+
export declare function disconnectInteractionSignal<N extends NodeAny, Name extends InteractionSignalName>(manager: InteractionManager<N>, target: N, name: Name, slot: InteractionSignalSlot<Name>): void;
|
|
23
|
+
export declare function dispatchInteractionContextMenu<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, button?: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
24
|
+
export declare function dispatchInteractionKeyDown<N extends NodeAny>(manager: InteractionManager<N>, key: string, keyCode?: number, modifiers?: Readonly<Partial<KeyboardEventData>>): void;
|
|
25
|
+
export declare function dispatchInteractionKeyUp<N extends NodeAny>(manager: InteractionManager<N>, key: string, keyCode?: number, modifiers?: Readonly<Partial<KeyboardEventData>>): void;
|
|
26
|
+
export declare function dispatchInteractionPointerCancel<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
27
|
+
export declare function dispatchInteractionPointerDown<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, button?: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
28
|
+
export declare function dispatchInteractionPointerMove<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, button?: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
29
|
+
export declare function dispatchInteractionPointerUp<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, button?: number, time?: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
30
|
+
export declare function dispatchInteractionWheel<N extends NodeAny>(manager: InteractionManager<N>, x: number, y: number, deltaX?: number, deltaY?: number, options?: Readonly<InteractionPointerOptions>): void;
|
|
31
|
+
export declare function enableInteractionSignals<N extends NodeAny>(source: N): InteractionSignals;
|
|
32
|
+
export declare function getInteractionSignals<N extends NodeAny>(source: N): InteractionSignals | null;
|
|
33
|
+
export declare function releaseInteractionPointer<N extends NodeAny>(manager: InteractionManager<N>, pointerId: number): void;
|
|
34
|
+
type KeyboardSignalName = 'onKeyDown' | 'onKeyUp';
|
|
35
|
+
type InteractionSignalPayload<Name extends InteractionSignalName> = Name extends KeyboardSignalName ? Readonly<KeyboardEventData> : Readonly<PointerEventData>;
|
|
36
|
+
type InteractionSignalSlot<Name extends InteractionSignalName> = (value: InteractionSignalPayload<Name>) => void;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=interactionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactionManager.d.ts","sourceRoot":"","sources":["../src/interactionManager.ts"],"names":[],"mappings":"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"}
|