@daboss2003/liveness-web 1.0.0 → 1.0.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/dist/ui.js +21 -24
- package/package.json +1 -1
- package/src/ui.ts +21 -24
package/dist/ui.js
CHANGED
|
@@ -4,9 +4,10 @@ import { DEFAULT_SOUND_DATA_URLS } from "./default-sounds.generated";
|
|
|
4
4
|
const OVAL_W = 270;
|
|
5
5
|
const OVAL_H = 360;
|
|
6
6
|
const OVAL_TOP_PCT = 40;
|
|
7
|
-
//
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
// Progress stroke sits on the main oval: ellipse inset by half stroke so outer edge aligns with cutout
|
|
8
|
+
const STROKE_HALF = 1.75;
|
|
9
|
+
const RX = OVAL_W / 2 - STROKE_HALF;
|
|
10
|
+
const RY = OVAL_H / 2 - STROKE_HALF;
|
|
10
11
|
const ELLIPSE_PERIMETER = Math.PI * (3 * (RX + RY) - Math.sqrt((3 * RX + RY) * (RX + 3 * RY)));
|
|
11
12
|
/** Step label (from engine) → hint icon kind. Use this so the correct icon shows when steps are randomized. */
|
|
12
13
|
const STEP_LABEL_TO_HINT = {
|
|
@@ -40,6 +41,10 @@ function createStyles() {
|
|
|
40
41
|
display: flex;
|
|
41
42
|
flex-direction: column;
|
|
42
43
|
align-items: center;
|
|
44
|
+
--oval-w: min(72vmin, ${OVAL_W}px);
|
|
45
|
+
--oval-h: min(96vmin, ${OVAL_H}px);
|
|
46
|
+
/* Half-height of the visible oval for positioning (oval uses full w/h as radii) */
|
|
47
|
+
--oval-half-h: var(--oval-h);
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
/* ── Full-bleed video behind everything ─────────────────────────────── */
|
|
@@ -65,9 +70,9 @@ function createStyles() {
|
|
|
65
70
|
.lv-overlay {
|
|
66
71
|
position: absolute;
|
|
67
72
|
inset: 0;
|
|
68
|
-
/*
|
|
69
|
-
--ow:
|
|
70
|
-
--oh:
|
|
73
|
+
/* Ellipse size (radii): full oval w/h so cutout is large; ring is scaled to match */
|
|
74
|
+
--ow: var(--oval-w);
|
|
75
|
+
--oh: var(--oval-h);
|
|
71
76
|
background: var(--lv-dark);
|
|
72
77
|
-webkit-mask-image: radial-gradient(
|
|
73
78
|
ellipse var(--ow) var(--oh) at 50% ${OVAL_TOP_PCT}%,
|
|
@@ -85,22 +90,17 @@ function createStyles() {
|
|
|
85
90
|
background: rgba(180,0,0,0.55);
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
/* ── Oval SVG ring
|
|
93
|
+
/* ── Oval SVG ring (2× so progress sits on the main oval boundary) ───── */
|
|
89
94
|
.lv-ring-wrap {
|
|
90
95
|
position: absolute;
|
|
91
96
|
left: 50%;
|
|
92
97
|
top: ${OVAL_TOP_PCT}%;
|
|
93
98
|
transform: translate(-50%, -50%);
|
|
94
|
-
width:
|
|
95
|
-
height:
|
|
99
|
+
width: calc(2 * var(--oval-w));
|
|
100
|
+
height: calc(2 * var(--oval-h));
|
|
96
101
|
pointer-events: none;
|
|
97
102
|
}
|
|
98
103
|
.lv-ring-wrap svg { width: 100%; height: 100%; overflow: visible; }
|
|
99
|
-
.lv-ring-track {
|
|
100
|
-
fill: none;
|
|
101
|
-
stroke: rgba(255,255,255,0.15);
|
|
102
|
-
stroke-width: 3.5;
|
|
103
|
-
}
|
|
104
104
|
.lv-ring-progress {
|
|
105
105
|
fill: none;
|
|
106
106
|
stroke: var(--lv-green);
|
|
@@ -134,7 +134,7 @@ function createStyles() {
|
|
|
134
134
|
.lv-dots {
|
|
135
135
|
position: absolute;
|
|
136
136
|
z-index: 2;
|
|
137
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
137
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 20px);
|
|
138
138
|
left: 50%;
|
|
139
139
|
transform: translateX(-50%);
|
|
140
140
|
display: flex;
|
|
@@ -152,7 +152,7 @@ function createStyles() {
|
|
|
152
152
|
.lv-instruction {
|
|
153
153
|
position: absolute;
|
|
154
154
|
z-index: 2;
|
|
155
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
155
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 52px);
|
|
156
156
|
left: 50%;
|
|
157
157
|
transform: translateX(-50%);
|
|
158
158
|
white-space: nowrap;
|
|
@@ -168,7 +168,7 @@ function createStyles() {
|
|
|
168
168
|
.lv-pos-hint {
|
|
169
169
|
position: absolute;
|
|
170
170
|
z-index: 2;
|
|
171
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
171
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 84px);
|
|
172
172
|
left: 50%;
|
|
173
173
|
transform: translateX(-50%);
|
|
174
174
|
font-size: 13px;
|
|
@@ -278,9 +278,6 @@ export function startLivenessWithUI(options) {
|
|
|
278
278
|
ringWrap.className = "lv-ring-wrap";
|
|
279
279
|
ringWrap.innerHTML = `
|
|
280
280
|
<svg viewBox="0 0 ${OVAL_W} ${OVAL_H}">
|
|
281
|
-
<ellipse class="lv-ring-track"
|
|
282
|
-
cx="${rx}" cy="${ry}" rx="${RX}" ry="${RY}"
|
|
283
|
-
pathLength="${ELLIPSE_PERIMETER.toFixed(1)}"/>
|
|
284
281
|
<ellipse class="lv-ring-progress"
|
|
285
282
|
cx="${rx}" cy="${ry}" rx="${RX}" ry="${RY}"
|
|
286
283
|
pathLength="${ELLIPSE_PERIMETER.toFixed(1)}"
|
|
@@ -295,10 +292,10 @@ export function startLivenessWithUI(options) {
|
|
|
295
292
|
hintIcon.setAttribute("aria-hidden", "true");
|
|
296
293
|
root.appendChild(hintIcon);
|
|
297
294
|
// ── Header ─────────────────────────────────────────────────────────────────
|
|
298
|
-
const header = document.createElement("div");
|
|
299
|
-
header.className = "lv-header";
|
|
300
|
-
header.innerHTML = `<span class="lv-header-title">Face Verification</span>`;
|
|
301
|
-
root.appendChild(header);
|
|
295
|
+
// const header = document.createElement("div");
|
|
296
|
+
// header.className = "lv-header";
|
|
297
|
+
// header.innerHTML = `<span class="lv-header-title">Face Verification</span>`;
|
|
298
|
+
// root.appendChild(header);
|
|
302
299
|
// ── Step dots ──────────────────────────────────────────────────────────────
|
|
303
300
|
const dotsEl = document.createElement("div");
|
|
304
301
|
dotsEl.className = "lv-dots";
|
package/package.json
CHANGED
package/src/ui.ts
CHANGED
|
@@ -14,9 +14,10 @@ const OVAL_W = 270;
|
|
|
14
14
|
const OVAL_H = 360;
|
|
15
15
|
const OVAL_TOP_PCT = 40;
|
|
16
16
|
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
// Progress stroke sits on the main oval: ellipse inset by half stroke so outer edge aligns with cutout
|
|
18
|
+
const STROKE_HALF = 1.75;
|
|
19
|
+
const RX = OVAL_W / 2 - STROKE_HALF;
|
|
20
|
+
const RY = OVAL_H / 2 - STROKE_HALF;
|
|
20
21
|
const ELLIPSE_PERIMETER = Math.PI * (3 * (RX + RY) - Math.sqrt((3 * RX + RY) * (RX + 3 * RY)));
|
|
21
22
|
|
|
22
23
|
type HintKind = "left" | "blink" | "right" | "nod" | "mouth";
|
|
@@ -55,6 +56,10 @@ function createStyles(): HTMLStyleElement {
|
|
|
55
56
|
display: flex;
|
|
56
57
|
flex-direction: column;
|
|
57
58
|
align-items: center;
|
|
59
|
+
--oval-w: min(72vmin, ${OVAL_W}px);
|
|
60
|
+
--oval-h: min(96vmin, ${OVAL_H}px);
|
|
61
|
+
/* Half-height of the visible oval for positioning (oval uses full w/h as radii) */
|
|
62
|
+
--oval-half-h: var(--oval-h);
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/* ── Full-bleed video behind everything ─────────────────────────────── */
|
|
@@ -80,9 +85,9 @@ function createStyles(): HTMLStyleElement {
|
|
|
80
85
|
.lv-overlay {
|
|
81
86
|
position: absolute;
|
|
82
87
|
inset: 0;
|
|
83
|
-
/*
|
|
84
|
-
--ow:
|
|
85
|
-
--oh:
|
|
88
|
+
/* Ellipse size (radii): full oval w/h so cutout is large; ring is scaled to match */
|
|
89
|
+
--ow: var(--oval-w);
|
|
90
|
+
--oh: var(--oval-h);
|
|
86
91
|
background: var(--lv-dark);
|
|
87
92
|
-webkit-mask-image: radial-gradient(
|
|
88
93
|
ellipse var(--ow) var(--oh) at 50% ${OVAL_TOP_PCT}%,
|
|
@@ -100,22 +105,17 @@ function createStyles(): HTMLStyleElement {
|
|
|
100
105
|
background: rgba(180,0,0,0.55);
|
|
101
106
|
}
|
|
102
107
|
|
|
103
|
-
/* ── Oval SVG ring
|
|
108
|
+
/* ── Oval SVG ring (2× so progress sits on the main oval boundary) ───── */
|
|
104
109
|
.lv-ring-wrap {
|
|
105
110
|
position: absolute;
|
|
106
111
|
left: 50%;
|
|
107
112
|
top: ${OVAL_TOP_PCT}%;
|
|
108
113
|
transform: translate(-50%, -50%);
|
|
109
|
-
width:
|
|
110
|
-
height:
|
|
114
|
+
width: calc(2 * var(--oval-w));
|
|
115
|
+
height: calc(2 * var(--oval-h));
|
|
111
116
|
pointer-events: none;
|
|
112
117
|
}
|
|
113
118
|
.lv-ring-wrap svg { width: 100%; height: 100%; overflow: visible; }
|
|
114
|
-
.lv-ring-track {
|
|
115
|
-
fill: none;
|
|
116
|
-
stroke: rgba(255,255,255,0.15);
|
|
117
|
-
stroke-width: 3.5;
|
|
118
|
-
}
|
|
119
119
|
.lv-ring-progress {
|
|
120
120
|
fill: none;
|
|
121
121
|
stroke: var(--lv-green);
|
|
@@ -149,7 +149,7 @@ function createStyles(): HTMLStyleElement {
|
|
|
149
149
|
.lv-dots {
|
|
150
150
|
position: absolute;
|
|
151
151
|
z-index: 2;
|
|
152
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
152
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 20px);
|
|
153
153
|
left: 50%;
|
|
154
154
|
transform: translateX(-50%);
|
|
155
155
|
display: flex;
|
|
@@ -167,7 +167,7 @@ function createStyles(): HTMLStyleElement {
|
|
|
167
167
|
.lv-instruction {
|
|
168
168
|
position: absolute;
|
|
169
169
|
z-index: 2;
|
|
170
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
170
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 52px);
|
|
171
171
|
left: 50%;
|
|
172
172
|
transform: translateX(-50%);
|
|
173
173
|
white-space: nowrap;
|
|
@@ -183,7 +183,7 @@ function createStyles(): HTMLStyleElement {
|
|
|
183
183
|
.lv-pos-hint {
|
|
184
184
|
position: absolute;
|
|
185
185
|
z-index: 2;
|
|
186
|
-
top: calc(${OVAL_TOP_PCT}% +
|
|
186
|
+
top: calc(${OVAL_TOP_PCT}% + var(--oval-half-h) + 84px);
|
|
187
187
|
left: 50%;
|
|
188
188
|
transform: translateX(-50%);
|
|
189
189
|
font-size: 13px;
|
|
@@ -301,9 +301,6 @@ export function startLivenessWithUI(options: StartLivenessOptions): LivenessEngi
|
|
|
301
301
|
ringWrap.className = "lv-ring-wrap";
|
|
302
302
|
ringWrap.innerHTML = `
|
|
303
303
|
<svg viewBox="0 0 ${OVAL_W} ${OVAL_H}">
|
|
304
|
-
<ellipse class="lv-ring-track"
|
|
305
|
-
cx="${rx}" cy="${ry}" rx="${RX}" ry="${RY}"
|
|
306
|
-
pathLength="${ELLIPSE_PERIMETER.toFixed(1)}"/>
|
|
307
304
|
<ellipse class="lv-ring-progress"
|
|
308
305
|
cx="${rx}" cy="${ry}" rx="${RX}" ry="${RY}"
|
|
309
306
|
pathLength="${ELLIPSE_PERIMETER.toFixed(1)}"
|
|
@@ -320,10 +317,10 @@ export function startLivenessWithUI(options: StartLivenessOptions): LivenessEngi
|
|
|
320
317
|
root.appendChild(hintIcon);
|
|
321
318
|
|
|
322
319
|
// ── Header ─────────────────────────────────────────────────────────────────
|
|
323
|
-
const header = document.createElement("div");
|
|
324
|
-
header.className = "lv-header";
|
|
325
|
-
header.innerHTML = `<span class="lv-header-title">Face Verification</span>`;
|
|
326
|
-
root.appendChild(header);
|
|
320
|
+
// const header = document.createElement("div");
|
|
321
|
+
// header.className = "lv-header";
|
|
322
|
+
// header.innerHTML = `<span class="lv-header-title">Face Verification</span>`;
|
|
323
|
+
// root.appendChild(header);
|
|
327
324
|
|
|
328
325
|
// ── Step dots ──────────────────────────────────────────────────────────────
|
|
329
326
|
const dotsEl = document.createElement("div");
|