@jjlmoya/utils-creative 1.5.0 → 1.6.0
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/package.json +1 -1
- package/src/tool/bead-pattern-generator/component.astro +29 -21
- package/src/tool/bead-pattern-generator/i18n/en.ts +15 -3
- package/src/tool/bead-pattern-generator/i18n/es.ts +15 -3
- package/src/tool/bead-pattern-generator/i18n/fr.ts +15 -3
- package/src/tool/bead-pattern-generator/index.ts +14 -2
- package/src/tool/dice-roller/component.astro +42 -30
- package/src/tool/dice-roller/i18n/en.ts +10 -1
- package/src/tool/dice-roller/i18n/es.ts +10 -1
- package/src/tool/dice-roller/i18n/fr.ts +10 -1
- package/src/tool/dice-roller/index.ts +9 -0
- package/src/tool/fortune-cookie/component.astro +27 -16
- package/src/tool/synesthesia-painter/component.astro +5 -5
- package/src/tool/zalgo-generator/component.astro +29 -18
- package/src/tool/zalgo-generator/i18n/en.ts +12 -1
- package/src/tool/zalgo-generator/i18n/es.ts +12 -1
- package/src/tool/zalgo-generator/i18n/fr.ts +12 -1
- package/src/tool/zalgo-generator/index.ts +11 -0
package/package.json
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
+
import type { BeadPatternGeneratorUI } from './index';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
ui: BeadPatternGeneratorUI;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { ui } = Astro.props;
|
|
2
9
|
---
|
|
3
10
|
|
|
4
11
|
<div class="bead-wrapper">
|
|
@@ -8,13 +15,13 @@
|
|
|
8
15
|
<div class="bead-inner">
|
|
9
16
|
<div class="bead-header">
|
|
10
17
|
<div class="bead-header-title">
|
|
11
|
-
<h2>
|
|
12
|
-
<p>
|
|
18
|
+
<h2>{ui.title}</h2>
|
|
19
|
+
<p>{ui.subtitle}</p>
|
|
13
20
|
</div>
|
|
14
21
|
|
|
15
22
|
<div class="bead-controls">
|
|
16
23
|
<div class="bead-control-group">
|
|
17
|
-
<label class="bead-control-label">
|
|
24
|
+
<label class="bead-control-label">{ui.gridSizeLabel}</label>
|
|
18
25
|
<div class="bead-slider-row">
|
|
19
26
|
<input type="range" id="grid-width" min="10" max="100" value="40" class="bead-slider bead-slider-pink" />
|
|
20
27
|
<span id="grid-width-value" class="bead-slider-val bead-val-pink">40</span>
|
|
@@ -22,7 +29,7 @@
|
|
|
22
29
|
</div>
|
|
23
30
|
|
|
24
31
|
<div class="bead-control-group">
|
|
25
|
-
<label class="bead-control-label">
|
|
32
|
+
<label class="bead-control-label">{ui.colorCountLabel}</label>
|
|
26
33
|
<div class="bead-slider-row">
|
|
27
34
|
<input type="range" id="color-count" min="2" max="32" value="12" class="bead-slider bead-slider-purple" />
|
|
28
35
|
<span id="color-count-value" class="bead-slider-val bead-val-purple">12</span>
|
|
@@ -30,16 +37,16 @@
|
|
|
30
37
|
</div>
|
|
31
38
|
|
|
32
39
|
<div class="bead-control-group">
|
|
33
|
-
<label class="bead-control-label">
|
|
40
|
+
<label class="bead-control-label">{ui.optionsLabel}</label>
|
|
34
41
|
<div class="bead-options-row">
|
|
35
42
|
<label class="bead-checkbox-label">
|
|
36
43
|
<input type="checkbox" id="show-rulers" class="bead-checkbox" />
|
|
37
|
-
<span>
|
|
44
|
+
<span>{ui.rulersLabel}</span>
|
|
38
45
|
</label>
|
|
39
46
|
<div class="bead-divider"></div>
|
|
40
|
-
<label class="bead-checkbox-label" title=
|
|
47
|
+
<label class="bead-checkbox-label" title={ui.symbolsTooltip}>
|
|
41
48
|
<input type="checkbox" id="show-symbols" class="bead-checkbox" />
|
|
42
|
-
<span>
|
|
49
|
+
<span>{ui.symbolsLabel}</span>
|
|
43
50
|
</label>
|
|
44
51
|
</div>
|
|
45
52
|
</div>
|
|
@@ -48,7 +55,7 @@
|
|
|
48
55
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="currentColor">
|
|
49
56
|
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"></path>
|
|
50
57
|
</svg>
|
|
51
|
-
<span>
|
|
58
|
+
<span>{ui.downloadBtn}</span>
|
|
52
59
|
</button>
|
|
53
60
|
</div>
|
|
54
61
|
</div>
|
|
@@ -62,21 +69,21 @@
|
|
|
62
69
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
63
70
|
</svg>
|
|
64
71
|
</div>
|
|
65
|
-
<h3>
|
|
66
|
-
<p>
|
|
72
|
+
<h3>{ui.uploadTitle}</h3>
|
|
73
|
+
<p>{ui.uploadSubtitle}</p>
|
|
67
74
|
</div>
|
|
68
75
|
</div>
|
|
69
76
|
|
|
70
77
|
<div id="result-area" class="bead-result bead-hidden">
|
|
71
78
|
<div class="bead-result-inner">
|
|
72
79
|
<div class="bead-palette-col">
|
|
73
|
-
<h3 class="bead-palette-title">
|
|
80
|
+
<h3 class="bead-palette-title">{ui.paletteTitle}</h3>
|
|
74
81
|
<div id="palette-grid" class="bead-palette-grid"></div>
|
|
75
82
|
<button id="reupload-btn" class="bead-reupload-btn">
|
|
76
83
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
77
84
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
|
78
85
|
</svg>
|
|
79
|
-
|
|
86
|
+
{ui.reuploadBtn}
|
|
80
87
|
</button>
|
|
81
88
|
</div>
|
|
82
89
|
<div class="bead-canvas-col">
|
|
@@ -86,8 +93,8 @@
|
|
|
86
93
|
|
|
87
94
|
<div class="bead-tunnel-bar">
|
|
88
95
|
<div>
|
|
89
|
-
<h3 class="bead-tunnel-title">
|
|
90
|
-
<p class="bead-tunnel-sub">
|
|
96
|
+
<h3 class="bead-tunnel-title">{ui.tunnelVisionTitle}</h3>
|
|
97
|
+
<p class="bead-tunnel-sub">{ui.tunnelVisionSubtitle}</p>
|
|
91
98
|
</div>
|
|
92
99
|
<div class="bead-tunnel-controls">
|
|
93
100
|
<button id="focus-prev" class="bead-tunnel-btn">▲</button>
|
|
@@ -590,6 +597,7 @@
|
|
|
590
597
|
min-height: 25rem;
|
|
591
598
|
display: flex;
|
|
592
599
|
flex-direction: column;
|
|
600
|
+
gap: 3rem;
|
|
593
601
|
}
|
|
594
602
|
|
|
595
603
|
.bead-drop-zone {
|
|
@@ -716,13 +724,13 @@
|
|
|
716
724
|
gap: 0.5rem;
|
|
717
725
|
}
|
|
718
726
|
|
|
719
|
-
.bead-palette-item {
|
|
727
|
+
:global(.bead-palette-item) {
|
|
720
728
|
display: flex;
|
|
721
729
|
flex-direction: column;
|
|
722
730
|
align-items: center;
|
|
723
731
|
}
|
|
724
732
|
|
|
725
|
-
.bead-color-swatch {
|
|
733
|
+
:global(.bead-color-swatch) {
|
|
726
734
|
width: 100%;
|
|
727
735
|
aspect-ratio: 1;
|
|
728
736
|
border-radius: 50%;
|
|
@@ -734,21 +742,21 @@
|
|
|
734
742
|
justify-content: center;
|
|
735
743
|
}
|
|
736
744
|
|
|
737
|
-
:global(.theme-dark
|
|
745
|
+
:global(.theme-dark .bead-color-swatch) {
|
|
738
746
|
border-color: #1f2937;
|
|
739
747
|
outline-color: #374151;
|
|
740
748
|
}
|
|
741
749
|
|
|
742
|
-
.bead-symbol {
|
|
750
|
+
:global(.bead-symbol) {
|
|
743
751
|
font-size: 0.75rem;
|
|
744
752
|
font-weight: 700;
|
|
745
753
|
user-select: none;
|
|
746
754
|
}
|
|
747
|
-
.bead-symbol-dark {
|
|
755
|
+
:global(.bead-symbol-dark) {
|
|
748
756
|
color: #000;
|
|
749
757
|
}
|
|
750
758
|
|
|
751
|
-
.bead-symbol-light {
|
|
759
|
+
:global(.bead-symbol-light) {
|
|
752
760
|
color: #fff;
|
|
753
761
|
}
|
|
754
762
|
|
|
@@ -7,12 +7,24 @@ export const content: BeadPatternGeneratorLocaleContent = {
|
|
|
7
7
|
faqTitle: 'Frequently Asked Questions',
|
|
8
8
|
bibliographyTitle: 'Artisan Bibliography',
|
|
9
9
|
ui: {
|
|
10
|
-
title: 'Pattern
|
|
10
|
+
title: 'Pattern Laboratory',
|
|
11
|
+
subtitle: 'Color engineering for your hands',
|
|
11
12
|
description: 'From photo to bead scheme.',
|
|
13
|
+
gridSizeLabel: 'Size (Width)',
|
|
14
|
+
colorCountLabel: 'Colors',
|
|
15
|
+
optionsLabel: 'Options',
|
|
16
|
+
rulersLabel: 'Rulers',
|
|
17
|
+
symbolsTooltip: 'Surprise Pattern',
|
|
18
|
+
symbolsLabel: 'Symbols',
|
|
19
|
+
downloadBtn: 'Download',
|
|
20
|
+
uploadTitle: 'Upload Your Vision',
|
|
21
|
+
uploadSubtitle: 'and let the digital magic happen',
|
|
22
|
+
paletteTitle: 'Chromatic DNA',
|
|
23
|
+
reuploadBtn: 'Change Image',
|
|
24
|
+
tunnelVisionTitle: 'Tunnel Vision',
|
|
25
|
+
tunnelVisionSubtitle: 'Your precision assistant row by row.',
|
|
12
26
|
uploadLabel: 'Upload your photo',
|
|
13
|
-
gridSizeLabel: 'Grid size (beads)',
|
|
14
27
|
pixelateBtn: 'Generate Pattern',
|
|
15
|
-
downloadBtn: 'Download Scheme',
|
|
16
28
|
faqTitle: 'FAQ',
|
|
17
29
|
bibliographyTitle: 'References'
|
|
18
30
|
},
|
|
@@ -7,12 +7,24 @@ export const content: BeadPatternGeneratorLocaleContent = {
|
|
|
7
7
|
faqTitle: 'Preguntas Frecuentes',
|
|
8
8
|
bibliographyTitle: 'Bibliografía del Artesano',
|
|
9
9
|
ui: {
|
|
10
|
-
title: '
|
|
10
|
+
title: 'Laboratorio de Patrones',
|
|
11
|
+
subtitle: 'Ingeniería de color para tus manos',
|
|
11
12
|
description: 'De fotografía a esquema de cuentas.',
|
|
13
|
+
gridSizeLabel: 'Tamaño (Ancho)',
|
|
14
|
+
colorCountLabel: 'Colores',
|
|
15
|
+
optionsLabel: 'Opciones',
|
|
16
|
+
rulersLabel: 'Reglas',
|
|
17
|
+
symbolsTooltip: 'Patrón Sorpresa',
|
|
18
|
+
symbolsLabel: 'Símbolos',
|
|
19
|
+
downloadBtn: 'Descargar',
|
|
20
|
+
uploadTitle: 'Carga tu Visión',
|
|
21
|
+
uploadSubtitle: 'y deja que la magia digital ocurra',
|
|
22
|
+
paletteTitle: 'ADN Cromático',
|
|
23
|
+
reuploadBtn: 'Cambiar Imagen',
|
|
24
|
+
tunnelVisionTitle: 'Visión de Túnel',
|
|
25
|
+
tunnelVisionSubtitle: 'Tu asistente de precisión fila por fila.',
|
|
12
26
|
uploadLabel: 'Sube tu foto',
|
|
13
|
-
gridSizeLabel: 'Tamaño de la cuadrícula (beads)',
|
|
14
27
|
pixelateBtn: 'Generar Patrón',
|
|
15
|
-
downloadBtn: 'Descargar Esquema',
|
|
16
28
|
faqTitle: 'FAQ',
|
|
17
29
|
bibliographyTitle: 'Referencias'
|
|
18
30
|
},
|
|
@@ -7,12 +7,24 @@ export const content: BeadPatternGeneratorLocaleContent = {
|
|
|
7
7
|
faqTitle: 'Questions Fréquemment Posées',
|
|
8
8
|
bibliographyTitle: 'Bibliographie de l\'Artisan',
|
|
9
9
|
ui: {
|
|
10
|
-
title: '
|
|
10
|
+
title: 'Laboratoire de Modèles',
|
|
11
|
+
subtitle: 'Ingénierie chromatique pour vos mains',
|
|
11
12
|
description: 'De la photo au schéma de perles.',
|
|
13
|
+
gridSizeLabel: 'Taille (Largeur)',
|
|
14
|
+
colorCountLabel: 'Couleurs',
|
|
15
|
+
optionsLabel: 'Options',
|
|
16
|
+
rulersLabel: 'Règles',
|
|
17
|
+
symbolsTooltip: 'Motif Surprise',
|
|
18
|
+
symbolsLabel: 'Symboles',
|
|
19
|
+
downloadBtn: 'Télécharger',
|
|
20
|
+
uploadTitle: 'Chargez Votre Vision',
|
|
21
|
+
uploadSubtitle: 'et laissez la magie numérique opérer',
|
|
22
|
+
paletteTitle: 'ADN Chromatique',
|
|
23
|
+
reuploadBtn: 'Changer l\'Image',
|
|
24
|
+
tunnelVisionTitle: 'Vision de Tunnel',
|
|
25
|
+
tunnelVisionSubtitle: 'Votre assistant de précision rangée par rangée.',
|
|
12
26
|
uploadLabel: 'Chargez votre photo',
|
|
13
|
-
gridSizeLabel: 'Taille de grille (perles)',
|
|
14
27
|
pixelateBtn: 'Générer le Modèle',
|
|
15
|
-
downloadBtn: 'Télécharger le Schéma',
|
|
16
28
|
faqTitle: 'FAQ',
|
|
17
29
|
bibliographyTitle: 'Références'
|
|
18
30
|
},
|
|
@@ -7,10 +7,22 @@ export interface BeadPatternGeneratorUI {
|
|
|
7
7
|
[key: string]: string;
|
|
8
8
|
title: string;
|
|
9
9
|
description: string;
|
|
10
|
-
|
|
10
|
+
subtitle: string;
|
|
11
11
|
gridSizeLabel: string;
|
|
12
|
-
|
|
12
|
+
colorCountLabel: string;
|
|
13
|
+
optionsLabel: string;
|
|
14
|
+
rulersLabel: string;
|
|
15
|
+
symbolsTooltip: string;
|
|
16
|
+
symbolsLabel: string;
|
|
13
17
|
downloadBtn: string;
|
|
18
|
+
uploadTitle: string;
|
|
19
|
+
uploadSubtitle: string;
|
|
20
|
+
paletteTitle: string;
|
|
21
|
+
reuploadBtn: string;
|
|
22
|
+
tunnelVisionTitle: string;
|
|
23
|
+
tunnelVisionSubtitle: string;
|
|
24
|
+
uploadLabel: string;
|
|
25
|
+
pixelateBtn: string;
|
|
14
26
|
faqTitle: string;
|
|
15
27
|
bibliographyTitle: string;
|
|
16
28
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
---
|
|
2
|
+
import type { DiceRollerUI } from './index';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
ui: DiceRollerUI;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { ui } = Astro.props;
|
|
2
9
|
---
|
|
3
10
|
|
|
4
|
-
<div id="dice-roller-root" class="dr-root">
|
|
11
|
+
<div id="dice-roller-root" class="dr-root" data-ui={JSON.stringify(ui)}>
|
|
5
12
|
<div class="dr-panel">
|
|
6
13
|
|
|
7
14
|
<div class="dr-selector">
|
|
8
|
-
<p class="dr-label">
|
|
15
|
+
<p class="dr-label">{ui.addDiceLabel}</p>
|
|
9
16
|
<div class="dr-dice-grid">
|
|
10
17
|
<button class="dr-die-btn" data-sides="4">d4</button>
|
|
11
18
|
<button class="dr-die-btn" data-sides="6">d6</button>
|
|
@@ -19,16 +26,16 @@
|
|
|
19
26
|
|
|
20
27
|
<div class="dr-pool-section">
|
|
21
28
|
<div class="dr-pool-header">
|
|
22
|
-
<p class="dr-label">
|
|
23
|
-
<button id="dr-clear-pool" class="dr-clear-btn">
|
|
29
|
+
<p class="dr-label">{ui.bagLabel}</p>
|
|
30
|
+
<button id="dr-clear-pool" class="dr-clear-btn">{ui.emptyBagBtn}</button>
|
|
24
31
|
</div>
|
|
25
32
|
<div id="dr-pool" class="dr-pool-display">
|
|
26
|
-
<span class="dr-pool-empty">
|
|
33
|
+
<span class="dr-pool-empty">{ui.emptyBagText}</span>
|
|
27
34
|
</div>
|
|
28
35
|
</div>
|
|
29
36
|
|
|
30
37
|
<div class="dr-modifier-section">
|
|
31
|
-
<label class="dr-label" for="dr-modifier">
|
|
38
|
+
<label class="dr-label" for="dr-modifier">{ui.modifierLabel}</label>
|
|
32
39
|
<div class="dr-modifier-controls">
|
|
33
40
|
<button id="dr-mod-dec" class="dr-mod-btn">−</button>
|
|
34
41
|
<span id="dr-modifier-val" class="dr-modifier-display">0</span>
|
|
@@ -37,7 +44,7 @@
|
|
|
37
44
|
</div>
|
|
38
45
|
|
|
39
46
|
<button id="dr-roll-btn" class="dr-roll-btn" disabled>
|
|
40
|
-
<span id="dr-roll-text">
|
|
47
|
+
<span id="dr-roll-text">{ui.rollBtn}</span>
|
|
41
48
|
</button>
|
|
42
49
|
|
|
43
50
|
</div>
|
|
@@ -46,11 +53,11 @@
|
|
|
46
53
|
|
|
47
54
|
<div class="dr-result-card" id="dr-result-card">
|
|
48
55
|
<div class="dr-result-empty" id="dr-result-empty">
|
|
49
|
-
<p>
|
|
56
|
+
<p>{ui.preRollText}</p>
|
|
50
57
|
</div>
|
|
51
58
|
<div class="dr-result-content" id="dr-result-content" style="display:none">
|
|
52
59
|
<div class="dr-total-area">
|
|
53
|
-
<span class="dr-total-label">
|
|
60
|
+
<span class="dr-total-label">{ui.totalLabel}</span>
|
|
54
61
|
<span id="dr-total" class="dr-total-val">0</span>
|
|
55
62
|
<span id="dr-roll-expr" class="dr-roll-expr"></span>
|
|
56
63
|
</div>
|
|
@@ -60,11 +67,11 @@
|
|
|
60
67
|
|
|
61
68
|
<div class="dr-history-section">
|
|
62
69
|
<div class="dr-history-header">
|
|
63
|
-
<span class="dr-label">
|
|
64
|
-
<button id="dr-clear-history" class="dr-clear-btn">
|
|
70
|
+
<span class="dr-label">{ui.historyLabel}</span>
|
|
71
|
+
<button id="dr-clear-history" class="dr-clear-btn">{ui.clearHistoryBtn}</button>
|
|
65
72
|
</div>
|
|
66
73
|
<div id="dr-history-list" class="dr-history-list">
|
|
67
|
-
<p class="dr-history-empty">
|
|
74
|
+
<p class="dr-history-empty">{ui.emptyHistoryText}</p>
|
|
68
75
|
</div>
|
|
69
76
|
</div>
|
|
70
77
|
|
|
@@ -72,6 +79,10 @@
|
|
|
72
79
|
</div>
|
|
73
80
|
|
|
74
81
|
<script>
|
|
82
|
+
import type { DiceRollerUI } from './index';
|
|
83
|
+
const root = document.getElementById('dice-roller-root') as HTMLElement;
|
|
84
|
+
const ui = JSON.parse(root.dataset.ui || '{}') as DiceRollerUI;
|
|
85
|
+
|
|
75
86
|
type Pool = { sides: number; count: number }[];
|
|
76
87
|
|
|
77
88
|
let pool: Pool = [];
|
|
@@ -94,9 +105,9 @@
|
|
|
94
105
|
|
|
95
106
|
function renderPool(): void {
|
|
96
107
|
if (pool.length === 0) {
|
|
97
|
-
poolDisplay.innerHTML =
|
|
108
|
+
poolDisplay.innerHTML = `<span class="dr-pool-empty">${ui.emptyBagText}</span>`;
|
|
98
109
|
rollBtn.disabled = true;
|
|
99
|
-
rollText.textContent =
|
|
110
|
+
rollText.textContent = ui.rollBtn;
|
|
100
111
|
return;
|
|
101
112
|
}
|
|
102
113
|
|
|
@@ -106,14 +117,15 @@
|
|
|
106
117
|
chip.className = 'dr-pool-chip';
|
|
107
118
|
chip.innerHTML = `
|
|
108
119
|
<span class="dr-chip-label">${count}d${sides}</span>
|
|
109
|
-
<button class="dr-chip-remove" data-sides="${sides}"
|
|
120
|
+
<button class="dr-chip-remove" data-sides="${sides}">−</button>
|
|
110
121
|
`;
|
|
111
122
|
poolDisplay.appendChild(chip);
|
|
112
123
|
});
|
|
113
124
|
|
|
114
125
|
const total = poolTotal();
|
|
115
126
|
rollBtn.disabled = false;
|
|
116
|
-
|
|
127
|
+
const label = total === 1 ? ui.rollOneLabel : ui.rollManyLabel;
|
|
128
|
+
rollText.textContent = label.replace('$COUNT', total.toString());
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
function addDie(sides: number): void {
|
|
@@ -224,7 +236,7 @@
|
|
|
224
236
|
rollBtn.addEventListener('click', rollAll);
|
|
225
237
|
|
|
226
238
|
document.getElementById('dr-clear-history')?.addEventListener('click', () => {
|
|
227
|
-
historyList.innerHTML =
|
|
239
|
+
historyList.innerHTML = `<p class="dr-history-empty">${ui.emptyHistoryText}</p>`;
|
|
228
240
|
});
|
|
229
241
|
</script>
|
|
230
242
|
|
|
@@ -378,7 +390,7 @@
|
|
|
378
390
|
font-style: italic;
|
|
379
391
|
}
|
|
380
392
|
|
|
381
|
-
.dr-pool-chip {
|
|
393
|
+
:global(.dr-pool-chip) {
|
|
382
394
|
display: flex;
|
|
383
395
|
align-items: center;
|
|
384
396
|
gap: 0.25rem;
|
|
@@ -388,13 +400,13 @@
|
|
|
388
400
|
padding: 0.2rem 0.5rem 0.2rem 0.75rem;
|
|
389
401
|
}
|
|
390
402
|
|
|
391
|
-
.dr-chip-label {
|
|
403
|
+
:global(.dr-chip-label) {
|
|
392
404
|
font-size: 0.8rem;
|
|
393
405
|
font-weight: 700;
|
|
394
406
|
color: var(--dr-primary);
|
|
395
407
|
}
|
|
396
408
|
|
|
397
|
-
.dr-chip-remove {
|
|
409
|
+
:global(.dr-chip-remove) {
|
|
398
410
|
width: 1.125rem;
|
|
399
411
|
height: 1.125rem;
|
|
400
412
|
border-radius: 50%;
|
|
@@ -411,7 +423,7 @@
|
|
|
411
423
|
padding: 0;
|
|
412
424
|
}
|
|
413
425
|
|
|
414
|
-
.dr-chip-remove:hover {
|
|
426
|
+
:global(.dr-chip-remove:hover) {
|
|
415
427
|
background: var(--dr-primary-dark);
|
|
416
428
|
}
|
|
417
429
|
|
|
@@ -581,7 +593,7 @@
|
|
|
581
593
|
justify-content: center;
|
|
582
594
|
}
|
|
583
595
|
|
|
584
|
-
.dr-result-pip {
|
|
596
|
+
:global(.dr-result-pip) {
|
|
585
597
|
display: flex;
|
|
586
598
|
flex-direction: column;
|
|
587
599
|
align-items: center;
|
|
@@ -594,24 +606,24 @@
|
|
|
594
606
|
transition: border-color 0.2s;
|
|
595
607
|
}
|
|
596
608
|
|
|
597
|
-
.dr-pip-max {
|
|
609
|
+
:global(.dr-pip-max) {
|
|
598
610
|
border-color: var(--dr-success);
|
|
599
611
|
background: rgba(16, 185, 129, 0.1);
|
|
600
612
|
}
|
|
601
613
|
|
|
602
|
-
.dr-pip-min {
|
|
614
|
+
:global(.dr-pip-min) {
|
|
603
615
|
border-color: var(--dr-danger);
|
|
604
616
|
background: rgba(239, 68, 68, 0.1);
|
|
605
617
|
}
|
|
606
618
|
|
|
607
|
-
.dr-pip-val {
|
|
619
|
+
:global(.dr-pip-val) {
|
|
608
620
|
font-size: 1.25rem;
|
|
609
621
|
font-weight: 800;
|
|
610
622
|
color: var(--dr-text);
|
|
611
623
|
line-height: 1;
|
|
612
624
|
}
|
|
613
625
|
|
|
614
|
-
.dr-pip-die {
|
|
626
|
+
:global(.dr-pip-die) {
|
|
615
627
|
font-size: 0.65rem;
|
|
616
628
|
color: var(--dr-text-muted);
|
|
617
629
|
font-weight: 600;
|
|
@@ -662,7 +674,7 @@
|
|
|
662
674
|
margin: 1rem 0;
|
|
663
675
|
}
|
|
664
676
|
|
|
665
|
-
.dr-history-item {
|
|
677
|
+
:global(.dr-history-item) {
|
|
666
678
|
display: grid;
|
|
667
679
|
grid-template-columns: 1fr auto auto;
|
|
668
680
|
align-items: center;
|
|
@@ -686,7 +698,7 @@
|
|
|
686
698
|
}
|
|
687
699
|
}
|
|
688
700
|
|
|
689
|
-
.dr-hist-expr {
|
|
701
|
+
:global(.dr-hist-expr) {
|
|
690
702
|
color: var(--dr-text-muted);
|
|
691
703
|
font-size: 0.75rem;
|
|
692
704
|
overflow: hidden;
|
|
@@ -694,13 +706,13 @@
|
|
|
694
706
|
white-space: nowrap;
|
|
695
707
|
}
|
|
696
708
|
|
|
697
|
-
.dr-hist-result {
|
|
709
|
+
:global(.dr-hist-result) {
|
|
698
710
|
font-weight: 800;
|
|
699
711
|
font-size: 1rem;
|
|
700
712
|
color: var(--dr-primary);
|
|
701
713
|
}
|
|
702
714
|
|
|
703
|
-
.dr-hist-time {
|
|
715
|
+
:global(.dr-hist-time) {
|
|
704
716
|
font-size: 0.7rem;
|
|
705
717
|
color: var(--dr-text-muted);
|
|
706
718
|
}
|
|
@@ -14,7 +14,16 @@ export const content: DiceRollerLocaleContent = {
|
|
|
14
14
|
historyLabel: 'History',
|
|
15
15
|
clearHistoryBtn: 'Clear History',
|
|
16
16
|
faqTitle: 'FAQ',
|
|
17
|
-
bibliographyTitle: 'References'
|
|
17
|
+
bibliographyTitle: 'References',
|
|
18
|
+
addDiceLabel: 'Add dice to the bag',
|
|
19
|
+
bagLabel: 'Dice bag',
|
|
20
|
+
emptyBagBtn: 'Empty',
|
|
21
|
+
emptyBagText: 'Click the dice to add them',
|
|
22
|
+
modifierLabel: 'Modifier',
|
|
23
|
+
rollManyLabel: 'Roll $COUNT dice',
|
|
24
|
+
rollOneLabel: 'Roll $COUNT die',
|
|
25
|
+
preRollText: 'Add dice and roll',
|
|
26
|
+
emptyHistoryText: 'Roll history will appear here'
|
|
18
27
|
},
|
|
19
28
|
seo: [
|
|
20
29
|
{ type: 'title', text: 'The Art of Randomness: History and Mathematics of Dice', level: 2 },
|
|
@@ -14,7 +14,16 @@ export const content: DiceRollerLocaleContent = {
|
|
|
14
14
|
historyLabel: 'Historial',
|
|
15
15
|
clearHistoryBtn: 'Limpiar Historial',
|
|
16
16
|
faqTitle: 'FAQ',
|
|
17
|
-
bibliographyTitle: 'Referencias'
|
|
17
|
+
bibliographyTitle: 'Referencias',
|
|
18
|
+
addDiceLabel: 'Añadir dados a la bolsa',
|
|
19
|
+
bagLabel: 'Bolsa de dados',
|
|
20
|
+
emptyBagBtn: 'Vaciar',
|
|
21
|
+
emptyBagText: 'Haz clic en los dados para añadirlos',
|
|
22
|
+
modifierLabel: 'Modificador',
|
|
23
|
+
rollManyLabel: 'Lanzar $COUNT dados',
|
|
24
|
+
rollOneLabel: 'Lanzar $COUNT dado',
|
|
25
|
+
preRollText: 'Añade dados y lanza',
|
|
26
|
+
emptyHistoryText: 'El historial de tiradas aparecerá aquí'
|
|
18
27
|
},
|
|
19
28
|
seo: [
|
|
20
29
|
{ type: 'title', text: 'El arte de la aleatoriedad: historia y matemáticas de los dados', level: 2 },
|
|
@@ -14,7 +14,16 @@ export const content: DiceRollerLocaleContent = {
|
|
|
14
14
|
historyLabel: 'Historique',
|
|
15
15
|
clearHistoryBtn: 'Effacer l\'historique',
|
|
16
16
|
faqTitle: 'FAQ',
|
|
17
|
-
bibliographyTitle: 'Références'
|
|
17
|
+
bibliographyTitle: 'Références',
|
|
18
|
+
addDiceLabel: 'Ajouter des dés au sac',
|
|
19
|
+
bagLabel: 'Sac de dés',
|
|
20
|
+
emptyBagBtn: 'Vider',
|
|
21
|
+
emptyBagText: 'Cliquez sur les dés pour les ajouter',
|
|
22
|
+
modifierLabel: 'Modificateur',
|
|
23
|
+
rollManyLabel: 'Lancer $COUNT dés',
|
|
24
|
+
rollOneLabel: 'Lancer $COUNT dé',
|
|
25
|
+
preRollText: 'Ajoutez des dés et lancez',
|
|
26
|
+
emptyHistoryText: 'L\'historique des lancers apparaîtra ici'
|
|
18
27
|
},
|
|
19
28
|
seo: [
|
|
20
29
|
{ type: 'title', text: 'L\'Art du Hasard : Histoire et Mathématiques des Dés', level: 2 },
|
|
@@ -13,6 +13,15 @@ export interface DiceRollerUI {
|
|
|
13
13
|
clearHistoryBtn: string;
|
|
14
14
|
faqTitle: string;
|
|
15
15
|
bibliographyTitle: string;
|
|
16
|
+
addDiceLabel: string;
|
|
17
|
+
bagLabel: string;
|
|
18
|
+
emptyBagBtn: string;
|
|
19
|
+
emptyBagText: string;
|
|
20
|
+
modifierLabel: string;
|
|
21
|
+
rollManyLabel: string;
|
|
22
|
+
rollOneLabel: string;
|
|
23
|
+
preRollText: string;
|
|
24
|
+
emptyHistoryText: string;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
export type DiceRollerLocaleContent = ToolLocaleContent<DiceRollerUI>;
|
|
@@ -470,25 +470,35 @@ const ASSETS = {
|
|
|
470
470
|
top: 50%;
|
|
471
471
|
left: 50%;
|
|
472
472
|
transform: translate(-50%, -50%) scale(0.5);
|
|
473
|
-
width:
|
|
474
|
-
max-width:
|
|
473
|
+
width: 85%;
|
|
474
|
+
max-width: 320px;
|
|
475
|
+
background-color: #fff;
|
|
476
|
+
border-radius: 2px;
|
|
477
|
+
box-shadow:
|
|
478
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.2),
|
|
479
|
+
0 4px 6px -2px rgba(0, 0, 0, 0.1),
|
|
480
|
+
inset 0 0 20px rgba(0, 0, 0, 0.05);
|
|
475
481
|
opacity: 0;
|
|
476
482
|
transition-property: all;
|
|
477
|
-
transition-timing-function: cubic-bezier(0.
|
|
478
|
-
transition-duration:
|
|
483
|
+
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
484
|
+
transition-duration: 800ms;
|
|
479
485
|
z-index: 0;
|
|
486
|
+
overflow: hidden;
|
|
480
487
|
}
|
|
481
488
|
|
|
482
489
|
.fortune-cookie-paper.visible {
|
|
483
490
|
opacity: 1;
|
|
484
|
-
transform: translate(-50%, -50%) scale(1);
|
|
491
|
+
transform: translate(-50%, -50%) scale(1) rotate(-1deg);
|
|
485
492
|
z-index: 20;
|
|
486
493
|
}
|
|
487
494
|
|
|
488
495
|
.fortune-cookie-paper-img {
|
|
489
496
|
width: 100%;
|
|
490
|
-
|
|
491
|
-
|
|
497
|
+
height: auto;
|
|
498
|
+
display: block;
|
|
499
|
+
opacity: 0.15;
|
|
500
|
+
pointer-events: none;
|
|
501
|
+
mix-blend-mode: multiply;
|
|
492
502
|
}
|
|
493
503
|
|
|
494
504
|
.fortune-cookie-paper-content {
|
|
@@ -498,23 +508,24 @@ const ASSETS = {
|
|
|
498
508
|
flex-direction: column;
|
|
499
509
|
align-items: center;
|
|
500
510
|
justify-content: center;
|
|
501
|
-
padding:
|
|
511
|
+
padding: 1.5rem;
|
|
502
512
|
text-align: center;
|
|
513
|
+
z-index: 10;
|
|
503
514
|
}
|
|
504
515
|
|
|
505
516
|
.fortune-cookie-text {
|
|
506
|
-
color: #
|
|
507
|
-
font-weight:
|
|
517
|
+
color: #1e293b;
|
|
518
|
+
font-weight: 800;
|
|
508
519
|
font-size: 1.125rem;
|
|
509
|
-
line-height: 1.
|
|
520
|
+
line-height: 1.4;
|
|
510
521
|
transform: rotate(-1deg);
|
|
511
522
|
user-select: text;
|
|
523
|
+
margin: 0;
|
|
512
524
|
}
|
|
513
525
|
|
|
514
526
|
@media (min-width: 768px) {
|
|
515
527
|
.fortune-cookie-text {
|
|
516
528
|
font-size: 1.25rem;
|
|
517
|
-
line-height: 1.75rem;
|
|
518
529
|
}
|
|
519
530
|
}
|
|
520
531
|
|
|
@@ -527,12 +538,12 @@ const ASSETS = {
|
|
|
527
538
|
transform: rotate(-1deg);
|
|
528
539
|
}
|
|
529
540
|
|
|
530
|
-
.fortune-cookie-number {
|
|
541
|
+
:global(.fortune-cookie-number) {
|
|
531
542
|
font-size: 0.75rem;
|
|
532
543
|
line-height: 1rem;
|
|
533
544
|
font-weight: 700;
|
|
534
|
-
background-color:
|
|
535
|
-
color: #
|
|
545
|
+
background-color: #f1f5f9;
|
|
546
|
+
color: #dc2626;
|
|
536
547
|
padding-left: 0.5rem;
|
|
537
548
|
padding-right: 0.5rem;
|
|
538
549
|
padding-top: 0.125rem;
|
|
@@ -621,7 +632,7 @@ const ASSETS = {
|
|
|
621
632
|
40%, 60% { transform: translate3d(4px, 0, 0) rotate(4deg); }
|
|
622
633
|
}
|
|
623
634
|
|
|
624
|
-
.fortune-cookie-crumb {
|
|
635
|
+
:global(.fortune-cookie-crumb) {
|
|
625
636
|
position: absolute;
|
|
626
637
|
width: 20px;
|
|
627
638
|
height: 20px;
|
|
@@ -282,7 +282,7 @@ const { ui } = Astro.props;
|
|
|
282
282
|
color: #ef4444;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
.synesthesia-painter-char {
|
|
285
|
+
:global(.synesthesia-painter-char) {
|
|
286
286
|
display: inline-block;
|
|
287
287
|
color: var(--char-color);
|
|
288
288
|
transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -301,7 +301,7 @@ const { ui } = Astro.props;
|
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
.synesthesia-painter-viz-layer.dots .synesthesia-painter-char {
|
|
304
|
+
:global(.synesthesia-painter-viz-layer.dots .synesthesia-painter-char) {
|
|
305
305
|
color: transparent;
|
|
306
306
|
font-size: 0;
|
|
307
307
|
width: 1rem;
|
|
@@ -312,17 +312,17 @@ const { ui } = Astro.props;
|
|
|
312
312
|
box-shadow: 0 0 8px var(--char-color);
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
.synesthesia-painter-viz-layer.aura .synesthesia-painter-char {
|
|
315
|
+
:global(.synesthesia-painter-viz-layer.aura .synesthesia-painter-char) {
|
|
316
316
|
color: rgba(255, 255, 255, 0.15);
|
|
317
317
|
text-shadow: 0 0 18px var(--char-color), 0 0 36px var(--char-color);
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
:global(.theme-dark
|
|
320
|
+
:global(.theme-dark .synesthesia-painter-viz-layer.aura .synesthesia-painter-char) {
|
|
321
321
|
color: rgba(255, 255, 255, 0.85);
|
|
322
322
|
text-shadow: 0 0 14px var(--char-color), 0 0 28px var(--char-color), 0 0 56px var(--char-color);
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
-
.synesthesia-painter-cursor {
|
|
325
|
+
:global(.synesthesia-painter-cursor) {
|
|
326
326
|
display: inline-block;
|
|
327
327
|
width: 2px;
|
|
328
328
|
height: 2.5rem;
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Icon } from 'astro-icon/components';
|
|
3
|
+
import type { ZalgoGeneratorUI } from './index';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
ui: ZalgoGeneratorUI;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { ui } = Astro.props;
|
|
3
10
|
---
|
|
4
11
|
|
|
5
|
-
<section class="zg-section">
|
|
12
|
+
<section class="zg-section" id="zalgo-generator-root" data-ui={JSON.stringify(ui)}>
|
|
6
13
|
<div class="zg-grid">
|
|
7
14
|
<div class="zg-left">
|
|
8
15
|
<div class="zg-config-card">
|
|
9
16
|
<div class="zg-config-hover-bg"></div>
|
|
10
17
|
<h3 class="zg-config-title">
|
|
11
18
|
<Icon name="mdi:tune-variant" style="width:1.25rem;height:1.25rem;color:#9333ea" />
|
|
12
|
-
|
|
19
|
+
{ui.configTitle}
|
|
13
20
|
</h3>
|
|
14
21
|
|
|
15
22
|
<div class="zg-config-body">
|
|
16
23
|
<div class="zg-field">
|
|
17
24
|
<div class="zg-field-header">
|
|
18
|
-
<label class="zg-field-label">
|
|
25
|
+
<label class="zg-field-label">{ui.intensity}</label>
|
|
19
26
|
<span id="intensity-value" class="zg-intensity-val">50%</span>
|
|
20
27
|
</div>
|
|
21
28
|
<input type="range" id="intensity-slider" min="0.1" max="1.5" step="0.1" value="0.5" class="zg-slider" />
|
|
@@ -23,21 +30,21 @@ import { Icon } from 'astro-icon/components';
|
|
|
23
30
|
|
|
24
31
|
<div class="zg-toggles">
|
|
25
32
|
<label class="zg-toggle-row">
|
|
26
|
-
<span class="zg-toggle-label">
|
|
33
|
+
<span class="zg-toggle-label">{ui.upLabel}</span>
|
|
27
34
|
<div class="zg-switch">
|
|
28
35
|
<input type="checkbox" id="opt-up" checked class="zg-switch-input" />
|
|
29
36
|
<div class="zg-switch-track"></div>
|
|
30
37
|
</div>
|
|
31
38
|
</label>
|
|
32
39
|
<label class="zg-toggle-row">
|
|
33
|
-
<span class="zg-toggle-label">
|
|
40
|
+
<span class="zg-toggle-label">{ui.midLabel}</span>
|
|
34
41
|
<div class="zg-switch">
|
|
35
42
|
<input type="checkbox" id="opt-middle" checked class="zg-switch-input" />
|
|
36
43
|
<div class="zg-switch-track"></div>
|
|
37
44
|
</div>
|
|
38
45
|
</label>
|
|
39
46
|
<label class="zg-toggle-row">
|
|
40
|
-
<span class="zg-toggle-label">
|
|
47
|
+
<span class="zg-toggle-label">{ui.downLabel}</span>
|
|
41
48
|
<div class="zg-switch">
|
|
42
49
|
<input type="checkbox" id="opt-down" checked class="zg-switch-input" />
|
|
43
50
|
<div class="zg-switch-track"></div>
|
|
@@ -47,13 +54,13 @@ import { Icon } from 'astro-icon/components';
|
|
|
47
54
|
|
|
48
55
|
<button id="reset-options" class="zg-reset-btn">
|
|
49
56
|
<Icon name="mdi:history" style="width:1rem;height:1rem" />
|
|
50
|
-
|
|
57
|
+
{ui.resetBtn}
|
|
51
58
|
</button>
|
|
52
59
|
</div>
|
|
53
60
|
</div>
|
|
54
61
|
|
|
55
62
|
<div class="zg-warning">
|
|
56
|
-
<p>
|
|
63
|
+
<p>{ui.warningText}</p>
|
|
57
64
|
</div>
|
|
58
65
|
</div>
|
|
59
66
|
|
|
@@ -68,14 +75,14 @@ import { Icon } from 'astro-icon/components';
|
|
|
68
75
|
<textarea
|
|
69
76
|
id="input-text"
|
|
70
77
|
class="zg-textarea"
|
|
71
|
-
placeholder=
|
|
78
|
+
placeholder={ui.inputPlaceholder}
|
|
72
79
|
></textarea>
|
|
73
80
|
<div class="zg-editor-footer">
|
|
74
|
-
<span id="char-count" class="zg-char-count">0
|
|
81
|
+
<span id="char-count" class="zg-char-count">0 {ui.charLabel}</span>
|
|
75
82
|
<div class="zg-footer-sep"></div>
|
|
76
83
|
<button id="copy-btn" class="zg-copy-btn">
|
|
77
84
|
<Icon name="mdi:content-copy" style="width:1.25rem;height:1.25rem" />
|
|
78
|
-
|
|
85
|
+
{ui.copyBtn}
|
|
79
86
|
</button>
|
|
80
87
|
<button id="clear-btn" class="zg-clear-btn">
|
|
81
88
|
<Icon name="mdi:trash-can-outline" style="width:1.25rem;height:1.25rem" />
|
|
@@ -84,24 +91,28 @@ import { Icon } from 'astro-icon/components';
|
|
|
84
91
|
</div>
|
|
85
92
|
|
|
86
93
|
<div class="zg-preview-wrap">
|
|
87
|
-
<div class="zg-preview-badge">
|
|
94
|
+
<div class="zg-preview-badge">{ui.previewLabel}</div>
|
|
88
95
|
<div id="fake-ui-body" class="zg-preview-body">
|
|
89
96
|
<div class="zg-preview-dots"></div>
|
|
90
97
|
<div id="zalgo-output" class="zg-output">
|
|
91
|
-
<span class="zg-output-empty">
|
|
98
|
+
<span class="zg-output-empty">{ui.emptyLabel}</span>
|
|
92
99
|
</div>
|
|
93
100
|
<div id="glitch-overlay" class="zg-glitch-overlay">
|
|
94
101
|
<div class="zg-glitch-line zg-glitch-line-1"></div>
|
|
95
102
|
<div class="zg-glitch-line zg-glitch-line-2"></div>
|
|
96
103
|
</div>
|
|
97
104
|
</div>
|
|
98
|
-
<p class="zg-preview-note">
|
|
105
|
+
<p class="zg-preview-note">{ui.noteText}</p>
|
|
99
106
|
</div>
|
|
100
107
|
</div>
|
|
101
108
|
</div>
|
|
102
109
|
</section>
|
|
103
110
|
|
|
104
111
|
<script>
|
|
112
|
+
import type { ZalgoGeneratorUI } from './index';
|
|
113
|
+
const root = document.getElementById('zalgo-generator-root') as HTMLElement;
|
|
114
|
+
const ui = JSON.parse(root.dataset.ui || '{}') as ZalgoGeneratorUI;
|
|
115
|
+
|
|
105
116
|
const UP = ["\u030d","\u030e","\u0304","\u0305","\u033f","\u0311","\u0306","\u0310","\u0352","\u0357","\u0351","\u0307","\u0308","\u030a","\u0342","\u0343","\u0344","\u034a","\u034b","\u034c","\u0303","\u0302","\u030c","\u0350","\u0300","\u0301","\u030b","\u030f","\u0312","\u0313","\u0314","\u033d","\u0309","\u0363","\u0364","\u0365","\u0366","\u0367","\u0368","\u0369","\u036a","\u036b","\u036c","\u036d","\u036e","\u036f","\u033e","\u035b","\u0346","\u031a"];
|
|
106
117
|
const MID = ["\u0315","\u031b","\u0340","\u0341","\u0358","\u0321","\u0322","\u0327","\u0328","\u0334","\u0335","\u0336","\u034f","\u035c","\u035d","\u035e","\u035f","\u0360","\u0362","\u0338","\u0337","\u0361","\u0489"];
|
|
107
118
|
const DOWN = ["\u0316","\u0317","\u0318","\u0319","\u031c","\u031d","\u031e","\u031f","\u0320","\u0324","\u0325","\u0326","\u0329","\u032a","\u032b","\u032c","\u032d","\u032e","\u032f","\u0330","\u0331","\u0332","\u0333","\u0339","\u033a","\u033b","\u033c","\u0345","\u0347","\u0348","\u0349","\u034d","\u034e","\u0353","\u0354","\u0355","\u0356","\u0359","\u035a","\u0323"];
|
|
@@ -142,10 +153,10 @@ import { Icon } from 'astro-icon/components';
|
|
|
142
153
|
function update() {
|
|
143
154
|
const text = input.value;
|
|
144
155
|
const intensity = parseFloat(intensitySlider.value);
|
|
145
|
-
if (charCount) charCount.textContent = `${text.length}
|
|
156
|
+
if (charCount) charCount.textContent = `${text.length} ${ui.charLabel}`;
|
|
146
157
|
if (intensityValue) intensityValue.textContent = `${Math.round(intensity * 100)}%`;
|
|
147
158
|
if (!text.trim()) {
|
|
148
|
-
output.innerHTML =
|
|
159
|
+
output.innerHTML = `<span class="zg-output-empty">${ui.emptyLabel}</span>`;
|
|
149
160
|
glitchOverlay.style.opacity = "0";
|
|
150
161
|
fakeUiBody.style.borderColor = "";
|
|
151
162
|
fakeUiBody.style.boxShadow = "";
|
|
@@ -174,10 +185,10 @@ import { Icon } from 'astro-icon/components';
|
|
|
174
185
|
|
|
175
186
|
copyBtn?.addEventListener("click", () => {
|
|
176
187
|
const text = output.textContent || "";
|
|
177
|
-
if (text && text !==
|
|
188
|
+
if (text && text !== ui.emptyLabel) {
|
|
178
189
|
navigator.clipboard.writeText(text);
|
|
179
190
|
const orig = copyBtn.innerHTML;
|
|
180
|
-
copyBtn.innerHTML =
|
|
191
|
+
copyBtn.innerHTML = ui.copied || '¡Copiado!';
|
|
181
192
|
setTimeout(() => { copyBtn.innerHTML = orig; }, 2000);
|
|
182
193
|
}
|
|
183
194
|
});
|
|
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
|
|
|
15
15
|
copyBtn: 'Copy Chaos',
|
|
16
16
|
copied: 'Copied!',
|
|
17
17
|
faqTitle: 'FAQ',
|
|
18
|
-
bibliographyTitle: 'References'
|
|
18
|
+
bibliographyTitle: 'References',
|
|
19
|
+
configTitle: 'Configuration',
|
|
20
|
+
intensity: 'Intensity',
|
|
21
|
+
upLabel: 'Upper Corruption',
|
|
22
|
+
midLabel: 'Middle Noise',
|
|
23
|
+
downLabel: 'Lower Corruption',
|
|
24
|
+
resetBtn: 'Reset Values',
|
|
25
|
+
warningText: 'WARNING: Zalgo text uses combined Unicode characters that may visually overflow their container. Use with caution on social media.',
|
|
26
|
+
previewLabel: 'Real-time Preview',
|
|
27
|
+
emptyLabel: 'Empty',
|
|
28
|
+
charLabel: 'CHARACTERS',
|
|
29
|
+
noteText: 'Note: Some browsers may limit the rendering of combined characters'
|
|
19
30
|
},
|
|
20
31
|
seo: [
|
|
21
32
|
{ type: 'title', text: 'What Is Zalgo Text and How Does Visual Corruption Work?', level: 2 },
|
|
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
|
|
|
15
15
|
copyBtn: 'Copiar Caos',
|
|
16
16
|
copied: '¡Copiado!',
|
|
17
17
|
faqTitle: 'FAQ',
|
|
18
|
-
bibliographyTitle: 'Referencias'
|
|
18
|
+
bibliographyTitle: 'Referencias',
|
|
19
|
+
configTitle: 'Configuración',
|
|
20
|
+
intensity: 'Intensidad',
|
|
21
|
+
upLabel: 'Corrupción Superior',
|
|
22
|
+
midLabel: 'Ruido Central',
|
|
23
|
+
downLabel: 'Corrupción Inferior',
|
|
24
|
+
resetBtn: 'Restablecer Valores',
|
|
25
|
+
warningText: 'ADVERTENCIA: El texto Zalgo utiliza caracteres combinados de Unicode que pueden desbordar visualmente su contenedor. Úsese con precaución en redes sociales.',
|
|
26
|
+
previewLabel: 'Vista Previa en Tiempo Real',
|
|
27
|
+
emptyLabel: 'Vacío',
|
|
28
|
+
charLabel: 'CARACTERES',
|
|
29
|
+
noteText: 'Nota: Algunos navegadores pueden limitar el renderizado de caracteres combinados'
|
|
19
30
|
},
|
|
20
31
|
seo: [
|
|
21
32
|
{ type: 'title', text: '¿Qué es el Texto Zalgo y cómo funciona la corrupción visual?', level: 2 },
|
|
@@ -15,7 +15,18 @@ export const content: ZalgoGeneratorLocaleContent = {
|
|
|
15
15
|
copyBtn: 'Copier le Chaos',
|
|
16
16
|
copied: 'Copié !',
|
|
17
17
|
faqTitle: 'FAQ',
|
|
18
|
-
bibliographyTitle: 'Références'
|
|
18
|
+
bibliographyTitle: 'Références',
|
|
19
|
+
configTitle: 'Configuration',
|
|
20
|
+
intensity: 'Intensité',
|
|
21
|
+
upLabel: 'Corruption Supérieure',
|
|
22
|
+
midLabel: 'Bruit Central',
|
|
23
|
+
downLabel: 'Corruption Inférieure',
|
|
24
|
+
resetBtn: 'Réinitialiser les Valeurs',
|
|
25
|
+
warningText: 'AVERTISSEMENT : Le texte Zalgo utilise des caractères combinés Unicode qui peuvent déborder visuellement de leur conteneur. À utiliser avec précaution sur les réseaux sociaux.',
|
|
26
|
+
previewLabel: 'Aperçu en Temps Réel',
|
|
27
|
+
emptyLabel: 'Vide',
|
|
28
|
+
charLabel: 'CARACTÈRES',
|
|
29
|
+
noteText: 'Note : Certains navigateurs peuvent limiter le rendu des caractères combinés'
|
|
19
30
|
},
|
|
20
31
|
seo: [
|
|
21
32
|
{ type: 'title', text: 'Qu\'est-ce que le Texte Zalgo et comment fonctionne la corruption visuelle ?', level: 2 },
|
|
@@ -14,6 +14,17 @@ export interface ZalgoGeneratorUI {
|
|
|
14
14
|
copied: string;
|
|
15
15
|
faqTitle: string;
|
|
16
16
|
bibliographyTitle: string;
|
|
17
|
+
configTitle: string;
|
|
18
|
+
intensity: string;
|
|
19
|
+
upLabel: string;
|
|
20
|
+
midLabel: string;
|
|
21
|
+
downLabel: string;
|
|
22
|
+
resetBtn: string;
|
|
23
|
+
warningText: string;
|
|
24
|
+
previewLabel: string;
|
|
25
|
+
emptyLabel: string;
|
|
26
|
+
charLabel: string;
|
|
27
|
+
noteText: string;
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
export type ZalgoGeneratorLocaleContent = ToolLocaleContent<ZalgoGeneratorUI>;
|