@umicat/phaser-sdk 1.0.12 → 1.0.14

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.
@@ -264,6 +264,9 @@ export function spawnHudEntity(ctx, entity) {
264
264
  }
265
265
  }
266
266
  go.setData('entityId', entity.id);
267
+ // Stamp the kind (mirrors spawnEntity for world entities) so the editor can
268
+ // branch on it — e.g. double-click an icon-button/text widget for inline edit.
269
+ go.setData('entityKind', entity.kind);
267
270
  // Z-order. Layer first (base < overlay < modal), then explicit z within layer.
268
271
  const layerDepth = LAYER_DEPTH[entity.layer ?? 'base'];
269
272
  const z = typeof entity.z === 'number' ? entity.z : 0;
@@ -16,8 +16,52 @@ export function setupScreenshotListener(game) {
16
16
  console.error('[UmicatSDK] Screenshot failed:', e);
17
17
  }
18
18
  }
19
+ else if (event.data?.type === 'screenshotRegion') {
20
+ // Marquee-to-chat: the host drew a selection rect over the iframe (in
21
+ // iframe-relative CSS px); crop the canvas to it here, where the canvas's
22
+ // on-screen position + intrinsic resolution are known (handles letterbox
23
+ // bars + display scaling). Responds with the cropped PNG.
24
+ try {
25
+ const r = event.data.rect;
26
+ const dataUrl = cropCanvasRegion(game, r);
27
+ window.parent.postMessage({ type: 'screenshot_region_result', dataUrl, requestId: event.data.requestId }, '*');
28
+ }
29
+ catch (e) {
30
+ console.error('[UmicatSDK] Region screenshot failed:', e);
31
+ window.parent.postMessage({ type: 'screenshot_region_result', dataUrl: null, requestId: event.data?.requestId }, '*');
32
+ }
33
+ }
19
34
  });
20
35
  }
36
+ /**
37
+ * Crop the game canvas to a rect given in iframe-relative CSS pixels (the host's
38
+ * marquee). Maps display px → intrinsic canvas px via the canvas's bounding rect
39
+ * + resolution (uniform scale — Phaser FIT preserves aspect), clamps to bounds.
40
+ */
41
+ function cropCanvasRegion(game, rect) {
42
+ const canvas = game.canvas;
43
+ const cr = canvas.getBoundingClientRect();
44
+ if (cr.width <= 0 || cr.height <= 0)
45
+ return null;
46
+ const scale = canvas.width / cr.width; // intrinsic px per displayed px
47
+ let sx = Math.round((rect.x - cr.x) * scale);
48
+ let sy = Math.round((rect.y - cr.y) * scale);
49
+ let sw = Math.round(rect.width * scale);
50
+ let sh = Math.round(rect.height * scale);
51
+ // Clamp to the canvas (the marquee can run past the letterboxed edges).
52
+ sx = Math.max(0, Math.min(sx, canvas.width - 1));
53
+ sy = Math.max(0, Math.min(sy, canvas.height - 1));
54
+ sw = Math.max(1, Math.min(sw, canvas.width - sx));
55
+ sh = Math.max(1, Math.min(sh, canvas.height - sy));
56
+ const out = document.createElement('canvas');
57
+ out.width = sw;
58
+ out.height = sh;
59
+ const ctx = out.getContext('2d');
60
+ if (!ctx)
61
+ return null;
62
+ ctx.drawImage(canvas, sx, sy, sw, sh, 0, 0, sw, sh);
63
+ return out.toDataURL('image/png');
64
+ }
21
65
  /**
22
66
  * Take a screenshot programmatically (e.g., from within a scene).
23
67
  * Returns a base64 data URL of the current canvas.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umicat/phaser-sdk",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Umicat Phaser 3 SDK — game infrastructure for the Umicat platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",