@flighthq/interaction 0.3.0-next.906.07cea63 → 0.3.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/contract.d.ts +1 -1
- package/dist/contract.js +1 -1
- package/dist/displayHitTests.d.ts +0 -3
- package/dist/displayHitTests.d.ts.map +1 -1
- package/dist/displayHitTests.js +0 -9
- package/dist/displayHitTests.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/registerDefaultHitTests.d.ts.map +1 -1
- package/dist/registerDefaultHitTests.js +3 -5
- package/dist/registerDefaultHitTests.js.map +1 -1
- package/dist/registerShapeHitTest.d.ts +3 -3
- package/dist/registerShapeHitTest.d.ts.map +1 -1
- package/dist/registerShapeHitTest.js +5 -4
- package/dist/registerShapeHitTest.js.map +1 -1
- package/dist/{registerBitmapHitTest.d.ts → registerSpriteHitTest.d.ts} +4 -4
- package/dist/registerSpriteHitTest.d.ts.map +1 -0
- package/dist/registerSpriteHitTest.js +62 -0
- package/dist/registerSpriteHitTest.js.map +1 -0
- package/package.json +17 -14
- package/src/displayHitTests.test.ts +0 -39
- package/src/registerDefaultHitTests.test.ts +8 -3
- package/src/registerShapeHitTest.test.ts +39 -2
- package/src/{registerBitmapHitTest.test.ts → registerSpriteHitTest.test.ts} +6 -6
- package/src/spriteHitTests.test.ts +3 -1
- package/dist/registerBitmapHitTest.d.ts.map +0 -1
- package/dist/registerBitmapHitTest.js +0 -55
- package/dist/registerBitmapHitTest.js.map +0 -1
package/dist/contract.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export * from './hitTests';
|
|
|
7
7
|
export * from './interactionManager';
|
|
8
8
|
export * from './interactionSpatialIndex';
|
|
9
9
|
export * from './nodeInteractionState';
|
|
10
|
-
export * from './
|
|
10
|
+
export * from './registerSpriteHitTest';
|
|
11
11
|
export * from './registerShapeHitTest';
|
|
12
12
|
export * from './registerTextHitTest';
|
|
13
13
|
export * from './registerDefaultHitTests';
|
package/dist/contract.js
CHANGED
|
@@ -7,7 +7,7 @@ export * from './hitTests';
|
|
|
7
7
|
export * from './interactionManager';
|
|
8
8
|
export * from './interactionSpatialIndex';
|
|
9
9
|
export * from './nodeInteractionState';
|
|
10
|
-
export * from './
|
|
10
|
+
export * from './registerSpriteHitTest';
|
|
11
11
|
export * from './registerShapeHitTest';
|
|
12
12
|
export * from './registerTextHitTest';
|
|
13
13
|
export * from './registerDefaultHitTests';
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import type { NodeAny } from '@flighthq/types/contract';
|
|
2
|
-
export declare function defaultBitmapHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
3
2
|
export declare function defaultHtmlViewHitTestHandler(_source: NodeAny, _x: number, _y: number): boolean;
|
|
4
3
|
export declare function defaultMovieClipHitTestHandler(_source: NodeAny, _x: number, _y: number): boolean;
|
|
5
4
|
export declare function defaultNode2DHitTestHandler(_source: NodeAny, _x: number, _y: number): boolean;
|
|
6
|
-
export declare function defaultRenderTargetNode2DHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
7
5
|
export declare function defaultRichTextHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
8
6
|
export declare function defaultShapeHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
9
7
|
export declare function defaultTextHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
10
8
|
export declare function defaultTextInputHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
11
|
-
export declare function defaultVideoHitTestHandler(source: NodeAny, x: number, y: number): boolean;
|
|
12
9
|
//# sourceMappingURL=displayHitTests.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displayHitTests.d.ts","sourceRoot":"","sources":["../src/displayHitTests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAIxD,wBAAgB,
|
|
1
|
+
{"version":3,"file":"displayHitTests.d.ts","sourceRoot":"","sources":["../src/displayHitTests.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAIxD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAG/F;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAGhG;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAE7F;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5F;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAIzF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAExF;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE7F"}
|
package/dist/displayHitTests.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { hitTestGraphLocalBounds } from './hitTests';
|
|
2
|
-
export function defaultBitmapHitTestHandler(source, x, y) {
|
|
3
|
-
return hitTestGraphLocalBounds(source, x, y);
|
|
4
|
-
}
|
|
5
2
|
export function defaultHtmlViewHitTestHandler(_source, _x, _y) {
|
|
6
3
|
// HtmlView elements handle pointer events through the browser — not the canvas interaction system.
|
|
7
4
|
return false;
|
|
@@ -13,9 +10,6 @@ export function defaultMovieClipHitTestHandler(_source, _x, _y) {
|
|
|
13
10
|
export function defaultNode2DHitTestHandler(_source, _x, _y) {
|
|
14
11
|
return false;
|
|
15
12
|
}
|
|
16
|
-
export function defaultRenderTargetNode2DHitTestHandler(source, x, y) {
|
|
17
|
-
return hitTestGraphLocalBounds(source, x, y);
|
|
18
|
-
}
|
|
19
13
|
export function defaultRichTextHitTestHandler(source, x, y) {
|
|
20
14
|
return hitTestGraphLocalBounds(source, x, y);
|
|
21
15
|
}
|
|
@@ -30,7 +24,4 @@ export function defaultTextHitTestHandler(source, x, y) {
|
|
|
30
24
|
export function defaultTextInputHitTestHandler(source, x, y) {
|
|
31
25
|
return hitTestGraphLocalBounds(source, x, y);
|
|
32
26
|
}
|
|
33
|
-
export function defaultVideoHitTestHandler(source, x, y) {
|
|
34
|
-
return hitTestGraphLocalBounds(source, x, y);
|
|
35
|
-
}
|
|
36
27
|
//# sourceMappingURL=displayHitTests.js.map
|
|
@@ -1 +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,
|
|
1
|
+
{"version":3,"file":"displayHitTests.js","sourceRoot":"","sources":["../src/displayHitTests.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,UAAU,6BAA6B,CAAC,OAAgB,EAAE,EAAU,EAAE,EAAU;IACpF,mGAAmG;IACnG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,OAAgB,EAAE,EAAU,EAAE,EAAU;IACrF,uFAAuF;IACvF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,OAAgB,EAAE,EAAU,EAAE,EAAU;IAClF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS;IACjF,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS;IAC9E,wFAAwF;IACxF,wEAAwE;IACxE,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS;IAC7E,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS;IAClF,OAAO,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { captureInteractionPointer, clearFocus, connectFocusNavigation, connectInputToInteraction, connectInteractionSignal, containsNode2D, createFocusManager, createInteractionManager, createNodeInteractionState, createWebCursorBackend, describeGraphHit, disableInteractionGuards, disconnectInteractionSignal, dispatchInteractionContextMenu, dispatchInteractionKeyDown, dispatchInteractionKeyUp, dispatchInteractionPointerCancel, dispatchInteractionPointerDown, dispatchInteractionPointerMove, dispatchInteractionPointerUp, dispatchInteractionWheel, enableInteractionGuards, enableInteractionSignals, enableNodeInteractionState, explainInteractionHitEligibility, findGraphHitTarget, findGraphHitTargetPrecise, findGraphHitTargets, findGraphHitTargetsPrecise, findSpatialInteractionTarget, focusNextNode, focusNodeInDirection, focusPreviousNode, getFocusOrder, getFocusedNode, getInteractionSignals, getNode2DOverlapRectangle, getNodeCursor, getNodeHitArea, getNodeInteractionState, getNodeTabIndex, hitTestAreaQuery, hitTestAreaQueryCircle, hitTestGraphLocalBounds, hitTestGraphPoint, hitTestGraphPointPrecise, hitTestNode2Ds, hitTestNode2DsShape, hitTestNodeRegion, isNodeFocusable, isNodeFocused, isNodeHitTestEnabled, refreshInteractionSpatialIndex,
|
|
1
|
+
export { captureInteractionPointer, clearFocus, connectFocusNavigation, connectInputToInteraction, connectInteractionSignal, containsNode2D, createFocusManager, createInteractionManager, createNodeInteractionState, createWebCursorBackend, describeGraphHit, disableInteractionGuards, disconnectInteractionSignal, dispatchInteractionContextMenu, dispatchInteractionKeyDown, dispatchInteractionKeyUp, dispatchInteractionPointerCancel, dispatchInteractionPointerDown, dispatchInteractionPointerMove, dispatchInteractionPointerUp, dispatchInteractionWheel, enableInteractionGuards, enableInteractionSignals, enableNodeInteractionState, explainInteractionHitEligibility, findGraphHitTarget, findGraphHitTargetPrecise, findGraphHitTargets, findGraphHitTargetsPrecise, findSpatialInteractionTarget, focusNextNode, focusNodeInDirection, focusPreviousNode, getFocusOrder, getFocusedNode, getInteractionSignals, getNode2DOverlapRectangle, getNodeCursor, getNodeHitArea, getNodeInteractionState, getNodeTabIndex, hitTestAreaQuery, hitTestAreaQueryCircle, hitTestGraphLocalBounds, hitTestGraphPoint, hitTestGraphPointPrecise, hitTestNode2Ds, hitTestNode2DsShape, hitTestNodeRegion, isNodeFocusable, isNodeFocused, isNodeHitTestEnabled, refreshInteractionSpatialIndex, registerSpriteHitTest, registerDefaultHitTests, registerHitTest, registerHitTestPrecise, registerShapeHitTest, registerTextHitTest, releaseInteractionPointer, setFocusedNode, setInteractionConnectGuard, setNodeCursor, setNodeFocusable, setNodeHitArea, setNodeHitTestEnabled, setNodeTabIndex, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { captureInteractionPointer, clearFocus, connectFocusNavigation, connectInputToInteraction, connectInteractionSignal, containsNode2D, createFocusManager, createInteractionManager, createNodeInteractionState, createWebCursorBackend, describeGraphHit, disableInteractionGuards, disconnectInteractionSignal, dispatchInteractionContextMenu, dispatchInteractionKeyDown, dispatchInteractionKeyUp, dispatchInteractionPointerCancel, dispatchInteractionPointerDown, dispatchInteractionPointerMove, dispatchInteractionPointerUp, dispatchInteractionWheel, enableInteractionGuards, enableInteractionSignals, enableNodeInteractionState, explainInteractionHitEligibility, findGraphHitTarget, findGraphHitTargetPrecise, findGraphHitTargets, findGraphHitTargetsPrecise, findSpatialInteractionTarget, focusNextNode, focusNodeInDirection, focusPreviousNode, getFocusOrder, getFocusedNode, getInteractionSignals, getNode2DOverlapRectangle, getNodeCursor, getNodeHitArea, getNodeInteractionState, getNodeTabIndex, hitTestAreaQuery, hitTestAreaQueryCircle, hitTestGraphLocalBounds, hitTestGraphPoint, hitTestGraphPointPrecise, hitTestNode2Ds, hitTestNode2DsShape, hitTestNodeRegion, isNodeFocusable, isNodeFocused, isNodeHitTestEnabled, refreshInteractionSpatialIndex,
|
|
1
|
+
export { captureInteractionPointer, clearFocus, connectFocusNavigation, connectInputToInteraction, connectInteractionSignal, containsNode2D, createFocusManager, createInteractionManager, createNodeInteractionState, createWebCursorBackend, describeGraphHit, disableInteractionGuards, disconnectInteractionSignal, dispatchInteractionContextMenu, dispatchInteractionKeyDown, dispatchInteractionKeyUp, dispatchInteractionPointerCancel, dispatchInteractionPointerDown, dispatchInteractionPointerMove, dispatchInteractionPointerUp, dispatchInteractionWheel, enableInteractionGuards, enableInteractionSignals, enableNodeInteractionState, explainInteractionHitEligibility, findGraphHitTarget, findGraphHitTargetPrecise, findGraphHitTargets, findGraphHitTargetsPrecise, findSpatialInteractionTarget, focusNextNode, focusNodeInDirection, focusPreviousNode, getFocusOrder, getFocusedNode, getInteractionSignals, getNode2DOverlapRectangle, getNodeCursor, getNodeHitArea, getNodeInteractionState, getNodeTabIndex, hitTestAreaQuery, hitTestAreaQueryCircle, hitTestGraphLocalBounds, hitTestGraphPoint, hitTestGraphPointPrecise, hitTestNode2Ds, hitTestNode2DsShape, hitTestNodeRegion, isNodeFocusable, isNodeFocused, isNodeHitTestEnabled, refreshInteractionSpatialIndex, registerSpriteHitTest, registerDefaultHitTests, registerHitTest, registerHitTestPrecise, registerShapeHitTest, registerTextHitTest, releaseInteractionPointer, setFocusedNode, setInteractionConnectGuard, setNodeCursor, setNodeFocusable, setNodeHitArea, setNodeHitTestEnabled, setNodeTabIndex, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerDefaultHitTests.d.ts","sourceRoot":"","sources":["../src/registerDefaultHitTests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registerDefaultHitTests.d.ts","sourceRoot":"","sources":["../src/registerDefaultHitTests.ts"],"names":[],"mappings":"AA6BA,wBAAgB,uBAAuB,IAAI,IAAI,CAY9C"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DisplayObjectKind, HtmlViewKind, MorphShapeKind, MovieClipKind, QuadBatchKind, RichTextKind, Scale9ShapeKind, ShapeKind, SpriteKind, TextLabelKind, TilemapKind, } from '@flighthq/types/contract';
|
|
2
|
+
import { defaultNode2DHitTestHandler, defaultHtmlViewHitTestHandler, defaultMovieClipHitTestHandler, defaultRichTextHitTestHandler, defaultShapeHitTestHandler, defaultTextHitTestHandler, } from './displayHitTests';
|
|
3
3
|
import { registerHitTest } from './hitTests';
|
|
4
4
|
import { defaultQuadBatchHitTestHandler, defaultSpriteHitTestHandler, defaultTilemapHitTestHandler, } from './spriteHitTests';
|
|
5
5
|
export function registerDefaultHitTests() {
|
|
6
|
-
registerHitTest(BitmapKind, defaultBitmapHitTestHandler);
|
|
7
6
|
registerHitTest(DisplayObjectKind, defaultNode2DHitTestHandler);
|
|
8
7
|
registerHitTest(HtmlViewKind, defaultHtmlViewHitTestHandler);
|
|
9
8
|
registerHitTest(MovieClipKind, defaultMovieClipHitTestHandler);
|
|
9
|
+
registerHitTest(MorphShapeKind, defaultShapeHitTestHandler);
|
|
10
10
|
registerHitTest(QuadBatchKind, defaultQuadBatchHitTestHandler);
|
|
11
|
-
registerHitTest(RenderTargetNode2DKind, defaultRenderTargetNode2DHitTestHandler);
|
|
12
11
|
registerHitTest(RichTextKind, defaultRichTextHitTestHandler);
|
|
13
12
|
registerHitTest(Scale9ShapeKind, defaultShapeHitTestHandler);
|
|
14
13
|
registerHitTest(ShapeKind, defaultShapeHitTestHandler);
|
|
15
14
|
registerHitTest(SpriteKind, defaultSpriteHitTestHandler);
|
|
16
15
|
registerHitTest(TextLabelKind, defaultTextHitTestHandler);
|
|
17
16
|
registerHitTest(TilemapKind, defaultTilemapHitTestHandler);
|
|
18
|
-
registerHitTest(VideoKind, defaultVideoHitTestHandler);
|
|
19
17
|
}
|
|
20
18
|
//# sourceMappingURL=registerDefaultHitTests.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerDefaultHitTests.js","sourceRoot":"","sources":["../src/registerDefaultHitTests.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"registerDefaultHitTests.js","sourceRoot":"","sources":["../src/registerDefaultHitTests.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,2BAA2B,EAC3B,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,uBAAuB;IACrC,eAAe,CAAC,iBAAiB,EAAE,2BAA2B,CAAC,CAAC;IAChE,eAAe,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;IAC7D,eAAe,CAAC,aAAa,EAAE,8BAA8B,CAAC,CAAC;IAC/D,eAAe,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;IAC5D,eAAe,CAAC,aAAa,EAAE,8BAA8B,CAAC,CAAC;IAC/D,eAAe,CAAC,YAAY,EAAE,6BAA6B,CAAC,CAAC;IAC7D,eAAe,CAAC,eAAe,EAAE,0BAA0B,CAAC,CAAC;IAC7D,eAAe,CAAC,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACvD,eAAe,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;IACzD,eAAe,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;IAC1D,eAAe,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Opt-in exact hit provider for shapes: the `*Precise` queries then hit a Shape/Scale9Shape
|
|
3
|
-
* the point falls inside actual filled geometry (winding), not the bounding box. The coarse
|
|
4
|
-
* `registerDefaultHitTests` are unaffected.
|
|
2
|
+
* Opt-in exact hit provider for shapes: the `*Precise` queries then hit a Shape/MorphShape/Scale9Shape
|
|
3
|
+
* only where the point falls inside actual filled geometry (winding), not the bounding box. The coarse
|
|
4
|
+
* queries and `registerDefaultHitTests` are unaffected.
|
|
5
5
|
*
|
|
6
6
|
* Importing this module is the opt-in — it pulls `@flighthq/shape` + `@flighthq/path`, so the base
|
|
7
7
|
* interaction bundle stays free of them (tree-shaken unless referenced).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerShapeHitTest.d.ts","sourceRoot":"","sources":["../src/registerShapeHitTest.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"registerShapeHitTest.d.ts","sourceRoot":"","sources":["../src/registerShapeHitTest.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C"}
|
|
@@ -2,17 +2,18 @@ import { inverseMatrixTransformPointXY } from '@flighthq/geometry/contract';
|
|
|
2
2
|
import { getNodeWorldMatrix } from '@flighthq/node/contract';
|
|
3
3
|
import { containsPathPoint } from '@flighthq/path/contract';
|
|
4
4
|
import { getShapeFillRegions } from '@flighthq/shape/contract';
|
|
5
|
-
import { Scale9ShapeKind, ShapeKind } from '@flighthq/types/contract';
|
|
5
|
+
import { MorphShapeKind, Scale9ShapeKind, ShapeKind } from '@flighthq/types/contract';
|
|
6
6
|
import { registerHitTestPrecise } from './hitTests';
|
|
7
7
|
/**
|
|
8
|
-
* Opt-in exact hit provider for shapes: the `*Precise` queries then hit a Shape/Scale9Shape
|
|
9
|
-
* the point falls inside actual filled geometry (winding), not the bounding box. The coarse
|
|
10
|
-
* `registerDefaultHitTests` are unaffected.
|
|
8
|
+
* Opt-in exact hit provider for shapes: the `*Precise` queries then hit a Shape/MorphShape/Scale9Shape
|
|
9
|
+
* only where the point falls inside actual filled geometry (winding), not the bounding box. The coarse
|
|
10
|
+
* queries and `registerDefaultHitTests` are unaffected.
|
|
11
11
|
*
|
|
12
12
|
* Importing this module is the opt-in — it pulls `@flighthq/shape` + `@flighthq/path`, so the base
|
|
13
13
|
* interaction bundle stays free of them (tree-shaken unless referenced).
|
|
14
14
|
*/
|
|
15
15
|
export function registerShapeHitTest() {
|
|
16
|
+
registerHitTestPrecise(MorphShapeKind, hitTestShapeFill);
|
|
16
17
|
registerHitTestPrecise(ShapeKind, hitTestShapeFill);
|
|
17
18
|
registerHitTestPrecise(Scale9ShapeKind, hitTestShapeFill);
|
|
18
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerShapeHitTest.js","sourceRoot":"","sources":["../src/registerShapeHitTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"registerShapeHitTest.js","sourceRoot":"","sources":["../src/registerShapeHitTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAEtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB;IAClC,sBAAsB,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACzD,sBAAsB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACpD,sBAAsB,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;AAC5D,CAAC;AAED,gGAAgG;AAChG,SAAS,gBAAgB,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS;IAC7D,MAAM,OAAO,GAAG,mBAAmB,CAAE,MAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC,CAAC;IAEhC,6BAA6B,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,MAAgB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAClG,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC;AAED,MAAM,sBAAsB,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Opt-in exact hit provider for bitmaps: the `*Precise` queries then hit a
|
|
2
|
+
* Opt-in exact hit provider for bitmaps: the `*Precise` queries then hit a Sprite only where its pixel
|
|
3
3
|
* alpha meets `alphaThreshold` (0..255). Within the node's bounds but where the pixels aren't readable
|
|
4
4
|
* (no image, a GPU-only texture, or a headless environment that can't rasterize), it falls back to a
|
|
5
5
|
* bounds hit rather than throwing — best-available precision for that instance.
|
|
6
6
|
*
|
|
7
|
-
* Importing this module is the opt-in — it pulls `@flighthq/
|
|
7
|
+
* Importing this module is the opt-in — it pulls `@flighthq/bitmap`, so the base interaction bundle
|
|
8
8
|
* stays free of it (tree-shaken unless referenced).
|
|
9
9
|
*/
|
|
10
|
-
export declare function
|
|
11
|
-
//# sourceMappingURL=
|
|
10
|
+
export declare function registerSpriteHitTest(alphaThreshold?: number): void;
|
|
11
|
+
//# sourceMappingURL=registerSpriteHitTest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerSpriteHitTest.d.ts","sourceRoot":"","sources":["../src/registerSpriteHitTest.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,GAAE,MAAU,GAAG,IAAI,CAEtE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { captureBitmapFromImageResource, getBitmapPixelChannel } from '@flighthq/bitmap/contract';
|
|
2
|
+
import { inverseMatrixTransformPointXY } from '@flighthq/geometry/contract';
|
|
3
|
+
import { getNodeWorldMatrix } from '@flighthq/node/contract';
|
|
4
|
+
import { BitmapTextureSourceKind, ImageChannel, ImageTextureSourceKind, SpriteKind } from '@flighthq/types/contract';
|
|
5
|
+
import { hitTestGraphLocalBounds, registerHitTestPrecise } from './hitTests';
|
|
6
|
+
/**
|
|
7
|
+
* Opt-in exact hit provider for bitmaps: the `*Precise` queries then hit a Sprite only where its pixel
|
|
8
|
+
* alpha meets `alphaThreshold` (0..255). Within the node's bounds but where the pixels aren't readable
|
|
9
|
+
* (no image, a GPU-only texture, or a headless environment that can't rasterize), it falls back to a
|
|
10
|
+
* bounds hit rather than throwing — best-available precision for that instance.
|
|
11
|
+
*
|
|
12
|
+
* Importing this module is the opt-in — it pulls `@flighthq/bitmap`, so the base interaction bundle
|
|
13
|
+
* stays free of it (tree-shaken unless referenced).
|
|
14
|
+
*/
|
|
15
|
+
export function registerSpriteHitTest(alphaThreshold = 1) {
|
|
16
|
+
registerHitTestPrecise(SpriteKind, (source, x, y) => hitTestSpriteAlpha(source, x, y, alphaThreshold));
|
|
17
|
+
}
|
|
18
|
+
// Returns 0 on a hit (opaque pixel, or bounds fallback when pixels are unreadable), -1 on a miss.
|
|
19
|
+
function hitTestSpriteAlpha(source, x, y, alphaThreshold) {
|
|
20
|
+
if (!hitTestGraphLocalBounds(source, x, y))
|
|
21
|
+
return -1;
|
|
22
|
+
const sprite = source;
|
|
23
|
+
const texture = sprite.data.texture;
|
|
24
|
+
if (texture === null || texture.dimension !== '2d')
|
|
25
|
+
return 0;
|
|
26
|
+
const image = texture.source;
|
|
27
|
+
if (image === null)
|
|
28
|
+
return 0;
|
|
29
|
+
const bitmap = bitmapForImage(image);
|
|
30
|
+
if (bitmap === null)
|
|
31
|
+
return 0;
|
|
32
|
+
inverseMatrixTransformPointXY(bitmapAlphaLocalPoint, getNodeWorldMatrix(source), x, y);
|
|
33
|
+
const px = Math.floor(texture.uvOffset.x * image.width + bitmapAlphaLocalPoint.x);
|
|
34
|
+
const py = Math.floor(texture.uvOffset.y * image.height + bitmapAlphaLocalPoint.y);
|
|
35
|
+
if (px < 0 || py < 0 || px >= bitmap.width || py >= bitmap.height)
|
|
36
|
+
return -1;
|
|
37
|
+
return getBitmapPixelChannel(bitmap, px, py, ImageChannel.Alpha) >= alphaThreshold ? 0 : -1;
|
|
38
|
+
}
|
|
39
|
+
function bitmapForImage(image) {
|
|
40
|
+
if (image.kind === BitmapTextureSourceKind)
|
|
41
|
+
return image;
|
|
42
|
+
if (image.kind !== ImageTextureSourceKind)
|
|
43
|
+
return null;
|
|
44
|
+
const resource = image;
|
|
45
|
+
const cached = bitmapCache.get(resource);
|
|
46
|
+
if (cached !== undefined)
|
|
47
|
+
return cached;
|
|
48
|
+
let bitmap = null;
|
|
49
|
+
try {
|
|
50
|
+
bitmap = captureBitmapFromImageResource(resource);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
bitmap = null;
|
|
54
|
+
}
|
|
55
|
+
// Cache only successes so an image that is not yet readable is retried later.
|
|
56
|
+
if (bitmap !== null)
|
|
57
|
+
bitmapCache.set(resource, bitmap);
|
|
58
|
+
return bitmap;
|
|
59
|
+
}
|
|
60
|
+
const bitmapAlphaLocalPoint = { x: 0, y: 0 };
|
|
61
|
+
const bitmapCache = new WeakMap();
|
|
62
|
+
//# sourceMappingURL=registerSpriteHitTest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerSpriteHitTest.js","sourceRoot":"","sources":["../src/registerSpriteHitTest.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/interaction",
|
|
3
|
-
"version": "0.3.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"author": "Joshua Granick and other contributors",
|
|
5
|
+
"license": "MIT",
|
|
4
6
|
"repository": {
|
|
5
7
|
"type": "git",
|
|
6
8
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,21 +38,22 @@
|
|
|
36
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@flighthq/geometry": "0.3.0
|
|
40
|
-
"@flighthq/node": "0.3.0
|
|
41
|
-
"@flighthq/scene2d": "0.3.0
|
|
42
|
-
"@flighthq/log": "0.3.0
|
|
43
|
-
"@flighthq/path": "0.3.0
|
|
44
|
-
"@flighthq/shape": "0.3.0
|
|
45
|
-
"@flighthq/spatial": "0.3.0
|
|
46
|
-
"@flighthq/signals": "0.3.0
|
|
47
|
-
"@flighthq/
|
|
48
|
-
"@flighthq/text": "0.3.0
|
|
49
|
-
"@flighthq/textlayout": "0.3.0
|
|
50
|
-
"@flighthq/types": "0.3.0
|
|
41
|
+
"@flighthq/geometry": "0.3.0",
|
|
42
|
+
"@flighthq/node": "0.3.0",
|
|
43
|
+
"@flighthq/scene2d": "0.3.0",
|
|
44
|
+
"@flighthq/log": "0.3.0",
|
|
45
|
+
"@flighthq/path": "0.3.0",
|
|
46
|
+
"@flighthq/shape": "0.3.0",
|
|
47
|
+
"@flighthq/spatial": "0.3.0",
|
|
48
|
+
"@flighthq/signals": "0.3.0",
|
|
49
|
+
"@flighthq/bitmap": "0.3.0",
|
|
50
|
+
"@flighthq/text": "0.3.0",
|
|
51
|
+
"@flighthq/textlayout": "0.3.0",
|
|
52
|
+
"@flighthq/types": "0.3.0"
|
|
51
53
|
},
|
|
52
54
|
"devDependencies": {
|
|
53
|
-
"@flighthq/
|
|
55
|
+
"@flighthq/quadbatch": "*",
|
|
56
|
+
"@flighthq/tilemap": "*",
|
|
54
57
|
"typescript": "^5.3.0"
|
|
55
58
|
},
|
|
56
59
|
"description": "Hit testing: point-in-node tests and object overlap detection",
|
|
@@ -3,16 +3,13 @@ import { getNodeLocalBoundsRectangle } from '@flighthq/node/contract';
|
|
|
3
3
|
import { createDisplayObject } from '@flighthq/scene2d/contract';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
defaultBitmapHitTestHandler,
|
|
7
6
|
defaultNode2DHitTestHandler,
|
|
8
7
|
defaultHtmlViewHitTestHandler,
|
|
9
8
|
defaultMovieClipHitTestHandler,
|
|
10
|
-
defaultRenderTargetNode2DHitTestHandler,
|
|
11
9
|
defaultRichTextHitTestHandler,
|
|
12
10
|
defaultShapeHitTestHandler,
|
|
13
11
|
defaultTextHitTestHandler,
|
|
14
12
|
defaultTextInputHitTestHandler,
|
|
15
|
-
defaultVideoHitTestHandler,
|
|
16
13
|
} from './displayHitTests';
|
|
17
14
|
|
|
18
15
|
function makeNode2D() {
|
|
@@ -21,18 +18,6 @@ function makeNode2D() {
|
|
|
21
18
|
return obj;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
describe('defaultBitmapHitTestHandler', () => {
|
|
25
|
-
it('returns true when point is within local bounds', () => {
|
|
26
|
-
const obj = makeNode2D();
|
|
27
|
-
expect(defaultBitmapHitTestHandler(obj, 50, 50)).toBe(true);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('returns false when point is outside local bounds', () => {
|
|
31
|
-
const obj = makeNode2D();
|
|
32
|
-
expect(defaultBitmapHitTestHandler(obj, 200, 200)).toBe(false);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
|
|
36
21
|
describe('defaultHtmlViewHitTestHandler', () => {
|
|
37
22
|
it('always returns false — browser manages HtmlView hit testing', () => {
|
|
38
23
|
const obj = makeNode2D();
|
|
@@ -56,18 +41,6 @@ describe('defaultNode2DHitTestHandler', () => {
|
|
|
56
41
|
});
|
|
57
42
|
});
|
|
58
43
|
|
|
59
|
-
describe('defaultRenderTargetNode2DHitTestHandler', () => {
|
|
60
|
-
it('returns true when point is within local bounds', () => {
|
|
61
|
-
const obj = makeNode2D();
|
|
62
|
-
expect(defaultRenderTargetNode2DHitTestHandler(obj, 50, 50)).toBe(true);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('returns false when point is outside local bounds', () => {
|
|
66
|
-
const obj = makeNode2D();
|
|
67
|
-
expect(defaultRenderTargetNode2DHitTestHandler(obj, 200, 200)).toBe(false);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
44
|
describe('defaultRichTextHitTestHandler', () => {
|
|
72
45
|
it('returns true when point is within local bounds', () => {
|
|
73
46
|
const obj = makeNode2D();
|
|
@@ -115,15 +88,3 @@ describe('defaultTextInputHitTestHandler', () => {
|
|
|
115
88
|
expect(defaultTextInputHitTestHandler(obj, 200, 200)).toBe(false);
|
|
116
89
|
});
|
|
117
90
|
});
|
|
118
|
-
|
|
119
|
-
describe('defaultVideoHitTestHandler', () => {
|
|
120
|
-
it('returns true when point is within local bounds', () => {
|
|
121
|
-
const obj = makeNode2D();
|
|
122
|
-
expect(defaultVideoHitTestHandler(obj, 50, 50)).toBe(true);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('returns false when point is outside local bounds', () => {
|
|
126
|
-
const obj = makeNode2D();
|
|
127
|
-
expect(defaultVideoHitTestHandler(obj, 200, 200)).toBe(false);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setRectangle } from '@flighthq/geometry/contract';
|
|
2
2
|
import { getNodeLocalBoundsRectangle } from '@flighthq/node/contract';
|
|
3
|
-
import {
|
|
4
|
-
import { createShape } from '@flighthq/shape/contract';
|
|
3
|
+
import { createSprite, createScene2D } from '@flighthq/scene2d/contract';
|
|
4
|
+
import { createMorphShape, createShape } from '@flighthq/shape/contract';
|
|
5
5
|
|
|
6
6
|
import { findGraphHitTarget } from './hitTests';
|
|
7
7
|
import { setNodeHitTestEnabled } from './nodeInteractionState';
|
|
@@ -11,7 +11,7 @@ describe('registerDefaultHitTests', () => {
|
|
|
11
11
|
it('registers all built-in kinds so findGraphHitTarget resolves them', () => {
|
|
12
12
|
registerDefaultHitTests();
|
|
13
13
|
|
|
14
|
-
const bitmap =
|
|
14
|
+
const bitmap = createSprite();
|
|
15
15
|
setRectangle(getNodeLocalBoundsRectangle(bitmap), 0, 0, 100, 100);
|
|
16
16
|
setNodeHitTestEnabled(bitmap, true);
|
|
17
17
|
expect(findGraphHitTarget(bitmap, 50, 50)).toBe(bitmap);
|
|
@@ -20,6 +20,11 @@ describe('registerDefaultHitTests', () => {
|
|
|
20
20
|
setRectangle(getNodeLocalBoundsRectangle(shape), 0, 0, 100, 100);
|
|
21
21
|
setNodeHitTestEnabled(shape, true);
|
|
22
22
|
expect(findGraphHitTarget(shape, 50, 50)).toBe(shape);
|
|
23
|
+
|
|
24
|
+
const morphShape = createMorphShape({ commands: [], endData: [], startData: [], winding: 'nonZero' });
|
|
25
|
+
setRectangle(getNodeLocalBoundsRectangle(morphShape), 0, 0, 100, 100);
|
|
26
|
+
setNodeHitTestEnabled(morphShape, true);
|
|
27
|
+
expect(findGraphHitTarget(morphShape, 50, 50)).toBe(morphShape);
|
|
23
28
|
});
|
|
24
29
|
|
|
25
30
|
it('containers return null for self hit', () => {
|
|
@@ -1,13 +1,50 @@
|
|
|
1
1
|
import { setRectangle } from '@flighthq/geometry/contract';
|
|
2
2
|
import { getNodeLocalBoundsRectangle } from '@flighthq/node/contract';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { appendPathCircle, appendPathRectangle, createPath, createPathMorph } from '@flighthq/path/contract';
|
|
4
|
+
import {
|
|
5
|
+
appendMorphShapePath,
|
|
6
|
+
appendShapeBeginFill,
|
|
7
|
+
appendShapeCircle,
|
|
8
|
+
appendShapeEndFill,
|
|
9
|
+
createMorphShape,
|
|
10
|
+
createShape,
|
|
11
|
+
setMorphShapeProgress,
|
|
12
|
+
} from '@flighthq/shape/contract';
|
|
13
|
+
import { MorphShapeKind, ShapeKind } from '@flighthq/types/contract';
|
|
5
14
|
|
|
6
15
|
import { findGraphHitTargetPrecise, hitTestGraphLocalBounds, hitTestGraphPoint, registerHitTest } from './hitTests';
|
|
7
16
|
import { setNodeHitTestEnabled } from './nodeInteractionState';
|
|
8
17
|
import { registerShapeHitTest } from './registerShapeHitTest';
|
|
9
18
|
|
|
10
19
|
describe('registerShapeHitTest', () => {
|
|
20
|
+
it('winding-tests the MorphShape live sample for precise queries', () => {
|
|
21
|
+
registerHitTest(MorphShapeKind, hitTestGraphLocalBounds);
|
|
22
|
+
registerShapeHitTest();
|
|
23
|
+
const start = createPath();
|
|
24
|
+
appendPathCircle(start, 50, 50, 40);
|
|
25
|
+
const end = createPath();
|
|
26
|
+
appendPathRectangle(end, 10, 10, 80, 80);
|
|
27
|
+
const shape = createMorphShape(createPathMorph(start, end)!);
|
|
28
|
+
const secondStart = createPath();
|
|
29
|
+
appendPathCircle(secondStart, 150, 150, 40);
|
|
30
|
+
const secondEnd = createPath();
|
|
31
|
+
appendPathRectangle(secondEnd, 110, 110, 80, 80);
|
|
32
|
+
appendShapeBeginFill(shape, 0xff0000ff, 1);
|
|
33
|
+
appendMorphShapePath(shape);
|
|
34
|
+
appendShapeEndFill(shape);
|
|
35
|
+
appendShapeBeginFill(shape, 0x0000ffff, 1);
|
|
36
|
+
appendMorphShapePath(shape, createPathMorph(secondStart, secondEnd)!);
|
|
37
|
+
appendShapeEndFill(shape);
|
|
38
|
+
setRectangle(getNodeLocalBoundsRectangle(shape), 10, 10, 180, 180);
|
|
39
|
+
setNodeHitTestEnabled(shape, true);
|
|
40
|
+
|
|
41
|
+
expect(findGraphHitTargetPrecise(shape, 85, 85)).toBeNull();
|
|
42
|
+
expect(findGraphHitTargetPrecise(shape, 185, 185)).toBeNull();
|
|
43
|
+
setMorphShapeProgress(shape, 1);
|
|
44
|
+
expect(findGraphHitTargetPrecise(shape, 85, 85)).toBe(shape);
|
|
45
|
+
expect(findGraphHitTargetPrecise(shape, 185, 185)).toBe(shape);
|
|
46
|
+
});
|
|
47
|
+
|
|
11
48
|
it('winding-tests the actual fill for precise queries, so a bbox corner outside the circle misses', () => {
|
|
12
49
|
registerHitTest(ShapeKind, hitTestGraphLocalBounds);
|
|
13
50
|
registerShapeHitTest();
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { setRectangle } from '@flighthq/geometry/contract';
|
|
2
2
|
import { getNodeLocalBoundsRectangle } from '@flighthq/node/contract';
|
|
3
|
-
import {
|
|
3
|
+
import { createSprite } from '@flighthq/scene2d/contract';
|
|
4
4
|
|
|
5
5
|
import { findGraphHitTargetPrecise } from './hitTests';
|
|
6
6
|
import { setNodeHitTestEnabled } from './nodeInteractionState';
|
|
7
|
-
import {
|
|
7
|
+
import { registerSpriteHitTest } from './registerSpriteHitTest';
|
|
8
8
|
|
|
9
|
-
describe('
|
|
9
|
+
describe('registerSpriteHitTest', () => {
|
|
10
10
|
// Positive alpha-accuracy is exercised by the functional suite (jsdom cannot rasterize pixels); this
|
|
11
11
|
// covers the wiring and the documented bounds fallback when no readable image is present.
|
|
12
|
-
it('installs a precise
|
|
13
|
-
|
|
14
|
-
const bitmap =
|
|
12
|
+
it('installs a precise Sprite provider with a no-image bounds fallback', () => {
|
|
13
|
+
registerSpriteHitTest();
|
|
14
|
+
const bitmap = createSprite();
|
|
15
15
|
setRectangle(getNodeLocalBoundsRectangle(bitmap), 0, 0, 100, 100);
|
|
16
16
|
setNodeHitTestEnabled(bitmap, true);
|
|
17
17
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { setRectangle } from '@flighthq/geometry/contract';
|
|
2
2
|
import { addNodeChild, getNodeLocalBoundsRectangle } from '@flighthq/node/contract';
|
|
3
|
-
import { createQuadBatch
|
|
3
|
+
import { createQuadBatch } from '@flighthq/quadbatch/contract';
|
|
4
|
+
import { createSprite } from '@flighthq/scene2d/contract';
|
|
5
|
+
import { createTilemap } from '@flighthq/tilemap/contract';
|
|
4
6
|
|
|
5
7
|
import {
|
|
6
8
|
defaultQuadBatchHitTestHandler,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registerBitmapHitTest.d.ts","sourceRoot":"","sources":["../src/registerBitmapHitTest.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,GAAE,MAAU,GAAG,IAAI,CAEtE"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { inverseMatrixTransformPointXY } from '@flighthq/geometry/contract';
|
|
2
|
-
import { getNodeWorldMatrix } from '@flighthq/node/contract';
|
|
3
|
-
import { createSurfaceFromImageResource, getSurfacePixelChannel } from '@flighthq/surface/contract';
|
|
4
|
-
import { BitmapKind, ImageChannel } from '@flighthq/types/contract';
|
|
5
|
-
import { hitTestGraphLocalBounds, registerHitTestPrecise } from './hitTests';
|
|
6
|
-
/**
|
|
7
|
-
* Opt-in exact hit provider for bitmaps: the `*Precise` queries then hit a Bitmap only where its pixel
|
|
8
|
-
* alpha meets `alphaThreshold` (0..255). Within the node's bounds but where the pixels aren't readable
|
|
9
|
-
* (no image, a GPU-only texture, or a headless environment that can't rasterize), it falls back to a
|
|
10
|
-
* bounds hit rather than throwing — best-available precision for that instance.
|
|
11
|
-
*
|
|
12
|
-
* Importing this module is the opt-in — it pulls `@flighthq/surface`, so the base interaction bundle
|
|
13
|
-
* stays free of it (tree-shaken unless referenced).
|
|
14
|
-
*/
|
|
15
|
-
export function registerBitmapHitTest(alphaThreshold = 1) {
|
|
16
|
-
registerHitTestPrecise(BitmapKind, (source, x, y) => hitTestBitmapAlpha(source, x, y, alphaThreshold));
|
|
17
|
-
}
|
|
18
|
-
// Returns 0 on a hit (opaque pixel, or bounds fallback when pixels are unreadable), -1 on a miss.
|
|
19
|
-
function hitTestBitmapAlpha(source, x, y, alphaThreshold) {
|
|
20
|
-
if (!hitTestGraphLocalBounds(source, x, y))
|
|
21
|
-
return -1;
|
|
22
|
-
const bitmap = source;
|
|
23
|
-
const image = bitmap.data.image;
|
|
24
|
-
if (image === null)
|
|
25
|
-
return 0;
|
|
26
|
-
const surface = surfaceForImage(image);
|
|
27
|
-
if (surface === null)
|
|
28
|
-
return 0;
|
|
29
|
-
inverseMatrixTransformPointXY(bitmapAlphaLocalPoint, getNodeWorldMatrix(source), x, y);
|
|
30
|
-
const rect = bitmap.data.sourceRectangle;
|
|
31
|
-
const px = Math.floor(bitmapAlphaLocalPoint.x + (rect !== null ? rect.x : 0));
|
|
32
|
-
const py = Math.floor(bitmapAlphaLocalPoint.y + (rect !== null ? rect.y : 0));
|
|
33
|
-
if (px < 0 || py < 0 || px >= surface.width || py >= surface.height)
|
|
34
|
-
return -1;
|
|
35
|
-
return getSurfacePixelChannel(surface, px, py, ImageChannel.Alpha) >= alphaThreshold ? 0 : -1;
|
|
36
|
-
}
|
|
37
|
-
function surfaceForImage(image) {
|
|
38
|
-
const cached = surfaceCache.get(image);
|
|
39
|
-
if (cached !== undefined)
|
|
40
|
-
return cached;
|
|
41
|
-
let surface = null;
|
|
42
|
-
try {
|
|
43
|
-
surface = createSurfaceFromImageResource(image);
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
surface = null;
|
|
47
|
-
}
|
|
48
|
-
// Cache only successes so an image that is not yet readable is retried later.
|
|
49
|
-
if (surface !== null)
|
|
50
|
-
surfaceCache.set(image, surface);
|
|
51
|
-
return surface;
|
|
52
|
-
}
|
|
53
|
-
const bitmapAlphaLocalPoint = { x: 0, y: 0 };
|
|
54
|
-
const surfaceCache = new WeakMap();
|
|
55
|
-
//# sourceMappingURL=registerBitmapHitTest.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registerBitmapHitTest.js","sourceRoot":"","sources":["../src/registerBitmapHitTest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpG,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,iBAAyB,CAAC;IAC9D,sBAAsB,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;AACzG,CAAC;AAED,kGAAkG;AAClG,SAAS,kBAAkB,CAAC,MAAe,EAAE,CAAS,EAAE,CAAS,EAAE,cAAsB;IACvF,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,MAAgB,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IAChC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IAE7B,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IAE/B,6BAA6B,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,MAAgB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;IACzC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,KAAK,IAAI,EAAE,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,CAAC;IAC/E,OAAO,sBAAsB,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,eAAe,CAAC,KAAoB;IAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,IAAI,OAAO,GAAmB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,GAAG,8BAA8B,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,8EAA8E;IAC9E,IAAI,OAAO,KAAK,IAAI;QAAE,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,qBAAqB,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC7C,MAAM,YAAY,GAAG,IAAI,OAAO,EAA0B,CAAC"}
|