even-toolkit 0.1.0 → 0.2.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.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Splash screen system for G2 glasses apps.
3
+ *
4
+ * Renders a canvas-based splash image to G2 image tiles with configurable
5
+ * timing, tile layout, and a render callback for app-specific graphics.
6
+ *
7
+ * Usage:
8
+ * const splash = createSplash({
9
+ * render: (ctx, w, h) => {
10
+ * ctx.fillStyle = '#000';
11
+ * ctx.fillRect(0, 0, w, h);
12
+ * ctx.fillStyle = '#e0e0e0';
13
+ * ctx.font = 'bold 16px monospace';
14
+ * ctx.textAlign = 'center';
15
+ * ctx.fillText('MyApp', w/2, h/2);
16
+ * },
17
+ * tiles: 1,
18
+ * minTimeMs: 2000,
19
+ * });
20
+ *
21
+ * // In your bootstrap:
22
+ * await splash.show(bridge);
23
+ * // ... init your app ...
24
+ * await splash.waitMinTime();
25
+ * // Now safe to switch to app UI
26
+ */
27
+ export interface SplashConfig {
28
+ /**
29
+ * Render callback — draw your splash on the provided canvas context.
30
+ * The canvas is pre-filled with black.
31
+ *
32
+ * @param ctx Canvas 2D context
33
+ * @param w Canvas width in pixels
34
+ * @param h Canvas height in pixels
35
+ */
36
+ render: (ctx: CanvasRenderingContext2D, w: number, h: number) => void;
37
+ /**
38
+ * Number of image tiles to use (1-3).
39
+ * - 1: single 200x100 tile (left-aligned)
40
+ * - 2: 400x100 across 2 tiles
41
+ * - 3: 576x100 across 3 tiles (full width)
42
+ * Default: 1
43
+ */
44
+ tiles?: 1 | 2 | 3;
45
+ /**
46
+ * Minimum time the splash should be visible (ms).
47
+ * `waitMinTime()` will delay until this time has passed since `show()`.
48
+ * Default: 2000
49
+ */
50
+ minTimeMs?: number;
51
+ /**
52
+ * Maximum time before the splash is forcefully dismissed (ms).
53
+ * Set to 0 for no max. Default: 5000
54
+ */
55
+ maxTimeMs?: number;
56
+ /**
57
+ * Menu text shown below the image (in the text container).
58
+ * Default: empty string (hidden)
59
+ */
60
+ menuText?: string;
61
+ }
62
+ export interface SplashHandle {
63
+ /** Show the splash on the glasses. Returns when the image is sent. */
64
+ show: (bridge: SplashBridge) => Promise<void>;
65
+ /** Wait until minTimeMs has elapsed since show(). Resolves immediately if already elapsed. */
66
+ waitMinTime: () => Promise<void>;
67
+ /** Check if the splash is currently showing. */
68
+ isShowing: () => boolean;
69
+ /** Get encoded tile data (for apps that manage their own bridge). */
70
+ getTiles: () => {
71
+ id: number;
72
+ name: string;
73
+ bytes: Uint8Array;
74
+ }[];
75
+ }
76
+ /** Minimal bridge interface needed for splash (subset of EvenHubBridge). */
77
+ export interface SplashBridge {
78
+ showHomePage: (menuText: string) => Promise<void>;
79
+ sendImage: (containerId: number, containerName: string, pngBytes: Uint8Array) => Promise<void>;
80
+ }
81
+ export declare function createSplash(config: SplashConfig): SplashHandle;
82
+ //# sourceMappingURL=splash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splash.d.ts","sourceRoot":"","sources":["../splash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,MAAM,WAAW,YAAY;IAC3B;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAEtE;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAElB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,8FAA8F;IAC9F,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,gDAAgD;IAChD,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,qEAAqE;IACrE,QAAQ,EAAE,MAAM;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,EAAE,CAAC;CACnE;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA4F/D"}
package/dist/splash.js ADDED
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Splash screen system for G2 glasses apps.
3
+ *
4
+ * Renders a canvas-based splash image to G2 image tiles with configurable
5
+ * timing, tile layout, and a render callback for app-specific graphics.
6
+ *
7
+ * Usage:
8
+ * const splash = createSplash({
9
+ * render: (ctx, w, h) => {
10
+ * ctx.fillStyle = '#000';
11
+ * ctx.fillRect(0, 0, w, h);
12
+ * ctx.fillStyle = '#e0e0e0';
13
+ * ctx.font = 'bold 16px monospace';
14
+ * ctx.textAlign = 'center';
15
+ * ctx.fillText('MyApp', w/2, h/2);
16
+ * },
17
+ * tiles: 1,
18
+ * minTimeMs: 2000,
19
+ * });
20
+ *
21
+ * // In your bootstrap:
22
+ * await splash.show(bridge);
23
+ * // ... init your app ...
24
+ * await splash.waitMinTime();
25
+ * // Now safe to switch to app UI
26
+ */
27
+ import { G2_IMAGE_MAX_W, G2_IMAGE_MAX_H, IMAGE_TILES } from './layout';
28
+ import { encodeTilesBatch } from './png-utils';
29
+ export function createSplash(config) {
30
+ const tiles = config.tiles ?? 1;
31
+ const minTime = config.minTimeMs ?? 2000;
32
+ const maxTime = config.maxTimeMs ?? 5000;
33
+ const menuText = config.menuText ?? '';
34
+ let showTime = 0;
35
+ let showing = false;
36
+ let encodedTiles = [];
37
+ // Render canvas and encode tiles
38
+ function renderAndEncode() {
39
+ const tileW = G2_IMAGE_MAX_W; // 200
40
+ const tileH = G2_IMAGE_MAX_H; // 100
41
+ const canvasW = tiles * tileW;
42
+ const canvasH = tileH;
43
+ const canvas = document.createElement('canvas');
44
+ canvas.width = canvasW;
45
+ canvas.height = canvasH;
46
+ const ctx = canvas.getContext('2d');
47
+ // Black background
48
+ ctx.fillStyle = '#000000';
49
+ ctx.fillRect(0, 0, canvasW, canvasH);
50
+ // App-specific rendering
51
+ config.render(ctx, canvasW, canvasH);
52
+ // Encode each tile
53
+ encodedTiles = [];
54
+ for (let i = 0; i < tiles; i++) {
55
+ const slot = IMAGE_TILES[i];
56
+ const crop = { sx: i * tileW, sy: 0, sw: tileW, sh: tileH };
57
+ const enc = encodeTilesBatch(canvas, [{ crop, name: slot.name }], tileW, tileH)[0];
58
+ encodedTiles.push({ id: slot.id, name: slot.name, bytes: enc.bytes });
59
+ }
60
+ // Fill remaining tiles with black
61
+ if (tiles < 3) {
62
+ const black = document.createElement('canvas');
63
+ black.width = tileW;
64
+ black.height = tileH;
65
+ const bctx = black.getContext('2d');
66
+ bctx.fillStyle = '#000000';
67
+ bctx.fillRect(0, 0, tileW, tileH);
68
+ const blackEnc = encodeTilesBatch(black, [{ crop: { sx: 0, sy: 0, sw: tileW, sh: tileH }, name: 'black' }], tileW, tileH)[0];
69
+ for (let i = tiles; i < 3; i++) {
70
+ const slot = IMAGE_TILES[i];
71
+ encodedTiles.push({ id: slot.id, name: slot.name, bytes: blackEnc.bytes });
72
+ }
73
+ }
74
+ }
75
+ return {
76
+ async show(bridge) {
77
+ renderAndEncode();
78
+ showTime = Date.now();
79
+ showing = true;
80
+ // Show the home layout (image + optional text below)
81
+ await bridge.showHomePage(menuText);
82
+ // Send all tiles
83
+ for (const tile of encodedTiles) {
84
+ await bridge.sendImage(tile.id, tile.name, tile.bytes);
85
+ }
86
+ // Auto-dismiss after maxTime
87
+ if (maxTime > 0) {
88
+ setTimeout(() => { showing = false; }, maxTime);
89
+ }
90
+ },
91
+ async waitMinTime() {
92
+ const elapsed = Date.now() - showTime;
93
+ if (elapsed < minTime) {
94
+ await new Promise((r) => setTimeout(r, minTime - elapsed));
95
+ }
96
+ showing = false;
97
+ },
98
+ isShowing() {
99
+ return showing;
100
+ },
101
+ getTiles() {
102
+ if (encodedTiles.length === 0)
103
+ renderAndEncode();
104
+ return encodedTiles;
105
+ },
106
+ };
107
+ }
108
+ //# sourceMappingURL=splash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splash.js","sourceRoot":"","sources":["../splash.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "even-toolkit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Shared library for building Even Realities G2 glasses apps — bridge, display, gestures, action bars, timers, and more.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -69,6 +69,10 @@
69
69
  "./keep-alive": {
70
70
  "types": "./dist/keep-alive.d.ts",
71
71
  "import": "./dist/keep-alive.js"
72
+ },
73
+ "./splash": {
74
+ "types": "./dist/splash.d.ts",
75
+ "import": "./dist/splash.js"
72
76
  }
73
77
  },
74
78
  "files": [