@jaak.ai/stamps 2.0.0-dev.20 → 2.0.0-dev.22

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 CHANGED
@@ -43,7 +43,7 @@ yarn add @jaak.ai/stamps
43
43
  <script type="module" src="https://unpkg.com/@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js"></script>
44
44
  </head>
45
45
  <body>
46
- <jaak-stamps id="detector" debug="false"></jaak-stamps>
46
+ <jaak-stamps id="detector" debug="false" mask-size="90"></jaak-stamps>
47
47
 
48
48
  <button onclick="startCapture()">Iniciar Captura</button>
49
49
  <button onclick="stopCapture()">Detener</button>
@@ -140,6 +140,7 @@ import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
140
140
  <jaak-stamps
141
141
  #detector
142
142
  [debug]="false"
143
+ [maskSize]="90"
143
144
  (captureCompleted)="onCaptureCompleted($event)"
144
145
  (isReady)="onComponentReady($event)">
145
146
  </jaak-stamps>
@@ -241,7 +242,7 @@ import React, { useRef, useEffect, useImperativeHandle, forwardRef } from 'react
241
242
  // Importar el web component
242
243
  import '@jaak.ai/stamps/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js';
243
244
 
244
- const JaakStampsWrapper = forwardRef(({ debug = false, onCaptureCompleted, onIsReady }, ref) => {
245
+ const JaakStampsWrapper = forwardRef(({ debug = false, maskSize = 90, onCaptureCompleted, onIsReady }, ref) => {
245
246
  const elementRef = useRef(null);
246
247
 
247
248
  useImperativeHandle(ref, () => ({
@@ -285,6 +286,7 @@ const JaakStampsWrapper = forwardRef(({ debug = false, onCaptureCompleted, onIsR
285
286
  <jaak-stamps
286
287
  ref={elementRef}
287
288
  debug={debug}
289
+ mask-size={maskSize}
288
290
  />
289
291
  );
290
292
  });
@@ -364,6 +366,7 @@ function App() {
364
366
  <JaakStampsWrapper
365
367
  ref={detectorRef}
366
368
  debug={false}
369
+ maskSize={90}
367
370
  onCaptureCompleted={handleCaptureCompleted}
368
371
  onIsReady={handleIsReady}
369
372
  />
@@ -435,6 +438,7 @@ export default App;
435
438
  |-----------|------|---------------|-------------|
436
439
  | `debug` | `boolean` | `false` | Activa el modo debug para mostrar información de depuración |
437
440
  | `alignmentTolerance` | `number` | `10` | Tolerancia en píxeles para considerar un lado alineado |
441
+ | `maskSize` | `number` | `90` | Porcentaje del video que ocupará la máscara de detección (50-100) |
438
442
 
439
443
  ### Métodos Públicos
440
444
 
@@ -18,7 +18,7 @@ var patchBrowser = () => {
18
18
 
19
19
  patchBrowser().then(async (options) => {
20
20
  await index.globalScripts();
21
- return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"isVideoActive":[32],"statusMessage":[32],"statusColor":[32],"bestScore":[32],"capturedFullFrame":[32],"capturedCroppedId":[32],"capturedBackFullFrame":[32],"capturedBackCroppedId":[32],"captureStep":[32],"isCapturing":[32],"showFlipAnimation":[32],"showSuccessAnimation":[32],"shouldMirrorVideo":[32],"sideAlignment":[32],"isDetectionPaused":[32],"isLoading":[32],"isModelPreloaded":[32],"isMaskReady":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"getStatus":[64],"preloadModel":[64],"skipBackCapture":[64]}]]]], options);
21
+ return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"isVideoActive":[32],"statusMessage":[32],"statusColor":[32],"bestScore":[32],"capturedFullFrame":[32],"capturedCroppedId":[32],"capturedBackFullFrame":[32],"capturedBackCroppedId":[32],"captureStep":[32],"isCapturing":[32],"showFlipAnimation":[32],"showSuccessAnimation":[32],"shouldMirrorVideo":[32],"sideAlignment":[32],"isDetectionPaused":[32],"isLoading":[32],"isModelPreloaded":[32],"isMaskReady":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"getStatus":[64],"preloadModel":[64],"skipBackCapture":[64]}]]]], options);
22
22
  });
23
23
 
24
24
  exports.setNonce = index.setNonce;
@@ -13,6 +13,7 @@ const JaakStamps = class {
13
13
  get el() { return index.getElement(this); }
14
14
  debug = false;
15
15
  alignmentTolerance = 10; // Tolerancia en píxeles para considerar un lado alineado (escalado para 320x320)
16
+ maskSize = 90; // Porcentaje del video que ocupará la máscara (default 90%)
16
17
  captureCompleted;
17
18
  isReady;
18
19
  isVideoActive = false;
@@ -68,6 +69,12 @@ const JaakStamps = class {
68
69
  console.log(...args);
69
70
  }
70
71
  }
72
+ validateMaskSize() {
73
+ if (this.maskSize < 50 || this.maskSize > 100) {
74
+ console.warn(`maskSize debe estar entre 50 y 100. Valor actual: ${this.maskSize}. Usando valor por defecto: 90`);
75
+ this.maskSize = 90;
76
+ }
77
+ }
71
78
  emitReadyEvent() {
72
79
  const isDocumentReady = !!window.ort && this.isModelPreloaded;
73
80
  this.isReady.emit(isDocumentReady);
@@ -81,6 +88,7 @@ const JaakStamps = class {
81
88
  return settings.facingMode === 'environment';
82
89
  }
83
90
  async componentDidLoad() {
91
+ this.validateMaskSize();
84
92
  if (!window.ort) {
85
93
  const script = document.createElement('script');
86
94
  script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js';
@@ -148,14 +156,15 @@ const JaakStamps = class {
148
156
  // Calculate what would be the max width if limited by video height
149
157
  const maxWidthByHeight = displayedVideoHeight * this.ID1_ASPECT_RATIO;
150
158
  let maskWidthInVideo, maskHeightInVideo;
159
+ const sizeRatio = this.maskSize / 100;
151
160
  if (maxWidthByHeight <= displayedVideoWidth) {
152
161
  // Video height is the limiting factor
153
- maskHeightInVideo = displayedVideoHeight * 0.9; // Use 90% of available height
162
+ maskHeightInVideo = displayedVideoHeight * sizeRatio;
154
163
  maskWidthInVideo = maskHeightInVideo * this.ID1_ASPECT_RATIO;
155
164
  }
156
165
  else {
157
166
  // Video width is the limiting factor
158
- maskWidthInVideo = displayedVideoWidth * 0.9; // Use 90% of available width
167
+ maskWidthInVideo = displayedVideoWidth * sizeRatio;
159
168
  maskHeightInVideo = maskWidthInVideo / this.ID1_ASPECT_RATIO;
160
169
  }
161
170
  // Convert to percentages of the container
@@ -322,27 +331,42 @@ const JaakStamps = class {
322
331
  const capabilities = videoTrack.getCapabilities();
323
332
  // Detener el stream temporal
324
333
  tempStream.getTracks().forEach(track => track.stop());
325
- // Construir restricciones con la resolución máxima
334
+ // Construir restricciones con resolución optimizada para tablets
326
335
  const constraints = {
327
336
  facingMode: "environment"
328
337
  };
329
338
  if (capabilities.width && capabilities.height) {
330
- constraints.width = { ideal: capabilities.width.max };
331
- constraints.height = { ideal: capabilities.height.max };
332
- this.debugLog('📐 Max resolution capabilities:', {
333
- width: capabilities.width.max,
334
- height: capabilities.height.max
339
+ // Limitar resolución máxima para tablets para evitar problemas de rendimiento
340
+ const maxWidth = Math.min(capabilities.width.max, 1920);
341
+ const maxHeight = Math.min(capabilities.height.max, 1080);
342
+ // Para tablets, usar resolución moderada en lugar de máxima
343
+ const isTablet = /iPad|Android/i.test(navigator.userAgent) && window.innerWidth >= 768;
344
+ if (isTablet) {
345
+ constraints.width = { ideal: Math.min(maxWidth, 1280) };
346
+ constraints.height = { ideal: Math.min(maxHeight, 720) };
347
+ }
348
+ else {
349
+ constraints.width = { ideal: maxWidth };
350
+ constraints.height = { ideal: maxHeight };
351
+ }
352
+ this.debugLog('📐 Resolution capabilities:', {
353
+ maxWidth: capabilities.width.max,
354
+ maxHeight: capabilities.height.max,
355
+ selectedWidth: constraints.width.ideal,
356
+ selectedHeight: constraints.height.ideal,
357
+ isTablet
335
358
  });
336
359
  }
337
360
  return constraints;
338
361
  }
339
362
  catch (err) {
340
363
  this.debugLog('⚠️ Could not get capabilities, using fallback');
341
- // Fallback para dispositivos que no soportan getCapabilities
364
+ // Fallback optimizado para tablets
365
+ const isTablet = /iPad|Android/i.test(navigator.userAgent) && window.innerWidth >= 768;
342
366
  return {
343
367
  facingMode: "environment",
344
- width: { ideal: 1920 },
345
- height: { ideal: 1080 }
368
+ width: { ideal: isTablet ? 1280 : 1920 },
369
+ height: { ideal: isTablet ? 720 : 1080 }
346
370
  };
347
371
  }
348
372
  }
@@ -578,14 +602,15 @@ const JaakStamps = class {
578
602
  // Calculate mask dimensions using the same logic as updateMaskDimensions
579
603
  const maxWidthByHeight = displayedVideoHeight * this.ID1_ASPECT_RATIO;
580
604
  let visualMaskWidth, visualMaskHeight;
605
+ const sizeRatio = this.maskSize / 100;
581
606
  if (maxWidthByHeight <= displayedVideoWidth) {
582
607
  // Video height is the limiting factor
583
- visualMaskHeight = displayedVideoHeight * 0.9;
608
+ visualMaskHeight = displayedVideoHeight * sizeRatio;
584
609
  visualMaskWidth = visualMaskHeight * this.ID1_ASPECT_RATIO;
585
610
  }
586
611
  else {
587
612
  // Video width is the limiting factor
588
- visualMaskWidth = displayedVideoWidth * 0.9;
613
+ visualMaskWidth = displayedVideoWidth * sizeRatio;
589
614
  visualMaskHeight = visualMaskWidth / this.ID1_ASPECT_RATIO;
590
615
  }
591
616
  // Now map these visual mask dimensions to the distorted model space
@@ -899,7 +924,7 @@ const JaakStamps = class {
899
924
  this.cleanup();
900
925
  }
901
926
  render() {
902
- return (index.h("div", { key: 'c95e9dee4b79561384fe1777b99a4cc4fa92bdbe', class: "detector-container" }, index.h("div", { key: 'a002fed79f5fd475a636818535a4a65324ec3fbf', class: "video-container" }, index.h("video", { key: '1a2a79193aac789c53b899da06e24bc4fe71891e', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: this.isVideoActive ? 'block' : 'none' } }), index.h("canvas", { key: '1771841686ff849a70d3b8e23034a44880494c7e', ref: el => this.canvasRef = el, class: this.shouldMirrorVideo ? 'mirror' : '' }), this.isMaskReady && (index.h("div", { key: '29563822f3ec6c0d00ef20fb2da346b2d9c24175', class: "overlay-mask" }, index.h("div", { key: 'e70ec55cfc25697e62981ffbfb5c78dc32821daa', class: "card-outline" }, index.h("div", { key: '1ae7dae4facd6971a3031cec4992f657192855da', class: "side side-top" }), index.h("div", { key: 'efec73ad8e754a279443a93f05c7e416476540c3', class: "side side-right" }), index.h("div", { key: '42dca6ffed2ac93bffd48877b3ef05e11aa16bac', class: "side side-bottom" }), index.h("div", { key: 'e872078e654987be4d02600b866f39767bff6c91', class: "side side-left" }), index.h("div", { key: '71dc7e353e6a11ddc6e300ddd6a96c483dc8e43d', class: "corner corner-tl" }), index.h("div", { key: 'e380c3c0526f8c6c5f6caefc2ea1feabc17b0b4a', class: "corner corner-tr" }), index.h("div", { key: 'de4720a6418ec86931c24a0542cffdbba8211b22', class: "corner corner-bl" }), index.h("div", { key: '338a487a89c9c4d1662428fdc73cdb355766149c', class: "corner corner-br" }), !this.showFlipAnimation && !this.showSuccessAnimation && (index.h("div", { key: '34190a47c348dd00d48467c4edfd80efaf0494cd', class: "guide-text" }, this.statusMessage))), this.captureStep === 'back' && !this.showFlipAnimation && !this.showSuccessAnimation && (index.h("button", { key: 'c585163a9db511b461d575594b2c8f5a79cbc1d2', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, "Saltar reverso")))), this.isCapturing && (index.h("div", { key: 'bc56a29c90d7177cad35c930ed54304bb20f700e', class: "capture-animation" })), this.showFlipAnimation && (index.h("div", { key: '1d636a6dde80ec90f6db7868a0abd163af8a8836', class: "flip-animation" }, index.h("div", { key: '95a78fbba1f340d8a56b24a9dda4a4c888cc2d44', class: "id-card-icon" }), index.h("div", { key: 'bb8e11d34b31cb0d28c2b1f2d02a1cc85b8dd1b3', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), this.showSuccessAnimation && (index.h("div", { key: 'ae2ce6604dccccb27995cbcc0ba0635c36125e9f', class: "success-animation" }, index.h("div", { key: '713cdfca5618225281106ed9da9c30c7f00d2f96', class: "check-icon" }), index.h("div", { key: '9ac255f66474d6a0d546c4f28dd1464dc1db199c', class: "success-text" }, "\u00A1Proceso completado!"))), this.isLoading && (index.h("div", { key: 'f3d08c1ba7596c70b3184b6023e4c330cadf395e', class: "loading-overlay" }, index.h("div", { key: '989ebafd27b84d6e86483569fb28a2df3dc587d5', class: "loading-spinner" }), index.h("div", { key: 'b14a356fde939b9bd52733bafaba762e5c5b2503', class: "loading-text" }, this.statusMessage))), index.h("div", { key: '3ff6690dc129f0981eb21de785c631c1221dbd5b', class: "watermark" }, index.h("img", { key: '67ad3a5d54c9dd1b36fae6f5857695b8dd1a2447', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
927
+ return (index.h("div", { key: 'd812c8d6a607b4f2889be8f84384156f67ca51e3', class: "detector-container" }, index.h("div", { key: '215b581f8ebafa9295133fe397f4dcaea952e2bc', class: "video-container" }, index.h("video", { key: '2ac492b3c535857d8ee681dc0bfb91e6de25a4d0', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: this.isVideoActive ? 'block' : 'none' } }), index.h("canvas", { key: 'e51c2e4a4751d89cc662a26eff3d8360fa199f4b', ref: el => this.canvasRef = el, class: this.shouldMirrorVideo ? 'mirror' : '' }), this.isMaskReady && (index.h("div", { key: '2e0bb7df390e6286a758098abf929ce23e0820f2', class: "overlay-mask" }, index.h("div", { key: '3a8c73cef589adcf98991719e0adc0791cf51e13', class: "card-outline" }, index.h("div", { key: '908bdd704ff89f8ba9f2f30da068d2d2074f43ed', class: "side side-top" }), index.h("div", { key: 'd27227f2e03905d288cb5509cb4f8b98a5ade59e', class: "side side-right" }), index.h("div", { key: '7bdce198e7ff2dc459768b001edd3c52b0cc28a2', class: "side side-bottom" }), index.h("div", { key: '9f3c97b8d154a7e48b36accac1eb7e33ee2b3184', class: "side side-left" }), index.h("div", { key: '2ec0bfd6308505d8780453a22aeb9b25108b8a14', class: "corner corner-tl" }), index.h("div", { key: 'd6d1589901a1a2cba38451b31126524ccc009a9b', class: "corner corner-tr" }), index.h("div", { key: 'db4ddc071c5b29d2d5912f7a880cdf8654c0db70', class: "corner corner-bl" }), index.h("div", { key: 'cf9cf5d60189e512a5f4bfc08e24d2bf9ed3a499', class: "corner corner-br" }), !this.showFlipAnimation && !this.showSuccessAnimation && (index.h("div", { key: '0412e6f6ecca1af59710256a27d9ceb7b11c5998', class: "guide-text" }, this.statusMessage))), this.captureStep === 'back' && !this.showFlipAnimation && !this.showSuccessAnimation && (index.h("button", { key: '26bc516d80fda38ea94926e574812362cd77a816', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, "Saltar reverso")))), this.isCapturing && (index.h("div", { key: '49c64155438f74dc3e0c5e981dac62844315180d', class: "capture-animation" })), this.showFlipAnimation && (index.h("div", { key: '738adb391c667de96a0c30750e75de43803ae613', class: "flip-animation" }, index.h("div", { key: '9df006a94a68b9d6e4dd351fb0b88cf78e62b2ec', class: "id-card-icon" }), index.h("div", { key: '3e1736f4aeb5b14a3edc4f52991fc34ff85169ad', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), this.showSuccessAnimation && (index.h("div", { key: 'dc46b715ef3e4fb98e5ee3f8449520db6bb68e53', class: "success-animation" }, index.h("div", { key: '641dda07b6545e9ca391e8c6149c7e29251d68ae', class: "check-icon" }), index.h("div", { key: 'ea53a4d547be89cc0e79d5b616a289405fea1e75', class: "success-text" }, "\u00A1Proceso completado!"))), this.isLoading && (index.h("div", { key: 'bf30969faeb9b6bee4099d2462b6abeee7eca1ff', class: "loading-overlay" }, index.h("div", { key: 'c32d185c1376975ac20640c532b0f4e593caf0c0', class: "loading-spinner" }), index.h("div", { key: '2c5a64af6abd379f247640498dafa01efe661c5c', class: "loading-text" }, this.statusMessage))), index.h("div", { key: 'd16122cf20d25e51dc7a3c91753f541f41c2747e', class: "watermark" }, index.h("img", { key: 'ce18db8a5997dfa6e2ebae47b9a61b665f8106bd', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
903
928
  }
904
929
  };
905
930
  JaakStamps.style = myComponentCss;