Spaces:
Running
Running
Update index.html
Browse files- index.html +56 -24
index.html
CHANGED
|
@@ -3,45 +3,66 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
| 6 |
-
<title>Sài Gòn Sync -
|
| 7 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
<style>
|
| 9 |
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700;800&family=Inter:wght@400;600;800&display=swap');
|
|
|
|
| 10 |
body { margin: 0; padding: 0; width: 100vw; height: 100vh; overflow: hidden; background-color: #050508; color: #fff; font-family: 'Inter', sans-serif; display: flex; align-items: center; justify-content: center; }
|
| 11 |
-
.bg-glow { position: fixed; width: 60vw; height: 60vw; background: radial-gradient(circle, rgba(99, 102, 241, 0.15) 0%, rgba(0,0,0,0) 70%); top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 0; }
|
| 12 |
-
.main-container { position: relative; z-index: 10; width: 100%; max-width: 600px; display: flex; flex-direction: column; align-items: center; padding: 20px; transition: all 0.5s; }
|
| 13 |
|
| 14 |
-
|
|
|
|
| 15 |
|
| 16 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
.digit-column { height: 1.1em; overflow: hidden; position: relative; width: 0.65em; text-align: center; }
|
| 18 |
-
.digit-strip { transition: transform 0.
|
| 19 |
-
.digit-val { height: 1.1em; display: flex; align-items: center; justify-content: center; color: #fff; text-shadow: 0 0
|
| 20 |
-
.sep { color: #4f46e5; opacity: 0.8; margin: 0
|
| 21 |
|
| 22 |
-
.stats-bar { background: rgba(255, 255, 255, 0.
|
| 23 |
.stat-box { display: flex; flex-direction: column; align-items: center; }
|
| 24 |
-
.stat-label { font-size:
|
| 25 |
-
.stat-data { font-family: 'JetBrains Mono', monospace; font-size:
|
| 26 |
|
| 27 |
/* Countdown Overlay */
|
| 28 |
#countdown-overlay {
|
| 29 |
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
| 30 |
-
background:
|
| 31 |
flex-direction: column; align-items: center; justify-content: center;
|
| 32 |
}
|
| 33 |
-
#countdown-num { font-size:
|
| 34 |
</style>
|
| 35 |
</head>
|
| 36 |
<body onclick="lockScreen()">
|
| 37 |
<div class="bg-glow"></div>
|
| 38 |
|
| 39 |
<div id="countdown-overlay">
|
| 40 |
-
<div class="text-white text-
|
| 41 |
<div id="countdown-num">10</div>
|
| 42 |
</div>
|
| 43 |
|
| 44 |
-
<div class="main-container"
|
|
|
|
|
|
|
| 45 |
<select id="timezone-selector" class="tz-select" onchange="changeTimezone()">
|
| 46 |
<option value="Asia/Ho_Chi_Minh">🇻🇳 Sài Gòn (GMT+7)</option>
|
| 47 |
<option value="Asia/Singapore">🇸🇬 Singapore (GMT+8)</option>
|
|
@@ -61,12 +82,12 @@
|
|
| 61 |
<div class="digit-column"><div class="digit-strip" id="s2"></div></div>
|
| 62 |
</div>
|
| 63 |
|
| 64 |
-
<div id="full-date" class="text-gray-500 text-[
|
| 65 |
|
| 66 |
<div class="stats-bar">
|
| 67 |
-
<div class="stat-box"><span class="stat-label">Ping</span><span class="stat-data" id="v-ping">--</span></div>
|
| 68 |
-
<div class="stat-box"><span class="stat-label">
|
| 69 |
-
<div class="stat-box"><span class="stat-label">IP</span><span class="stat-data" id="v-ip">--</span></div>
|
| 70 |
</div>
|
| 71 |
</div>
|
| 72 |
|
|
@@ -85,9 +106,16 @@
|
|
| 85 |
});
|
| 86 |
}
|
| 87 |
|
| 88 |
-
function setDigit(id, val) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
function changeTimezone() { selectedTimezone = document.getElementById('timezone-selector').value; }
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
async function sync() {
|
| 93 |
const start = performance.now();
|
|
@@ -95,12 +123,14 @@
|
|
| 95 |
const r = await fetch('https://tuhbooh-networttools.hf.space');
|
| 96 |
const d = await r.json();
|
| 97 |
const ping = Math.round(performance.now() - start);
|
|
|
|
| 98 |
serverOffset = (d.ts * 1000 + ping/2) - Date.now();
|
| 99 |
const offsetAbs = Math.round(Math.abs(serverOffset));
|
| 100 |
|
| 101 |
const elPing = document.getElementById('v-ping');
|
| 102 |
const elOffset = document.getElementById('v-offset');
|
| 103 |
|
|
|
|
| 104 |
elPing.innerText = ping + "ms";
|
| 105 |
elPing.style.color = ping < 150 ? "#4ade80" : (ping < 400 ? "#facc15" : "#f87171");
|
| 106 |
|
|
@@ -114,10 +144,11 @@
|
|
| 114 |
function update() {
|
| 115 |
const now = new Date(Date.now() + serverOffset);
|
| 116 |
|
| 117 |
-
// Logic
|
| 118 |
const nextYear = now.getFullYear() + 1;
|
| 119 |
-
const
|
| 120 |
-
const
|
|
|
|
| 121 |
|
| 122 |
const overlay = document.getElementById('countdown-overlay');
|
| 123 |
if (diff > 0 && diff <= 10) {
|
|
@@ -127,6 +158,7 @@
|
|
| 127 |
overlay.style.display = 'none';
|
| 128 |
}
|
| 129 |
|
|
|
|
| 130 |
const formatter = new Intl.DateTimeFormat('en-GB', {
|
| 131 |
timeZone: selectedTimezone, hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false
|
| 132 |
});
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
| 6 |
+
<title>Sài Gòn Sync - The World's Most Accurate Clock</title>
|
| 7 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
<style>
|
| 9 |
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700;800&family=Inter:wght@400;600;800&display=swap');
|
| 10 |
+
|
| 11 |
body { margin: 0; padding: 0; width: 100vw; height: 100vh; overflow: hidden; background-color: #050508; color: #fff; font-family: 'Inter', sans-serif; display: flex; align-items: center; justify-content: center; }
|
|
|
|
|
|
|
| 12 |
|
| 13 |
+
/* Hiệu ứng nền */
|
| 14 |
+
.bg-glow { position: fixed; width: 60vw; height: 60vw; background: radial-gradient(circle, rgba(99, 102, 241, 0.15) 0%, rgba(0,0,0,0) 70%); top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 0; }
|
| 15 |
|
| 16 |
+
.main-container { position: relative; z-index: 10; width: 100%; max-width: 700px; display: flex; flex-direction: column; align-items: center; padding: 20px; }
|
| 17 |
+
|
| 18 |
+
/* Tiêu đề khẳng định thương hiệu */
|
| 19 |
+
.brand-title {
|
| 20 |
+
font-family: 'JetBrains Mono', monospace;
|
| 21 |
+
font-size: 10px;
|
| 22 |
+
letter-spacing: 5px;
|
| 23 |
+
font-weight: 800;
|
| 24 |
+
background: linear-gradient(to right, #6366f1, #a5b4fc, #6366f1);
|
| 25 |
+
-webkit-background-clip: text;
|
| 26 |
+
-webkit-text-fill-color: transparent;
|
| 27 |
+
text-transform: uppercase;
|
| 28 |
+
margin-bottom: 30px;
|
| 29 |
+
text-align: center;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
.tz-select { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); color: #a5b4fc; padding: 6px 18px; border-radius: 12px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 25px; outline: none; cursor: pointer; transition: 0.3s; }
|
| 33 |
+
.tz-select:hover { background: rgba(99, 102, 241, 0.15); border-color: #6366f1; }
|
| 34 |
+
|
| 35 |
+
.clock-wrapper { display: flex; align-items: center; justify-content: center; font-family: 'JetBrains Mono', monospace; font-size: clamp(3.5rem, 18vw, 7.5rem); font-weight: 800; line-height: 1; gap: 4px; margin-bottom: 15px; }
|
| 36 |
.digit-column { height: 1.1em; overflow: hidden; position: relative; width: 0.65em; text-align: center; }
|
| 37 |
+
.digit-strip { transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1); }
|
| 38 |
+
.digit-val { height: 1.1em; display: flex; align-items: center; justify-content: center; color: #fff; text-shadow: 0 0 30px rgba(99, 102, 241, 0.4); }
|
| 39 |
+
.sep { color: #4f46e5; opacity: 0.8; margin: 0 4px; padding-bottom: 15px; }
|
| 40 |
|
| 41 |
+
.stats-bar { background: rgba(255, 255, 255, 0.02); backdrop-filter: blur(25px); border: 1px solid rgba(255, 255, 255, 0.05); border-radius: 24px; padding: 15px 40px; display: flex; gap: 40px; margin-top: 40px; }
|
| 42 |
.stat-box { display: flex; flex-direction: column; align-items: center; }
|
| 43 |
+
.stat-label { font-size: 7px; text-transform: uppercase; letter-spacing: 2px; color: #4f46e5; margin-bottom: 4px; font-weight: 600; }
|
| 44 |
+
.stat-data { font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 700; transition: color 0.4s; }
|
| 45 |
|
| 46 |
/* Countdown Overlay */
|
| 47 |
#countdown-overlay {
|
| 48 |
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
| 49 |
+
background: #000; display: none; z-index: 100;
|
| 50 |
flex-direction: column; align-items: center; justify-content: center;
|
| 51 |
}
|
| 52 |
+
#countdown-num { font-size: 18rem; font-weight: 900; color: #f87171; text-shadow: 0 0 60px rgba(248, 113, 113, 0.6); font-family: 'JetBrains Mono'; }
|
| 53 |
</style>
|
| 54 |
</head>
|
| 55 |
<body onclick="lockScreen()">
|
| 56 |
<div class="bg-glow"></div>
|
| 57 |
|
| 58 |
<div id="countdown-overlay">
|
| 59 |
+
<div class="text-white text-2xl tracking-[15px] mb-10 font-black">HAPPY NEW YEAR</div>
|
| 60 |
<div id="countdown-num">10</div>
|
| 61 |
</div>
|
| 62 |
|
| 63 |
+
<div class="main-container">
|
| 64 |
+
<div class="brand-title">Đồng hồ chính xác nhất thế giới</div>
|
| 65 |
+
|
| 66 |
<select id="timezone-selector" class="tz-select" onchange="changeTimezone()">
|
| 67 |
<option value="Asia/Ho_Chi_Minh">🇻🇳 Sài Gòn (GMT+7)</option>
|
| 68 |
<option value="Asia/Singapore">🇸🇬 Singapore (GMT+8)</option>
|
|
|
|
| 82 |
<div class="digit-column"><div class="digit-strip" id="s2"></div></div>
|
| 83 |
</div>
|
| 84 |
|
| 85 |
+
<div id="full-date" class="text-gray-500 text-[11px] tracking-[5px] uppercase font-bold">---</div>
|
| 86 |
|
| 87 |
<div class="stats-bar">
|
| 88 |
+
<div class="stat-box"><span class="stat-label">Network Ping</span><span class="stat-data" id="v-ping">--</span></div>
|
| 89 |
+
<div class="stat-box"><span class="stat-label">Time Offset</span><span class="stat-data" id="v-offset">--</span></div>
|
| 90 |
+
<div class="stat-box"><span class="stat-label">Server IP</span><span class="stat-data" id="v-ip">--</span></div>
|
| 91 |
</div>
|
| 92 |
</div>
|
| 93 |
|
|
|
|
| 106 |
});
|
| 107 |
}
|
| 108 |
|
| 109 |
+
function setDigit(id, val) {
|
| 110 |
+
const strip = document.getElementById(id);
|
| 111 |
+
if (strip) strip.style.transform = `translateY(-${val * 1.1}em)`;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
function changeTimezone() { selectedTimezone = document.getElementById('timezone-selector').value; }
|
| 115 |
+
|
| 116 |
+
async function lockScreen() {
|
| 117 |
+
if ('wakeLock' in navigator) { try { wakeLock = await navigator.wakeLock.request('screen'); } catch(e){} }
|
| 118 |
+
}
|
| 119 |
|
| 120 |
async function sync() {
|
| 121 |
const start = performance.now();
|
|
|
|
| 123 |
const r = await fetch('https://tuhbooh-networttools.hf.space');
|
| 124 |
const d = await r.json();
|
| 125 |
const ping = Math.round(performance.now() - start);
|
| 126 |
+
|
| 127 |
serverOffset = (d.ts * 1000 + ping/2) - Date.now();
|
| 128 |
const offsetAbs = Math.round(Math.abs(serverOffset));
|
| 129 |
|
| 130 |
const elPing = document.getElementById('v-ping');
|
| 131 |
const elOffset = document.getElementById('v-offset');
|
| 132 |
|
| 133 |
+
// Màu sắc động
|
| 134 |
elPing.innerText = ping + "ms";
|
| 135 |
elPing.style.color = ping < 150 ? "#4ade80" : (ping < 400 ? "#facc15" : "#f87171");
|
| 136 |
|
|
|
|
| 144 |
function update() {
|
| 145 |
const now = new Date(Date.now() + serverOffset);
|
| 146 |
|
| 147 |
+
// Logic New Year Countdown
|
| 148 |
const nextYear = now.getFullYear() + 1;
|
| 149 |
+
const newYearStr = `Jan 1, ${nextYear} 00:00:00`;
|
| 150 |
+
const newYearDate = new Date(new Date(newYearStr).toLocaleString("en-US", {timeZone: selectedTimezone}));
|
| 151 |
+
const diff = (newYearDate - now) / 1000;
|
| 152 |
|
| 153 |
const overlay = document.getElementById('countdown-overlay');
|
| 154 |
if (diff > 0 && diff <= 10) {
|
|
|
|
| 158 |
overlay.style.display = 'none';
|
| 159 |
}
|
| 160 |
|
| 161 |
+
// Update Clock
|
| 162 |
const formatter = new Intl.DateTimeFormat('en-GB', {
|
| 163 |
timeZone: selectedTimezone, hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false
|
| 164 |
});
|