@crowdedkingdoms/construct 0.3.10 → 0.3.11-test.1
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/README.md +1 -1
- package/package.json +1 -1
- package/src/platform/media/WebcamService.ts +36 -2
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Releases are on npm under one dist-tag per tier, and a game pins the exact
|
|
|
30
30
|
version of its own tier, as it pins CrowdyJS:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npm install --save-exact @crowdedkingdoms/construct # X.Y.Z
|
|
33
|
+
npm install --save-exact @crowdedkingdoms/construct@dev # an X.Y.Z-dev.N build
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
`dev` is `X.Y.Z-dev.N`, `test` is `X.Y.Z-test.N`, and `prod` is `X.Y.Z` on
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crowdedkingdoms/construct",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11-test.1",
|
|
4
4
|
"description": "The Construct framework: the Crowded Kingdoms game platform layer (hosted sign-in, World Stores, voice/webcam/chat, Crowdy Studio dock, app and grid mods, grid programs) and engine loop, shared by the-construct starter and the games built on it. Ships TypeScript source for Vite.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -208,6 +208,20 @@ export class WebcamService {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
/** Ask for the camera and start sending frames. Resolves once capturing. */
|
|
211
|
+
/** Video-pixel rectangle copied into the 128×96 JPEG. Null keeps the whole frame. */
|
|
212
|
+
private frameCrop: { x: number; y: number; width: number; height: number } | null = null;
|
|
213
|
+
/** Camera size for the next start(). The encoded frame stays 128×96. */
|
|
214
|
+
private captureRequest = { width: CAPTURE_WIDTH, height: CAPTURE_HEIGHT };
|
|
215
|
+
|
|
216
|
+
setFrameCrop(crop: { x: number; y: number; width: number; height: number } | null): void {
|
|
217
|
+
this.frameCrop = crop;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Ask the camera for a larger picture before the next start(), so a face crop still has pixels. */
|
|
221
|
+
setCaptureSize(width: number, height: number): void {
|
|
222
|
+
if (width > 0 && height > 0) this.captureRequest = { width, height };
|
|
223
|
+
}
|
|
224
|
+
|
|
211
225
|
async start(): Promise<void> {
|
|
212
226
|
if (this.captureTimer) return;
|
|
213
227
|
if (typeof navigator === 'undefined' || !navigator.mediaDevices?.getUserMedia) {
|
|
@@ -216,7 +230,11 @@ export class WebcamService {
|
|
|
216
230
|
}
|
|
217
231
|
try {
|
|
218
232
|
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
219
|
-
video: {
|
|
233
|
+
video: {
|
|
234
|
+
width: this.captureRequest.width,
|
|
235
|
+
height: this.captureRequest.height,
|
|
236
|
+
frameRate: CAPTURE_FPS,
|
|
237
|
+
},
|
|
220
238
|
audio: false,
|
|
221
239
|
});
|
|
222
240
|
} catch (error) {
|
|
@@ -246,6 +264,7 @@ export class WebcamService {
|
|
|
246
264
|
stop(): void {
|
|
247
265
|
if (this.captureTimer) clearInterval(this.captureTimer);
|
|
248
266
|
this.captureTimer = null;
|
|
267
|
+
this.frameCrop = null;
|
|
249
268
|
this.video?.pause();
|
|
250
269
|
this.video = null;
|
|
251
270
|
this.canvas = null;
|
|
@@ -302,7 +321,22 @@ export class WebcamService {
|
|
|
302
321
|
const ctx = canvas.getContext('2d') as
|
|
303
322
|
OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null;
|
|
304
323
|
if (!ctx) return null;
|
|
305
|
-
|
|
324
|
+
const crop = this.frameCrop;
|
|
325
|
+
if (crop && crop.width > 0 && crop.height > 0) {
|
|
326
|
+
ctx.drawImage(
|
|
327
|
+
video,
|
|
328
|
+
crop.x,
|
|
329
|
+
crop.y,
|
|
330
|
+
crop.width,
|
|
331
|
+
crop.height,
|
|
332
|
+
0,
|
|
333
|
+
0,
|
|
334
|
+
CAPTURE_WIDTH,
|
|
335
|
+
CAPTURE_HEIGHT,
|
|
336
|
+
);
|
|
337
|
+
} else {
|
|
338
|
+
ctx.drawImage(video, 0, 0, CAPTURE_WIDTH, CAPTURE_HEIGHT);
|
|
339
|
+
}
|
|
306
340
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
307
341
|
const blob = await toBlob(canvas, this.quality);
|
|
308
342
|
if (!blob) return null;
|