@tvuikit/navigation-pixi 0.1.0 → 0.1.2
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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/pixiRegistry.d.ts +78 -0
- package/dist/pixiRegistry.d.ts.map +1 -0
- package/package.json +5 -5
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
function z(d) {
|
|
2
|
+
return { x: d.x, y: d.y, w: d.width, h: d.height };
|
|
3
|
+
}
|
|
4
|
+
function S(d) {
|
|
5
|
+
const E = d?.skipUpdate ?? !0, v = d?.view ?? d?.app?.view, o = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new WeakMap(), w = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), a = [], c = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Set();
|
|
6
|
+
let f = !1, l = { added: [], removed: [], changed: [] };
|
|
7
|
+
const L = (e) => l.added.push(e), j = (e) => l.removed.push(e), C = (e) => l.changed.push(e);
|
|
8
|
+
let k = 0, O = 0, M = !0;
|
|
9
|
+
const F = () => {
|
|
10
|
+
M = !0, f = !0;
|
|
11
|
+
};
|
|
12
|
+
return typeof window < "u" && v && (window.addEventListener("scroll", F, { passive: !0, capture: !0 }), window.addEventListener("resize", F, { passive: !0 })), {
|
|
13
|
+
ids() {
|
|
14
|
+
return a;
|
|
15
|
+
},
|
|
16
|
+
bounds(e) {
|
|
17
|
+
return w.get(e) ?? null;
|
|
18
|
+
},
|
|
19
|
+
group(e) {
|
|
20
|
+
return h.get(e) ?? null;
|
|
21
|
+
},
|
|
22
|
+
enabled(e) {
|
|
23
|
+
const n = o.get(e);
|
|
24
|
+
if (!n || n.destroyed) return !1;
|
|
25
|
+
const t = y.get(e);
|
|
26
|
+
return t !== void 0 ? t : !(n.visible === !1 || n.renderable === !1);
|
|
27
|
+
},
|
|
28
|
+
visible(e) {
|
|
29
|
+
const n = o.get(e);
|
|
30
|
+
if (!n || n.destroyed) return !1;
|
|
31
|
+
const t = p.get(e);
|
|
32
|
+
if (t !== void 0) return t;
|
|
33
|
+
const i = n.worldVisible;
|
|
34
|
+
return i !== void 0 ? i : n.visible !== !1;
|
|
35
|
+
},
|
|
36
|
+
sync(e) {
|
|
37
|
+
if (v && M) {
|
|
38
|
+
M = !1;
|
|
39
|
+
const r = v.getBoundingClientRect();
|
|
40
|
+
k = r.left, O = r.top;
|
|
41
|
+
}
|
|
42
|
+
const n = [];
|
|
43
|
+
if (f) {
|
|
44
|
+
f = !1;
|
|
45
|
+
for (let r = 0; r < a.length; r++) n.push(a[r]);
|
|
46
|
+
} else if (s.size > 0) {
|
|
47
|
+
for (const r of s) n.push(r);
|
|
48
|
+
s.clear();
|
|
49
|
+
}
|
|
50
|
+
for (let r = 0; r < n.length; r++) {
|
|
51
|
+
const u = n[r], g = o.get(u);
|
|
52
|
+
if (!g || g.destroyed) continue;
|
|
53
|
+
const B = z(g.getBounds(E)), I = v ? { x: B.x + k, y: B.y + O, w: B.w, h: B.h } : B, m = w.get(u);
|
|
54
|
+
w.set(u, I), (!m || m.x !== I.x || m.y !== I.y || m.w !== I.w || m.h !== I.h) && C(u);
|
|
55
|
+
}
|
|
56
|
+
const t = e?.added ?? [], i = e?.changed ?? [];
|
|
57
|
+
for (let r = 0; r < t.length; r++) s.add(t[r]);
|
|
58
|
+
for (let r = 0; r < i.length; r++) s.add(i[r]);
|
|
59
|
+
},
|
|
60
|
+
pendingUpdate() {
|
|
61
|
+
if (!(l.added.length > 0 || l.removed.length > 0 || l.changed.length > 0)) return;
|
|
62
|
+
const n = l;
|
|
63
|
+
return l = { added: [], removed: [], changed: [] }, n;
|
|
64
|
+
},
|
|
65
|
+
onFocus(e, n) {
|
|
66
|
+
x.get(e)?.(n);
|
|
67
|
+
},
|
|
68
|
+
onBlur(e, n) {
|
|
69
|
+
b.get(e)?.(n);
|
|
70
|
+
},
|
|
71
|
+
register(e, n, t) {
|
|
72
|
+
if (c.has(e)) {
|
|
73
|
+
o.set(e, n), A.set(n, e), t?.enabled !== void 0 && y.set(e, t.enabled), t?.visible !== void 0 && p.set(e, t.visible), t?.groupId !== void 0 && h.set(e, t.groupId), t?.onFocus && x.set(e, t.onFocus), t?.onBlur && b.set(e, t.onBlur), s.add(e), C(e);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
a.push(e), c.set(e, a.length - 1), o.set(e, n), A.set(n, e), t?.enabled !== void 0 && y.set(e, t.enabled), t?.visible !== void 0 && p.set(e, t.visible), t?.groupId !== void 0 && h.set(e, t.groupId), t?.onFocus && x.set(e, t.onFocus), t?.onBlur && b.set(e, t.onBlur), s.add(e), L(e);
|
|
77
|
+
},
|
|
78
|
+
unregister(e) {
|
|
79
|
+
const n = c.get(e);
|
|
80
|
+
if (n === void 0) return;
|
|
81
|
+
const t = a.pop();
|
|
82
|
+
t !== e && (a[n] = t, c.set(t, n)), c.delete(e), o.delete(e), w.delete(e), h.delete(e), y.delete(e), p.delete(e), x.delete(e), b.delete(e), s.delete(e), j(e);
|
|
83
|
+
},
|
|
84
|
+
invalidate(e) {
|
|
85
|
+
s.add(e);
|
|
86
|
+
},
|
|
87
|
+
invalidateAll() {
|
|
88
|
+
f = !0;
|
|
89
|
+
},
|
|
90
|
+
createContainerInvalidator(e) {
|
|
91
|
+
let n = e.x, t = e.y, i = e.scale?.x ?? 1, r = e.scale?.y ?? 1;
|
|
92
|
+
return () => {
|
|
93
|
+
const u = e.scale?.x ?? 1, g = e.scale?.y ?? 1;
|
|
94
|
+
e.x === n && e.y === t && u === i && g === r || (n = e.x, t = e.y, i = u, r = g, f = !0);
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
getObject(e) {
|
|
98
|
+
return o.get(e);
|
|
99
|
+
},
|
|
100
|
+
dispose() {
|
|
101
|
+
typeof window < "u" && v && (window.removeEventListener("scroll", F, !0), window.removeEventListener("resize", F)), a.length = 0, c.clear(), o.clear(), w.clear(), h.clear(), y.clear(), p.clear(), x.clear(), b.clear(), s.clear(), f = !1, l = { added: [], removed: [], changed: [] }, M = !0, k = 0, O = 0;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
S as createPixiRegistry
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/pixiRegistry.ts"],"sourcesContent":["import type {\n FocusReason,\n GroupId,\n NodeId,\n Rect,\n RegistryUpdate,\n SpatialRegistry,\n} from \"@tvuikit/navigation\";\n\n/**\n * Minimal structural type for Pixi DisplayObjects / Containers without depending on `pixi.js`.\n * Works with Pixi v7/v8 `getBounds(skipUpdate?)`.\n */\nexport type PixiDisplayObjectLike = {\n getBounds(skipUpdate?: boolean): { x: number; y: number; width: number; height: number };\n visible?: boolean;\n renderable?: boolean;\n worldVisible?: boolean;\n destroyed?: boolean;\n};\n\nexport type PixiRegistryOptions = {\n /**\n * If provided, bounds will be offset by the canvas' client rect so Pixi coords\n * can be navigated together with DOM client rects.\n */\n view?: HTMLCanvasElement;\n\n /**\n * Convenience: pass your Pixi `Application` and we'll use `app.view` as `view`.\n * (Typed structurally to avoid a hard dependency on `pixi.js`.)\n */\n app?: { view: HTMLCanvasElement };\n\n /**\n * Passed to `displayObject.getBounds(skipUpdate)`.\n * - true: do not force transforms update (faster; assumes your render loop already updates)\n * - false: force update (more accurate if you call sync outside render)\n *\n * Default: true\n */\n skipUpdate?: boolean;\n};\n\nexport type PixiRegisterOptions = {\n enabled?: boolean;\n visible?: boolean;\n groupId?: GroupId | null;\n onFocus?: (reason: FocusReason) => void;\n onBlur?: (reason: FocusReason) => void;\n};\n\nexport type PixiRegistry = SpatialRegistry & {\n register(id: NodeId, obj: PixiDisplayObjectLike, options?: PixiRegisterOptions): void;\n unregister(id: NodeId): void;\n invalidate(id: NodeId): void;\n invalidateAll(): void;\n /**\n * Convenience for \"scrolling containers\":\n * returns a function you can call from your render/tick/scroll loop.\n *\n * If the container's transform changed since the last call, we'll `invalidateAll()`\n * so cached bounds refresh on the next `engine.sync()`.\n *\n * This is intentionally push-based (no RAF started internally).\n */\n createContainerInvalidator(container: PixiContainerLike): () => void;\n getObject(id: NodeId): PixiDisplayObjectLike | undefined;\n dispose(): void;\n};\n\n/**\n * Minimal structural type for a Pixi Container transform (no dependency on pixi.js).\n * We only use the fields needed to detect \"scrolling\"/panning.\n */\nexport type PixiContainerLike = {\n x: number;\n y: number;\n scale?: { x: number; y: number };\n};\n\nfunction rectFromPixiBounds(b: { x: number; y: number; width: number; height: number }): Rect {\n return { x: b.x, y: b.y, w: b.width, h: b.height };\n}\n\nexport function createPixiRegistry(options?: PixiRegistryOptions): PixiRegistry {\n const skipUpdate = options?.skipUpdate ?? true;\n const view = options?.view ?? options?.app?.view;\n\n const objById = new Map<NodeId, PixiDisplayObjectLike>();\n const idByObj = new WeakMap<object, NodeId>();\n const rectById = new Map<NodeId, Rect>();\n const groupById = new Map<NodeId, GroupId | null>();\n const enabledById = new Map<NodeId, boolean>();\n const visibleOverrideById = new Map<NodeId, boolean>();\n const onFocusById = new Map<NodeId, (reason: FocusReason) => void>();\n const onBlurById = new Map<NodeId, (reason: FocusReason) => void>();\n\n // Stable ids + swap-remove\n const idsArr: NodeId[] = [];\n const idToIndex = new Map<NodeId, number>();\n\n // Dirty tracking\n const dirty = new Set<NodeId>();\n let dirtyAll = false;\n\n // Pending incremental updates\n let pending: Required<RegistryUpdate> = { added: [], removed: [], changed: [] };\n const markAdded = (id: NodeId) => pending.added.push(id);\n const markRemoved = (id: NodeId) => pending.removed.push(id);\n const markChanged = (id: NodeId) => pending.changed.push(id);\n\n // Canvas offset caching (updated during sync when needed)\n let viewOffsetX = 0;\n let viewOffsetY = 0;\n let viewDirty = true;\n\n const onViewportChange = () => {\n viewDirty = true;\n dirtyAll = true;\n };\n if (typeof window !== \"undefined\" && view) {\n window.addEventListener(\"scroll\", onViewportChange, { passive: true, capture: true });\n window.addEventListener(\"resize\", onViewportChange, { passive: true });\n }\n\n const registry: PixiRegistry = {\n ids() {\n return idsArr;\n },\n bounds(id) {\n return rectById.get(id) ?? null;\n },\n group(id) {\n return groupById.get(id) ?? null;\n },\n enabled(id) {\n const obj = objById.get(id);\n if (!obj) return false;\n if (obj.destroyed) return false;\n const override = enabledById.get(id);\n if (override !== undefined) return override;\n // Conservative: require visible+renderable if present.\n if (obj.visible === false) return false;\n if (obj.renderable === false) return false;\n return true;\n },\n visible(id) {\n const obj = objById.get(id);\n if (!obj) return false;\n if (obj.destroyed) return false;\n const override = visibleOverrideById.get(id);\n if (override !== undefined) return override;\n // Prefer worldVisible when available.\n const wv = (obj as { worldVisible?: boolean }).worldVisible;\n if (wv !== undefined) return wv;\n return obj.visible !== false;\n },\n sync(hint) {\n if (view && viewDirty) {\n viewDirty = false;\n const r = view.getBoundingClientRect();\n viewOffsetX = r.left;\n viewOffsetY = r.top;\n }\n\n const toMeasure: NodeId[] = [];\n if (dirtyAll) {\n dirtyAll = false;\n for (let i = 0; i < idsArr.length; i++) toMeasure.push(idsArr[i]!);\n } else if (dirty.size > 0) {\n for (const id of dirty) toMeasure.push(id);\n dirty.clear();\n }\n\n for (let i = 0; i < toMeasure.length; i++) {\n const id = toMeasure[i]!;\n const obj = objById.get(id);\n if (!obj || obj.destroyed) continue;\n const b = rectFromPixiBounds(obj.getBounds(skipUpdate));\n const next: Rect = view\n ? { x: b.x + viewOffsetX, y: b.y + viewOffsetY, w: b.w, h: b.h }\n : b;\n const prev = rectById.get(id);\n rectById.set(id, next);\n if (\n !prev ||\n prev.x !== next.x ||\n prev.y !== next.y ||\n prev.w !== next.w ||\n prev.h !== next.h\n ) {\n markChanged(id);\n }\n }\n\n // If the engine provided a hint, ensure bounds are refreshed for added/changed.\n const added = hint?.added ?? [];\n const changed = hint?.changed ?? [];\n for (let i = 0; i < added.length; i++) dirty.add(added[i]!);\n for (let i = 0; i < changed.length; i++) dirty.add(changed[i]!);\n },\n pendingUpdate() {\n const has =\n pending.added.length > 0 || pending.removed.length > 0 || pending.changed.length > 0;\n if (!has) return undefined;\n const hint: RegistryUpdate = pending;\n pending = { added: [], removed: [], changed: [] };\n return hint;\n },\n onFocus(id, reason) {\n onFocusById.get(id)?.(reason);\n },\n onBlur(id, reason) {\n onBlurById.get(id)?.(reason);\n },\n register(id, obj, opts) {\n if (idToIndex.has(id)) {\n objById.set(id, obj);\n idByObj.set(obj as object, id);\n if (opts?.enabled !== undefined) enabledById.set(id, opts.enabled);\n if (opts?.visible !== undefined) visibleOverrideById.set(id, opts.visible);\n if (opts?.groupId !== undefined) groupById.set(id, opts.groupId);\n if (opts?.onFocus) onFocusById.set(id, opts.onFocus);\n if (opts?.onBlur) onBlurById.set(id, opts.onBlur);\n dirty.add(id);\n markChanged(id);\n return;\n }\n\n idsArr.push(id);\n idToIndex.set(id, idsArr.length - 1);\n\n objById.set(id, obj);\n idByObj.set(obj as object, id);\n if (opts?.enabled !== undefined) enabledById.set(id, opts.enabled);\n if (opts?.visible !== undefined) visibleOverrideById.set(id, opts.visible);\n if (opts?.groupId !== undefined) groupById.set(id, opts.groupId);\n if (opts?.onFocus) onFocusById.set(id, opts.onFocus);\n if (opts?.onBlur) onBlurById.set(id, opts.onBlur);\n\n dirty.add(id);\n markAdded(id);\n },\n unregister(id) {\n const idx = idToIndex.get(id);\n if (idx === undefined) return;\n\n const last = idsArr.pop()!;\n if (last !== id) {\n idsArr[idx] = last;\n idToIndex.set(last, idx);\n }\n idToIndex.delete(id);\n\n objById.delete(id);\n rectById.delete(id);\n groupById.delete(id);\n enabledById.delete(id);\n visibleOverrideById.delete(id);\n onFocusById.delete(id);\n onBlurById.delete(id);\n dirty.delete(id);\n\n markRemoved(id);\n },\n invalidate(id) {\n dirty.add(id);\n },\n invalidateAll() {\n dirtyAll = true;\n },\n createContainerInvalidator(container) {\n let lastX = container.x;\n let lastY = container.y;\n let lastSx = container.scale?.x ?? 1;\n let lastSy = container.scale?.y ?? 1;\n return () => {\n const sx = container.scale?.x ?? 1;\n const sy = container.scale?.y ?? 1;\n if (container.x === lastX && container.y === lastY && sx === lastSx && sy === lastSy)\n return;\n lastX = container.x;\n lastY = container.y;\n lastSx = sx;\n lastSy = sy;\n dirtyAll = true;\n };\n },\n getObject(id) {\n return objById.get(id);\n },\n dispose() {\n if (typeof window !== \"undefined\" && view) {\n window.removeEventListener(\"scroll\", onViewportChange, true);\n window.removeEventListener(\"resize\", onViewportChange);\n }\n idsArr.length = 0;\n idToIndex.clear();\n objById.clear();\n rectById.clear();\n groupById.clear();\n enabledById.clear();\n visibleOverrideById.clear();\n onFocusById.clear();\n onBlurById.clear();\n dirty.clear();\n dirtyAll = false;\n pending = { added: [], removed: [], changed: [] };\n viewDirty = true;\n viewOffsetX = 0;\n viewOffsetY = 0;\n },\n };\n\n return registry;\n}\n"],"names":["rectFromPixiBounds","b","createPixiRegistry","options","skipUpdate","view","objById","idByObj","rectById","groupById","enabledById","visibleOverrideById","onFocusById","onBlurById","idsArr","idToIndex","dirty","dirtyAll","pending","markAdded","id","markRemoved","markChanged","viewOffsetX","viewOffsetY","viewDirty","onViewportChange","obj","override","wv","hint","toMeasure","i","next","prev","added","changed","reason","opts","idx","last","container","lastX","lastY","lastSx","lastSy","sx","sy"],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { FocusReason, GroupId, NodeId, SpatialRegistry } from "@tvuikit/navigation";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural type for Pixi DisplayObjects / Containers without depending on `pixi.js`.
|
|
4
|
+
* Works with Pixi v7/v8 `getBounds(skipUpdate?)`.
|
|
5
|
+
*/
|
|
6
|
+
export type PixiDisplayObjectLike = {
|
|
7
|
+
getBounds(skipUpdate?: boolean): {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
visible?: boolean;
|
|
14
|
+
renderable?: boolean;
|
|
15
|
+
worldVisible?: boolean;
|
|
16
|
+
destroyed?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type PixiRegistryOptions = {
|
|
19
|
+
/**
|
|
20
|
+
* If provided, bounds will be offset by the canvas' client rect so Pixi coords
|
|
21
|
+
* can be navigated together with DOM client rects.
|
|
22
|
+
*/
|
|
23
|
+
view?: HTMLCanvasElement;
|
|
24
|
+
/**
|
|
25
|
+
* Convenience: pass your Pixi `Application` and we'll use `app.view` as `view`.
|
|
26
|
+
* (Typed structurally to avoid a hard dependency on `pixi.js`.)
|
|
27
|
+
*/
|
|
28
|
+
app?: {
|
|
29
|
+
view: HTMLCanvasElement;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Passed to `displayObject.getBounds(skipUpdate)`.
|
|
33
|
+
* - true: do not force transforms update (faster; assumes your render loop already updates)
|
|
34
|
+
* - false: force update (more accurate if you call sync outside render)
|
|
35
|
+
*
|
|
36
|
+
* Default: true
|
|
37
|
+
*/
|
|
38
|
+
skipUpdate?: boolean;
|
|
39
|
+
};
|
|
40
|
+
export type PixiRegisterOptions = {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
visible?: boolean;
|
|
43
|
+
groupId?: GroupId | null;
|
|
44
|
+
onFocus?: (reason: FocusReason) => void;
|
|
45
|
+
onBlur?: (reason: FocusReason) => void;
|
|
46
|
+
};
|
|
47
|
+
export type PixiRegistry = SpatialRegistry & {
|
|
48
|
+
register(id: NodeId, obj: PixiDisplayObjectLike, options?: PixiRegisterOptions): void;
|
|
49
|
+
unregister(id: NodeId): void;
|
|
50
|
+
invalidate(id: NodeId): void;
|
|
51
|
+
invalidateAll(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Convenience for "scrolling containers":
|
|
54
|
+
* returns a function you can call from your render/tick/scroll loop.
|
|
55
|
+
*
|
|
56
|
+
* If the container's transform changed since the last call, we'll `invalidateAll()`
|
|
57
|
+
* so cached bounds refresh on the next `engine.sync()`.
|
|
58
|
+
*
|
|
59
|
+
* This is intentionally push-based (no RAF started internally).
|
|
60
|
+
*/
|
|
61
|
+
createContainerInvalidator(container: PixiContainerLike): () => void;
|
|
62
|
+
getObject(id: NodeId): PixiDisplayObjectLike | undefined;
|
|
63
|
+
dispose(): void;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Minimal structural type for a Pixi Container transform (no dependency on pixi.js).
|
|
67
|
+
* We only use the fields needed to detect "scrolling"/panning.
|
|
68
|
+
*/
|
|
69
|
+
export type PixiContainerLike = {
|
|
70
|
+
x: number;
|
|
71
|
+
y: number;
|
|
72
|
+
scale?: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export declare function createPixiRegistry(options?: PixiRegistryOptions): PixiRegistry;
|
|
78
|
+
//# sourceMappingURL=pixiRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pixiRegistry.d.ts","sourceRoot":"","sources":["../src/pixiRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,OAAO,EACP,MAAM,EAGN,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAE7B;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAEzB;;;OAGG;IACH,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAA;KAAE,CAAC;IAElC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACtF,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,IAAI,IAAI,CAAC;IACtB;;;;;;;;OAQG;IACH,0BAA0B,CAAC,SAAS,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC;IACrE,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAC;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClC,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAuO9E"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tvuikit/navigation-pixi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "PixiJS registry for TVKit Navigation. Provides WebGL/Canvas-based focusable registration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "TVKit Team",
|
|
9
|
-
"homepage": "https://
|
|
9
|
+
"homepage": "https://tvkit.dev/",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/dobreadi/tvkit.git",
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
|
-
"files": [
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
32
34
|
"exports": {
|
|
33
35
|
".": {
|
|
34
36
|
"types": "./dist/index.d.ts",
|
|
@@ -50,5 +52,3 @@
|
|
|
50
52
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
|
-
|
|
54
|
-
|