humanmap-vas 1.0.27 → 1.0.28
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/humanmap-vas-standalone.js +449 -72
- package/package.json +1 -1
- package/src/img/dark/head_left.svg +23 -0
- package/src/img/dark/head_right.svg +23 -0
- package/src/img/dark/neck_back.svg +19 -0
- package/src/img/dark/neck_front.svg +25 -0
- package/src/img/dark/neck_left.svg +24 -0
- package/src/img/dark/neck_right.svg +24 -0
- package/src/img/dark/torax_back.svg +33 -0
- package/src/img/dark/torax_front.svg +83 -0
- package/src/img/light/head_left.svg +19 -0
- package/src/img/light/head_right.svg +19 -0
- package/src/img/light/neck_back.svg +18 -0
- package/src/img/light/neck_front.svg +21 -0
- package/src/img/light/neck_left.svg +20 -0
- package/src/img/light/neck_right.svg +20 -0
- package/src/img/light/torax_back.svg +29 -0
- package/src/img/light/torax_front.svg +79 -0
- package/src/img/head_left.svg +0 -65
- package/src/img/head_right.svg +0 -66
- package/src/img/neck_back.svg +0 -44
- package/src/img/neck_front.svg +0 -44
- package/src/img/neck_left.svg +0 -47
- package/src/img/neck_right.svg +0 -47
- package/src/img/torax_back.svg +0 -103
- package/src/img/torax_front.svg +0 -281
|
@@ -1,47 +1,372 @@
|
|
|
1
1
|
// humanmap-vas-standalone.js — Cabeza + Cuello + Tórax (2 vistas: anterior/posterior)
|
|
2
2
|
(function(){
|
|
3
|
+
|
|
3
4
|
const STYLE = `
|
|
4
|
-
:host {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
font: 14px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, Noto Sans, sans-serif;
|
|
8
|
+
color: var(--hm-text-color, #111827);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* ==================== TEMAS ==================== */
|
|
12
|
+
:host([theme="light"]) {
|
|
13
|
+
--hm-border: 1px solid #e5e7eb;
|
|
14
|
+
--hm-border-radius: 14px;
|
|
15
|
+
--hm-background: #ffffff;
|
|
16
|
+
--hm-text-color: #111827;
|
|
17
|
+
--hm-toolbar-bg: #fafafa;
|
|
18
|
+
--hm-toolbar-border: #e5e7eb;
|
|
19
|
+
--hm-btn-bg: #ffffff;
|
|
20
|
+
--hm-btn-hover: #f3f4f6;
|
|
21
|
+
--hm-zone-fill: rgba(31,41,55,0);
|
|
22
|
+
--hm-zone-hover: rgba(31,41,55,0.22);
|
|
23
|
+
--hm-zone-selected: rgba(31,41,55,0.36);
|
|
24
|
+
--hm-label-color: #0a0a0a;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:host([theme="dark"]) {
|
|
28
|
+
--hm-border: 1px solid #374151;
|
|
29
|
+
--hm-border-radius: 14px;
|
|
30
|
+
--hm-background: #1f2937;
|
|
31
|
+
--hm-text-color: #f3f4f6;
|
|
32
|
+
--hm-toolbar-bg: #111827;
|
|
33
|
+
--hm-toolbar-border: #374151;
|
|
34
|
+
--hm-btn-bg: #374151;
|
|
35
|
+
--hm-btn-hover: #4b5563;
|
|
36
|
+
--hm-zone-fill: rgba(255,255,255,0);
|
|
37
|
+
--hm-zone-hover: rgba(255,255,255,0.1);
|
|
38
|
+
--hm-zone-selected: rgba(94, 101, 111, 0.9);
|
|
39
|
+
--hm-label-color: #d1d5db;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@media (prefers-color-scheme: dark) {
|
|
43
|
+
:host(:not([theme])) {
|
|
44
|
+
--hm-border: 1px solid #374151;
|
|
45
|
+
--hm-background: #1f2937;
|
|
46
|
+
--hm-text-color: #f3f4f6;
|
|
47
|
+
--hm-toolbar-bg: #111827;
|
|
48
|
+
--hm-toolbar-border: #374151;
|
|
49
|
+
--hm-btn-bg: #374151;
|
|
50
|
+
--hm-btn-hover: #4b5563;
|
|
51
|
+
--hm-zone-fill: rgba(255,255,255,0);
|
|
52
|
+
--hm-zone-hover: rgba(255,255,255,0.1);
|
|
53
|
+
--hm-zone-selected: rgba(94, 101, 111, 0.9);
|
|
54
|
+
--hm-label-color: #d1d5db;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ==================== ESTRUCTURA BASE ==================== */
|
|
59
|
+
.hm {
|
|
60
|
+
position: relative;
|
|
61
|
+
border: var(--hm-border);
|
|
62
|
+
border-radius: var(--hm-border-radius);
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
background: var(--hm-background);
|
|
65
|
+
color: var(--hm-text-color);
|
|
66
|
+
transition: background 0.4s ease, color 0.4s ease;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.hm-toolbar {
|
|
70
|
+
display: grid;
|
|
71
|
+
grid-template-columns: auto 1fr auto;
|
|
72
|
+
align-items: center;
|
|
73
|
+
gap: 8px;
|
|
74
|
+
padding: 8px 10px;
|
|
75
|
+
border-bottom: 1px solid var(--hm-toolbar-border);
|
|
76
|
+
background: var(--hm-toolbar-bg);
|
|
77
|
+
transition: background 0.4s ease, color 0.4s ease, border-color 0.4s ease;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.hm-center {
|
|
81
|
+
text-align: center;
|
|
82
|
+
font-weight: 600;
|
|
83
|
+
color: var(--hm-text-color);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.hm-toolbar select,
|
|
87
|
+
.hm-toolbar button {
|
|
88
|
+
appearance: none;
|
|
89
|
+
border: 1px solid var(--hm-toolbar-border);
|
|
90
|
+
border-radius: 10px;
|
|
91
|
+
padding: 6px 10px;
|
|
92
|
+
background: var(--hm-btn-bg);
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
font-weight: 500;
|
|
95
|
+
color: var(--hm-text-color);
|
|
96
|
+
transition: background 0.4s ease, color 0.4s ease, border-color 0.4s ease;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.hm-toolbar button:hover,
|
|
100
|
+
.hm-toolbar select:hover {
|
|
101
|
+
background: var(--hm-btn-hover);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.hm-toolbar .menu-btn {
|
|
105
|
+
font-size: 18px;
|
|
106
|
+
width: 36px;
|
|
107
|
+
height: 32px;
|
|
108
|
+
line-height: 1;
|
|
109
|
+
text-align: center;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.hm-dropdown {
|
|
113
|
+
position: absolute;
|
|
114
|
+
right: 10px;
|
|
115
|
+
top: 46px;
|
|
116
|
+
background: var(--hm-background);
|
|
117
|
+
border: 1px solid var(--hm-toolbar-border);
|
|
118
|
+
border-radius: 8px;
|
|
119
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
|
120
|
+
display: none;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
z-index: 9999;
|
|
123
|
+
}
|
|
124
|
+
|
|
12
125
|
.hm-dropdown.active { display: flex; }
|
|
13
|
-
|
|
14
|
-
.hm-dropdown button
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
126
|
+
|
|
127
|
+
.hm-dropdown button {
|
|
128
|
+
background: none;
|
|
129
|
+
border: none;
|
|
130
|
+
padding: 8px 16px;
|
|
131
|
+
text-align: left;
|
|
132
|
+
font-size: 14px;
|
|
133
|
+
cursor: pointer;
|
|
134
|
+
transition: background 0.15s;
|
|
135
|
+
color: var(--hm-text-color);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.hm-dropdown button:hover {
|
|
139
|
+
background: var(--hm-btn-hover);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ==================== LIENZO ==================== */
|
|
143
|
+
.hm-canvas-wrap {
|
|
144
|
+
position: relative;
|
|
145
|
+
width: var(--hm-width, 100%);
|
|
146
|
+
height: var(--hm-height, 500px);
|
|
147
|
+
aspect-ratio: 2 / 3;
|
|
148
|
+
background: var(--hm-background);
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
transition: background 0.4s ease, color 0.4s ease;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
svg.hm-svg {
|
|
157
|
+
position: absolute;
|
|
158
|
+
inset: 0;
|
|
159
|
+
width: 100%;
|
|
160
|
+
height: 100%;
|
|
161
|
+
margin: auto;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* ==================== ZONAS ==================== */
|
|
165
|
+
.zone {
|
|
166
|
+
fill: var(--hm-zone-fill);
|
|
167
|
+
transition: fill 0.4s ease;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.zone:hover { fill: var(--hm-zone-hover); }
|
|
172
|
+
|
|
19
173
|
.zone.readonly { cursor: default; }
|
|
20
|
-
|
|
21
|
-
.zone.selected { fill:
|
|
22
|
-
|
|
23
|
-
.
|
|
24
|
-
|
|
25
|
-
|
|
174
|
+
|
|
175
|
+
.zone.readonly:not(.selected):hover { fill: var(--hm-zone-fill); }
|
|
176
|
+
|
|
177
|
+
.zone.selected { fill: var(--hm-zone-selected); }
|
|
178
|
+
|
|
179
|
+
/* ==================== LABELS ==================== */
|
|
180
|
+
.hm-all-label {
|
|
181
|
+
fill: var(--hm-text-color);
|
|
182
|
+
font-weight: 700;
|
|
183
|
+
font-size: 36px;
|
|
184
|
+
text-anchor: middle;
|
|
185
|
+
dominant-baseline: middle;
|
|
186
|
+
transition: fill 0.4s ease;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.label {
|
|
190
|
+
fill: var(--hm-label-color);
|
|
191
|
+
font-size: 36px;
|
|
192
|
+
pointer-events: none;
|
|
193
|
+
user-select: none;
|
|
194
|
+
text-anchor: middle;
|
|
195
|
+
dominant-baseline: middle;
|
|
196
|
+
font-weight: 800;
|
|
197
|
+
transition: fill 0.4s ease;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* ==================== BOTONES FLOTANTES / MODAL ==================== */
|
|
201
|
+
.hm-print-btn {
|
|
202
|
+
position: absolute;
|
|
203
|
+
top: 10px;
|
|
204
|
+
right: 10px;
|
|
205
|
+
background: rgba(17,24,39,0.85);
|
|
206
|
+
color: #f9fafb;
|
|
207
|
+
border: none;
|
|
208
|
+
border-radius: 8px;
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
font-size: 18px;
|
|
211
|
+
padding: 6px 10px;
|
|
212
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
|
213
|
+
transition: opacity 0.25s ease, background 0.2s ease;
|
|
214
|
+
opacity: 0;
|
|
215
|
+
pointer-events: none;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.hm-canvas-wrap:hover .hm-print-btn {
|
|
219
|
+
opacity: 1;
|
|
220
|
+
pointer-events: auto;
|
|
221
|
+
}
|
|
222
|
+
|
|
26
223
|
.hm-print-btn:hover { background: rgba(37,99,235,0.9); }
|
|
27
|
-
|
|
224
|
+
|
|
225
|
+
.hm-zoom-float {
|
|
226
|
+
position: absolute;
|
|
227
|
+
bottom: 10px;
|
|
228
|
+
right: 10px;
|
|
229
|
+
background: rgba(31,41,55,0.85);
|
|
230
|
+
color: #fff;
|
|
231
|
+
border: none;
|
|
232
|
+
border-radius: 50%;
|
|
233
|
+
width: 42px;
|
|
234
|
+
height: 42px;
|
|
235
|
+
font-size: 20px;
|
|
236
|
+
line-height: 1;
|
|
237
|
+
cursor: pointer;
|
|
238
|
+
box-shadow: 0 3px 8px rgba(0,0,0,0.3);
|
|
239
|
+
transition: transform 0.2s ease, background 0.2s ease;
|
|
240
|
+
z-index: 20;
|
|
241
|
+
}
|
|
242
|
+
|
|
28
243
|
.hm-zoom-float:hover { transform: scale(1.08); background: rgba(31,41,55,1); }
|
|
29
|
-
|
|
244
|
+
|
|
245
|
+
/* ==================== MODAL DE ZOOM ==================== */
|
|
246
|
+
.hm-zoom-modal {
|
|
247
|
+
position: fixed;
|
|
248
|
+
inset: 0;
|
|
249
|
+
background: rgba(0, 0, 0, 0.85);
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: center;
|
|
252
|
+
justify-content: center;
|
|
253
|
+
z-index: 9999;
|
|
254
|
+
opacity: 0;
|
|
255
|
+
pointer-events: none;
|
|
256
|
+
transition: opacity 0.3s ease;
|
|
257
|
+
}
|
|
258
|
+
|
|
30
259
|
.hm-zoom-modal.active { opacity: 1; pointer-events: auto; }
|
|
31
|
-
|
|
32
|
-
.hm-zoom-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
260
|
+
|
|
261
|
+
.hm-zoom-inner {
|
|
262
|
+
position: relative;
|
|
263
|
+
width: 95vw;
|
|
264
|
+
height: 90vh;
|
|
265
|
+
background: var(--hm-background);
|
|
266
|
+
border-radius: 10px;
|
|
267
|
+
overflow: hidden;
|
|
268
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
|
|
269
|
+
display: flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
justify-content: center;
|
|
272
|
+
transform: scale(0.95);
|
|
273
|
+
opacity: 0;
|
|
274
|
+
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
275
|
+
}
|
|
276
|
+
|
|
37
277
|
.hm-zoom-modal.active .hm-zoom-inner { transform: scale(1); opacity: 1; }
|
|
38
|
-
|
|
39
|
-
.hm-
|
|
278
|
+
|
|
279
|
+
.hm-zoom-content {
|
|
280
|
+
position: relative;
|
|
281
|
+
width: 100%;
|
|
282
|
+
height: 100%;
|
|
283
|
+
display: flex;
|
|
284
|
+
align-items: center;
|
|
285
|
+
justify-content: center;
|
|
286
|
+
background: var(--hm-background);
|
|
287
|
+
overflow: auto;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.hm-zoom-close {
|
|
291
|
+
position: absolute;
|
|
292
|
+
top: 12px;
|
|
293
|
+
right: 12px;
|
|
294
|
+
border: none;
|
|
295
|
+
background: rgba(0, 0, 0, 0.75);
|
|
296
|
+
color: #fff;
|
|
297
|
+
border-radius: 50%;
|
|
298
|
+
width: 42px;
|
|
299
|
+
height: 42px;
|
|
300
|
+
font-size: 24px;
|
|
301
|
+
cursor: pointer;
|
|
302
|
+
z-index: 10000;
|
|
303
|
+
line-height: 1;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.hm-zoom-close:hover { background: rgba(0, 0, 0, 0.9); }
|
|
307
|
+
|
|
308
|
+
.hm-zoom-modal svg {
|
|
309
|
+
width: auto;
|
|
310
|
+
height: auto;
|
|
311
|
+
max-width: 100%;
|
|
312
|
+
max-height: 100%;
|
|
313
|
+
display: block;
|
|
314
|
+
transition: transform 0.25s ease;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.hm-zoom-hint {
|
|
318
|
+
position: absolute;
|
|
319
|
+
bottom: 10px;
|
|
320
|
+
right: 20px;
|
|
321
|
+
color: rgba(0,0,0,0.4);
|
|
322
|
+
font-size: 14px;
|
|
323
|
+
background: rgba(255,255,255,0.7);
|
|
324
|
+
padding: 4px 10px;
|
|
325
|
+
border-radius: 6px;
|
|
326
|
+
pointer-events: none;
|
|
327
|
+
user-select: none;
|
|
328
|
+
transition: opacity 1s ease 2s;
|
|
329
|
+
opacity: 1;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* ==================== LOADER ==================== */
|
|
333
|
+
.hm-loader {
|
|
334
|
+
position: absolute;
|
|
335
|
+
inset: 0;
|
|
336
|
+
display: flex;
|
|
337
|
+
flex-direction: column;
|
|
338
|
+
align-items: center;
|
|
339
|
+
justify-content: center;
|
|
340
|
+
background: rgba(255, 255, 255, 0.7);
|
|
341
|
+
backdrop-filter: blur(2px);
|
|
342
|
+
z-index: 1000;
|
|
343
|
+
opacity: 0;
|
|
344
|
+
transition: opacity 0.25s ease;
|
|
345
|
+
pointer-events: none;
|
|
346
|
+
}
|
|
347
|
+
|
|
40
348
|
.hm-loader.active { opacity: 1; pointer-events: all; }
|
|
41
|
-
.hm-loader::before { content: ''; width: 42px; height: 42px; border: 3px solid rgba(31,41,55,0.2); border-top-color: #3b82f6; border-radius: 50%; animation: hm-spin 1s linear infinite; }
|
|
42
|
-
.hm-loader span { margin-top: 10px; font-size: 14px; color: #1f2937; font-weight: 500; letter-spacing: 0.3px; opacity: 0.85; }
|
|
43
|
-
@keyframes hm-spin { to { transform: rotate(360deg); } }
|
|
44
349
|
|
|
350
|
+
.hm-loader::before {
|
|
351
|
+
content: '';
|
|
352
|
+
width: 42px;
|
|
353
|
+
height: 42px;
|
|
354
|
+
border: 3px solid rgba(31,41,55,0.2);
|
|
355
|
+
border-top-color: #3b82f6;
|
|
356
|
+
border-radius: 50%;
|
|
357
|
+
animation: hm-spin 1s linear infinite;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.hm-loader span {
|
|
361
|
+
margin-top: 10px;
|
|
362
|
+
font-size: 14px;
|
|
363
|
+
color: var(--hm-text-color);
|
|
364
|
+
font-weight: 500;
|
|
365
|
+
letter-spacing: 0.3px;
|
|
366
|
+
opacity: 0.85;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@keyframes hm-spin { to { transform: rotate(360deg); } }
|
|
45
370
|
`;
|
|
46
371
|
|
|
47
372
|
// ───────────────────────────────────────────────────────────────────────────
|
|
@@ -144,6 +469,8 @@
|
|
|
144
469
|
constructor(){
|
|
145
470
|
super();
|
|
146
471
|
this.attachShadow({mode:'open'});
|
|
472
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
473
|
+
this._theme = this.getAttribute('theme') || (prefersDark ? 'dark' : 'light');
|
|
147
474
|
this._view=this.getAttribute('view') || 'head_right';
|
|
148
475
|
this._zones=ZONES;
|
|
149
476
|
this._selected=new Set();
|
|
@@ -181,6 +508,8 @@
|
|
|
181
508
|
thorax_front: this._imgRoot + 'torax_front.svg',
|
|
182
509
|
thorax_back: this._imgRoot + 'torax_back.svg'
|
|
183
510
|
};
|
|
511
|
+
|
|
512
|
+
this._applyTheme();
|
|
184
513
|
}
|
|
185
514
|
|
|
186
515
|
_upgradeProperty(prop) {
|
|
@@ -198,6 +527,22 @@
|
|
|
198
527
|
this._imgRoot = this.getAttribute('img-root') || this._imgRoot;
|
|
199
528
|
this._syncUrl = this.getAttribute('sync-url') || null;
|
|
200
529
|
|
|
530
|
+
if (!this.hasAttribute('theme')) {
|
|
531
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
532
|
+
this.setAttribute('theme', prefersDark ? 'dark' : 'light');
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
this._applyTheme();
|
|
536
|
+
|
|
537
|
+
// --- 3️⃣ Escuchar cambios del sistema (modo oscuro/claro del SO) ---
|
|
538
|
+
this._mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
539
|
+
this._mediaListener = e => {
|
|
540
|
+
if (!this.hasAttribute('theme')) {
|
|
541
|
+
this.setAttribute('theme', e.matches ? 'dark' : 'light');
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
this._mediaQuery.addEventListener('change', this._mediaListener);
|
|
545
|
+
|
|
201
546
|
this._renderShell();
|
|
202
547
|
this._renderCanvas();
|
|
203
548
|
|
|
@@ -224,11 +569,23 @@
|
|
|
224
569
|
}
|
|
225
570
|
}
|
|
226
571
|
|
|
227
|
-
|
|
572
|
+
disconnectedCallback() {
|
|
573
|
+
if (this._mediaQuery && this._mediaListener) {
|
|
574
|
+
this._mediaQuery.removeEventListener('change', this._mediaListener);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
static get observedAttributes() { return ['view', 'img-root', 'read-only', 'sync-url', 'theme']; }
|
|
228
579
|
|
|
229
580
|
attributeChangedCallback (name, oldValue, newValue) {
|
|
230
581
|
if (oldValue === newValue) return;
|
|
231
582
|
|
|
583
|
+
if (name === 'theme' && oldValue !== newValue) {
|
|
584
|
+
this._theme = newValue === 'dark' ? 'dark' : 'light';
|
|
585
|
+
this._applyTheme();
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
|
|
232
589
|
if (name === 'view') {
|
|
233
590
|
this._view = newValue;
|
|
234
591
|
if (this._root) this._renderCanvas();
|
|
@@ -340,6 +697,32 @@
|
|
|
340
697
|
});
|
|
341
698
|
}
|
|
342
699
|
|
|
700
|
+
_applyTheme() {
|
|
701
|
+
const base = this._imgRoot.endsWith('/') ? this._imgRoot : this._imgRoot + '/';
|
|
702
|
+
const basePath = base + (this._theme === 'dark' ? 'dark/' : 'light/');
|
|
703
|
+
|
|
704
|
+
this._bg = {
|
|
705
|
+
head_right: basePath + 'head_right.svg',
|
|
706
|
+
head_left: basePath + 'head_left.svg',
|
|
707
|
+
neck_right: basePath + 'neck_right.svg',
|
|
708
|
+
neck_left: basePath + 'neck_left.svg',
|
|
709
|
+
thorax_front: basePath + 'torax_front.svg',
|
|
710
|
+
thorax_back: basePath + 'torax_back.svg'
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// Si tienes tus imágenes organizadas por vistas
|
|
714
|
+
/*Object.keys(this._bg).forEach(k => {
|
|
715
|
+
this._bg[k] = `${basePath}${k}.svg`;
|
|
716
|
+
});*/
|
|
717
|
+
|
|
718
|
+
this._root?.classList.toggle('theme-dark', this._theme === 'dark');
|
|
719
|
+
this._root?.classList.toggle('theme-light', this._theme === 'light');
|
|
720
|
+
|
|
721
|
+
if (this._root) {
|
|
722
|
+
this._renderCanvas();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
343
726
|
get syncUrl() { return this._syncUrl; }
|
|
344
727
|
|
|
345
728
|
set syncUrl(url) {
|
|
@@ -386,8 +769,12 @@
|
|
|
386
769
|
<select id="picker">${opts}</select>
|
|
387
770
|
<button id="menu" class="menu-btn" title="Más opciones">⋮</button>
|
|
388
771
|
<div id="dropdown" class="hm-dropdown">
|
|
389
|
-
<button
|
|
390
|
-
<button
|
|
772
|
+
<button data-action="export">📤 Exportar zonas (.json)</button>
|
|
773
|
+
<button data-action="import">📥 Importar zonas (.json)</button>
|
|
774
|
+
<hr style="margin:4px 0;">
|
|
775
|
+
<div style="padding: 4px 16px; font-weight:600;">Tema</div>
|
|
776
|
+
<button data-action="theme-light">🌞 Claro</button>
|
|
777
|
+
<button data-action="theme-dark">🌙 Oscuro</button>
|
|
391
778
|
<input id="fileInput" type="file" accept=".json" style="display:none;">
|
|
392
779
|
</div>
|
|
393
780
|
</div>
|
|
@@ -444,8 +831,6 @@
|
|
|
444
831
|
// Dropdown menú
|
|
445
832
|
this._els.menu = this.shadowRoot.getElementById('menu');
|
|
446
833
|
this._els.dropdown = this.shadowRoot.getElementById('dropdown');
|
|
447
|
-
this._els.exportBtn = this.shadowRoot.getElementById('export');
|
|
448
|
-
this._els.importBtn = this.shadowRoot.getElementById('import');
|
|
449
834
|
this._els.fileInput = this.shadowRoot.getElementById('fileInput');
|
|
450
835
|
|
|
451
836
|
// Mostrar/ocultar menú
|
|
@@ -461,25 +846,27 @@
|
|
|
461
846
|
}
|
|
462
847
|
});
|
|
463
848
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
849
|
+
this._els.dropdown.addEventListener('click', e => {
|
|
850
|
+
const action = e.target.dataset.action;
|
|
851
|
+
if (!action) return;
|
|
852
|
+
|
|
853
|
+
switch (action) {
|
|
854
|
+
case 'export':
|
|
855
|
+
this.exportSelectedZones();
|
|
856
|
+
break;
|
|
857
|
+
case 'import':
|
|
858
|
+
this.importZonesFromFile();
|
|
859
|
+
break;
|
|
860
|
+
case 'theme-light':
|
|
861
|
+
this.setAttribute('theme', 'light');
|
|
862
|
+
break;
|
|
863
|
+
case 'theme-dark':
|
|
864
|
+
this.setAttribute('theme', 'dark');
|
|
865
|
+
break;
|
|
866
|
+
}
|
|
867
|
+
|
|
480
868
|
this._els.dropdown.classList.remove('active');
|
|
481
|
-
|
|
482
|
-
});
|
|
869
|
+
});
|
|
483
870
|
|
|
484
871
|
this._els.fileInput.addEventListener('change', e => {
|
|
485
872
|
const file = e.target.files[0];
|
|
@@ -661,12 +1048,13 @@
|
|
|
661
1048
|
t.textContent = z.code;
|
|
662
1049
|
t.setAttribute('x', (x + w / 2) * layout.vb[2]);
|
|
663
1050
|
t.setAttribute('y', (y + h / 2) * layout.vb[3]);
|
|
664
|
-
t.
|
|
1051
|
+
t.classList.add('label');
|
|
665
1052
|
t.setAttribute('font-size', '32');
|
|
666
1053
|
t.setAttribute('font-weight', '700');
|
|
667
1054
|
t.setAttribute('text-anchor', 'middle');
|
|
668
1055
|
t.setAttribute('dominant-baseline', 'middle');
|
|
669
1056
|
t.setAttribute('pointer-events', 'none');
|
|
1057
|
+
t.setAttribute('class','label');
|
|
670
1058
|
gZones.appendChild(t);
|
|
671
1059
|
});
|
|
672
1060
|
|
|
@@ -679,7 +1067,7 @@
|
|
|
679
1067
|
t.textContent = v.label;
|
|
680
1068
|
t.setAttribute('x', layout.vb[2] / 2);
|
|
681
1069
|
t.setAttribute('y', 80);
|
|
682
|
-
t.
|
|
1070
|
+
t.classList.add('hm-all-label');
|
|
683
1071
|
g.appendChild(t);
|
|
684
1072
|
|
|
685
1073
|
|
|
@@ -726,7 +1114,6 @@
|
|
|
726
1114
|
});
|
|
727
1115
|
}
|
|
728
1116
|
|
|
729
|
-
|
|
730
1117
|
g.appendChild(rect);
|
|
731
1118
|
|
|
732
1119
|
const t=document.createElementNS('http://www.w3.org/2000/svg','text');
|
|
@@ -864,19 +1251,9 @@
|
|
|
864
1251
|
// Ajustar estilos dentro del SVG
|
|
865
1252
|
const style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
|
|
866
1253
|
style.textContent = `
|
|
867
|
-
.zone {
|
|
868
|
-
.
|
|
869
|
-
.label {
|
|
870
|
-
text-anchor: middle; dominant-baseline: middle;
|
|
871
|
-
pointer-events: none; user-select: none; }
|
|
872
|
-
.hm-all-label {
|
|
873
|
-
font-family: system-ui, sans-serif;
|
|
874
|
-
font-size: 48px;
|
|
875
|
-
font-weight: 800;
|
|
876
|
-
fill: #111827;
|
|
877
|
-
text-anchor: middle;
|
|
878
|
-
dominant-baseline: middle;
|
|
879
|
-
}
|
|
1254
|
+
.zone { cursor: default; transition: fill 120ms ease; }
|
|
1255
|
+
.label { font-size: 42px; font-weight: 800; text-anchor: middle; dominant-baseline: middle; pointer-events: none; user-select: none; }
|
|
1256
|
+
.hm-all-label { font-family: system-ui, sans-serif; font-size: 48px; font-weight: 800; text-anchor: middle; dominant-baseline: middle; }
|
|
880
1257
|
`;
|
|
881
1258
|
clone.insertBefore(style, clone.firstChild);
|
|
882
1259
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "humanmap-vas",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"description": "**HumanMap VAS** es una librería web que permite graficar el cuerpo humano con vistas anatómicas interactivas para identificar zonas según el sistema VAS. Desarrollada como *Web Component standalone*, puede integrarse fácilmente en proyectos **HTML**, **Django**, o **Vue.js**.",
|
|
5
5
|
"main": "humanmap-vas-standalone.js",
|
|
6
6
|
"files": [
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 595.28 841.89">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #7c7c7c;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-1, .cls-2 {
|
|
10
|
+
stroke-width: 0px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cls-2 {
|
|
14
|
+
fill: #828282;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</defs>
|
|
18
|
+
<path class="cls-1" d="m498.88,734.49c-25.62-42.22-37.2-92.98-31.73-142.12,0,0,.7-5.68.7-5.68l1.09-5.62c.27-1.75.78-3.92,1.25-5.59,0,0,1.5-5.54,1.5-5.54.75-2.63,1.92-5.52,2.77-8.15.67-1.64,2.56-6.2,3.31-7.94,0,0,2.52-5.15,2.52-5.15,5.09-10.2,11.29-19.88,17.25-29.56,10.03-16.06,19.25-32.57,26.57-50.01,29.7-69.45,48.07-150.02,14.87-221.57-37.95-81.21-126.25-134.06-214.82-137.49-71.03-2.81-144.36,24.49-192.23,77.81-1.92,2.09-5.52,6.36-7.28,8.57-7.14,8.68-12.45,18.54-17.36,28.66-15.91,34.28-30.72,81.44-30.69,119.33.06,3.7.44,7.37,1.19,10.88,1.31,6.95,6.1,12.95,9.28,20.22,3.34,7.26,4.08,15.63,2.75,23.49-1.34,7.8-4.84,14.87-8.42,21.76-3.61,6.76-7.47,13.31-11.35,19.84-6.79,11.26-16.67,27.96-23.89,38.82-3.85,6.05-8.17,12.46-7.69,19.78.51,4.92,2,10.59,6.93,12.7,8.6,3.71,19.82,1.37,27.34,8.15,3.13,2.81,5.06,6.76,5.71,10.86,1.32,7.95-4.94,14.9-6.38,22.07-2.03,11.67,10.83,18.04,20.29,20.91,0,0,3.28,1.03,3.28,1.03l-3.05,1.57c-2.48,1.28-4.89,2.63-6.8,4.4-2.84,2.56-4.32,6.51-3.61,10.25,1,3.97,4.23,6.53,7.07,9.53,9.06,8.61,13.78,19.65,9.37,31.92-1.75,5.38-3.7,10.58-3.98,16.22-.2,5.48.86,11.04,3.02,16.17,6.39,15.16,20.16,28.43,36.76,31.16,22.06,2.98,36.4-17.72,65.88-11.9,16.97,3.16,31.41,13.99,42.82,26.46-15.11-16.39-36.76-29.52-59.78-26.11-11.37,1.44-21.32,7.34-32.05,11.03-11.17,4.07-23.23,2.34-33.21-4.06-14.48-9.07-25.92-25.25-25.6-42.84.2-5.8,2.19-11.39,3.9-16.8,2.82-8.18,1.51-16.2-3.53-23.17-3.6-5.36-9.43-8.85-12.53-14.74-2.37-5.09-.49-11.46,3.56-15.15,2.26-2.11,4.86-3.55,7.4-4.89l.23,2.61c-3.69-1.14-7.34-2.53-10.79-4.43-7.1-3.72-13.46-11.13-11.67-19.73,1.61-8.66,9.27-15.87,5.15-24.77-4.92-12.21-20.27-8.1-30.29-12.64-6.06-2.6-8.5-9.46-9.01-15.58-.64-8.23,3.99-15.47,8.12-22.01,2.05-3.21,4.1-6.38,6.09-9.59,9.1-15.15,20.29-33.49,28.6-49.01,7.09-13,11.88-27.5,5.38-41.57-1.48-3.32-3.37-6.51-5.22-9.91-6.17-10.3-6.19-22.79-5.49-34.39,3.38-38.1,14.65-75.25,30.55-109.95,5.71-12.15,12.67-23.9,21.55-34.08,48.7-57.26,125.39-86.91,199.84-83.8,90.46,3.58,180.01,57.56,218.52,140.61,33.37,72.59,14.44,154.37-16.11,224.49-7.47,17.51-16.92,34.18-27.08,50.2-6.02,9.64-12.27,19.11-17.44,29.22,0,0-2.54,5.05-2.54,5.05-.76,1.88-2.66,5.93-3.34,7.78-.91,2.53-2,5.43-2.81,7.98,0,0-1.53,5.43-1.53,5.43-.94,3.32-1.72,7.67-2.42,11.03,0,0-.74,5.61-.74,5.61-5.93,48.88,5.15,99.48,30.02,141.91h0Z"/>
|
|
19
|
+
<path class="cls-1" d="m286.36,445.9c-7.25-14.31-9.02-31.29-4.37-46.71,5.55-20.62,20.25-38.87,43.73-35.1,16.28,2.98,31.07,14.96,36.71,30.62,5.32,15.65,2.82,32.28.85,48.28-1.88,12-5.15,23.95-10.9,34.71-3.5,6.17-9.24,14.08-13.15,20.03-3.37,4.93-6.72,9.91-10.42,14.64-1.91,2.4-4.02,4.94-6.63,6.75-6.61,4.08-14.53,7.07-22.38,5.99-17.13-3.38-17.68-27.02-16.34-40.72.7-7.93,2.31-15.72,3.94-23.49-2.14,15.39-4.62,31.68-.42,46.82,2.33,8.17,8.11,15.5,17.37,14.25,2.79-.33,5.51-1.04,8.14-2.09,3.4-1.41,6.88-2.96,9.48-5.62,5.12-5.58,9.3-12.6,13.62-18.95,4.86-7.79,11.61-16.64,15.11-25.05,5.45-12.56,7.85-26.08,9.05-39.67.8-7.72,1.38-15.52.53-23.2-1.32-15.67-10.72-28.47-24.64-35.51-30.44-14.85-49.63,11.71-54.03,39.4-1.68,11.69.2,23.71,4.76,34.64h0Z"/>
|
|
20
|
+
<path class="cls-1" d="m302.02,440.62c-3.29.99-5.58,3.41-3.35,6.66,1.74,2.76,3.57,5.82,4.06,9.2,1.06,6.85-1.79,13.87-5.8,19.2-.4.6-.57,1.11-.53,1.21.4,1.11,2.11,1.96,3.45,2.08,2.78.31,3.43-1.89,4.67-4.34,1.8-4.16,5.28-8.35,9.97-9.52,2.33-.67,5.25-.11,7.18-.74,2.47-.68,4.88-2.4,6.7-4.58,3.7-4.42,5.56-10.44,4.3-16.19-2.01-8.87-8.48-16.86-16.86-20.57-2.96-1.46-5.82-3.21-8.44-5.18-2.55-2.01-5.48-3.61-7.69-6.02,2.57,2.02,5.67,3.16,8.45,4.85,2.82,1.59,5.66,2.99,8.67,4.09,3.09,1.09,6.33,2.72,8.89,4.87,11.48,9.17,16.58,25.05,6.43,37.27-3.44,4.34-8.92,7.27-14.58,6.75-4.36-.04-7,3.41-8.81,7.07-1.05,2.18-3.09,5.81-6.17,6.39-4.67,1.38-12.24-2.78-9.64-8.36,1.04-1.92,2.64-3.44,3.64-5.12,2.39-3.83,4.03-8.37,3.75-12.9-.09-1.5-.4-3-.94-4.45-.74-2.28-2.36-4.43-2.61-6.96-.21-2.91,2.91-4.44,5.27-4.73h0Z"/>
|
|
21
|
+
<path class="cls-1" d="m313.51,437.94c-6.12-5.61-10.75-12.92-13.51-20.74-1.47-3.88-2.74-8-3-12.38-.99-14.4,10.88-24.58,23.98-27.63,6.61-1.63,14.52.41,19.22,5.57,4.42,4.83,7.55,10.3,10.66,15.98,8.55,16.48,6,32.8-.04,49.56-4.27,11.72-10.92,22.64-19.31,31.77,4.73-6.76,8.85-13.88,12.05-21.37,4.63-11.09,7.94-23.1,8.43-35.11.1-7.88-1.86-15.65-5.48-22.64-1.82-3.49-4.14-6.97-6.32-10.24-2.11-3.1-4.44-6.08-7.77-7.72-9.37-4.72-24.11,2.41-29.21,10.89-4.24,6.78-3.26,15.09-.89,22.52,2.12,7.93,5.92,15.21,11.19,21.52h0Z"/>
|
|
22
|
+
<path class="cls-2" d="m298.64,402.89c2.76,1.31,5.24,2.98,7.96,4.26,4.55,2.01,9.35,3.16,14.25,4.18-8.27,1.51-16.9-2-22.21-8.43h0Z"/>
|
|
23
|
+
</svg>
|