Compare commits
No commits in common. "b7568305598443a6c15b8d153976da9f26c4bdd0" and "470f0f389c8a99f3b4da64202cea67b1e69488b2" have entirely different histories.
b756830559
...
470f0f389c
|
|
@ -45,14 +45,18 @@ const POLL_INTERVAL_MS = 10_000;
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="mt-8 flex items-center justify-center font-mono text-colorSecondary sm:mt-10"
|
class="mt-8 flex items-end justify-center gap-1 font-mono text-colorSecondary sm:mt-10"
|
||||||
style="text-shadow: 0 0 40px rgba(203,161,106,0.35)"
|
style="text-shadow: 0 0 40px rgba(203,161,106,0.35)"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
id="counter-number"
|
id="group-thousands"
|
||||||
class="counter-number text-[clamp(3.5rem,16vw,9rem)] font-bold tabular-nums"
|
class="countdown hidden text-[clamp(3.5rem,16vw,9rem)]"
|
||||||
aria-hidden="true"
|
>
|
||||||
>0</span>
|
<span id="digit-thousands" style="--value:0;" aria-hidden="true">0</span>
|
||||||
|
</span>
|
||||||
|
<span class="countdown text-[clamp(3.5rem,16vw,9rem)]">
|
||||||
|
<span id="digit-rest" style="--value:0;" aria-hidden="true">0</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p id="sr-count" class="sr-only" aria-live="polite">
|
<p id="sr-count" class="sr-only" aria-live="polite">
|
||||||
|
|
@ -88,11 +92,19 @@ const POLL_INTERVAL_MS = 10_000;
|
||||||
.counter-card {
|
.counter-card {
|
||||||
animation: counter-fade-in 0.6s ease-out;
|
animation: counter-fade-in 0.6s ease-out;
|
||||||
}
|
}
|
||||||
.counter-number {
|
.countdown {
|
||||||
display: inline-block;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
.counter-number.counter-bump {
|
/* Fix para Safari/iOS: sin esto, las dos capas del dígito (actual y
|
||||||
animation: counter-bump 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
siguiente) no quedan recortadas ni aisladas y se ven superpuestas. */
|
||||||
|
.countdown > * {
|
||||||
|
overflow: clip;
|
||||||
|
isolation: isolate;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
.pulse-update {
|
||||||
|
animation: counter-pulse 0.5s ease-out;
|
||||||
}
|
}
|
||||||
@keyframes counter-fade-in {
|
@keyframes counter-fade-in {
|
||||||
from {
|
from {
|
||||||
|
|
@ -104,18 +116,15 @@ const POLL_INTERVAL_MS = 10_000;
|
||||||
transform: translateY(0) scale(1);
|
transform: translateY(0) scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes counter-bump {
|
@keyframes counter-pulse {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
35% {
|
30% {
|
||||||
transform: scale(1.12) translateY(-0.05em);
|
transform: scale(1.06);
|
||||||
opacity: 0.55;
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: scale(1) translateY(0);
|
transform: scale(1);
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -123,12 +132,15 @@ const POLL_INTERVAL_MS = 10_000;
|
||||||
<script is:inline define:vars={{ POLL_INTERVAL_MS }}>
|
<script is:inline define:vars={{ POLL_INTERVAL_MS }}>
|
||||||
const ENDPOINT = "/api/voluntarios/count";
|
const ENDPOINT = "/api/voluntarios/count";
|
||||||
|
|
||||||
const counterNumber = document.getElementById("counter-number");
|
const groupThousands = document.getElementById("group-thousands");
|
||||||
|
const digitThousands = document.getElementById("digit-thousands");
|
||||||
|
const digitRest = document.getElementById("digit-rest");
|
||||||
const srCount = document.getElementById("sr-count");
|
const srCount = document.getElementById("sr-count");
|
||||||
const statusDot = document.getElementById("status-dot");
|
const statusDot = document.getElementById("status-dot");
|
||||||
const statusPing = document.getElementById("status-ping");
|
const statusPing = document.getElementById("status-ping");
|
||||||
const statusText = document.getElementById("status-text");
|
const statusText = document.getElementById("status-text");
|
||||||
const lastUpdated = document.getElementById("last-updated");
|
const lastUpdated = document.getElementById("last-updated");
|
||||||
|
const numberWrap = digitRest.closest("div");
|
||||||
|
|
||||||
const STATUS_STYLES = {
|
const STATUS_STYLES = {
|
||||||
live: { color: "bg-emerald-400", text: "En vivo" },
|
live: { color: "bg-emerald-400", text: "En vivo" },
|
||||||
|
|
@ -139,15 +151,31 @@ const POLL_INTERVAL_MS = 10_000;
|
||||||
let currentCount = null;
|
let currentCount = null;
|
||||||
|
|
||||||
function renderCount(count) {
|
function renderCount(count) {
|
||||||
const safe = Math.max(0, Math.min(999999, Math.round(count)));
|
const safe = Math.max(0, Math.min(99999, Math.round(count)));
|
||||||
|
const thousands = Math.floor(safe / 1000);
|
||||||
|
const rest = safe % 1000;
|
||||||
|
|
||||||
|
if (thousands > 0) {
|
||||||
|
groupThousands.classList.remove("hidden");
|
||||||
|
digitThousands.style.setProperty("--value", String(thousands));
|
||||||
|
digitThousands.textContent = String(thousands);
|
||||||
|
digitThousands.setAttribute("aria-label", String(thousands));
|
||||||
|
digitRest.style.setProperty("--digits", "3");
|
||||||
|
} else {
|
||||||
|
groupThousands.classList.add("hidden");
|
||||||
|
digitRest.style.removeProperty("--digits");
|
||||||
|
}
|
||||||
|
|
||||||
|
digitRest.style.setProperty("--value", String(rest));
|
||||||
|
digitRest.textContent = String(rest);
|
||||||
|
digitRest.setAttribute("aria-label", String(rest));
|
||||||
|
|
||||||
counterNumber.textContent = safe.toLocaleString("es-ES");
|
|
||||||
srCount.textContent = `${safe} ${safe === 1 ? "voluntario registrado" : "voluntarios registrados"}`;
|
srCount.textContent = `${safe} ${safe === 1 ? "voluntario registrado" : "voluntarios registrados"}`;
|
||||||
|
|
||||||
if (currentCount !== null && currentCount !== safe) {
|
if (currentCount !== null && currentCount !== safe && numberWrap) {
|
||||||
counterNumber.classList.remove("counter-bump");
|
numberWrap.classList.remove("pulse-update");
|
||||||
void counterNumber.offsetWidth;
|
void numberWrap.offsetWidth;
|
||||||
counterNumber.classList.add("counter-bump");
|
numberWrap.classList.add("pulse-update");
|
||||||
}
|
}
|
||||||
currentCount = safe;
|
currentCount = safe;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue