BlueSkyXN commited on
Commit
7481290
·
verified ·
1 Parent(s): 39d8003

Update index.html (#1)

Browse files

- Update index.html (c784660e72c3d23f50fbea941c987c2aa5fa43ef)

Files changed (1) hide show
  1. index.html +324 -19
index.html CHANGED
@@ -1,19 +1,324 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Claude 刷新倒计时 - 终极炫彩背景</title>
7
+
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+
10
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap" rel="stylesheet">
11
+
12
+ <style>
13
+ /* 页面主体样式 */
14
+ body {
15
+ font-family: 'Inter', sans-serif; /* 应用 Inter 字体 */
16
+ /* 全新终极炫彩背景渐变: "霓虹幻想" 主题 */
17
+ background: linear-gradient(135deg,
18
+ #ff00ff 0%, /* Magenta */
19
+ #ff0080 15%, /* Deep Pink */
20
+ #0077ff 30%, /* Bright Blue */
21
+ #00ffdd 45%, /* Cyan/Turquoise */
22
+ #aaff00 60%, /* Lime Green */
23
+ #ffaa00 75%, /* Orange */
24
+ #ff0000 90%, /* Red */
25
+ #ff00ff 100% /* Magenta (to loop smoothly for animation) */
26
+ );
27
+ background-size: 400% 400%; /* 增大背景尺寸,为动画提供更广阔的移动空间 */
28
+ animation: gradientAnimation 25s ease infinite; /* 应用背景渐变动画,25秒周期,平滑无限循环 */
29
+ color: #333; /* 页面默认文字颜色 (主要被卡片内样式覆盖) */
30
+ display: flex; /* 使用 Flexbox 布局 */
31
+ justify-content: center; /* 水平居中 */
32
+ align-items: center; /* 垂直居中 */
33
+ min-height: 100vh; /* 最小高度为视口高度,确保内容撑满屏幕 */
34
+ margin: 0; /* 移除默认外边距 */
35
+ padding: 1rem; /* 页面内边距,防止内容紧贴边缘 */
36
+ overflow-x: hidden; /* 防止背景动画可能导致的水平滚动条 */
37
+ }
38
+
39
+ /* 背景渐变动画定义 */
40
+ @keyframes gradientAnimation {
41
+ 0% { background-position: 0% 50%; } /* 动画开始时背景位置 */
42
+ 50% { background-position: 100% 50%; } /* 动画中间状态背景位置 */
43
+ 100% { background-position: 0% 50%; } /* 动画结束时背景位置,形成循环 */
44
+ }
45
+
46
+ /* Bento Grid 容器样式 */
47
+ .bento-grid {
48
+ display: grid; /* 使用 Grid 布局 */
49
+ grid-template-columns: repeat(1, 1fr); /* 移动端默认为单列 */
50
+ gap: 1.5rem; /* 网格项之间的间距 */
51
+ width: 100%; /* 宽度占满父容器 */
52
+ max-width: 900px; /* 最大宽度限制,防止在大屏幕上过宽 */
53
+ position: relative; /* 相对定位,确保在动画背景之上 */
54
+ z-index: 1; /* 层级提高,确保在背景之上 */
55
+ }
56
+
57
+ /* 响应式设计:中等屏幕及以上 (768px) */
58
+ @media (min-width: 768px) {
59
+ .bento-grid {
60
+ grid-template-columns: repeat(2, 1fr); /* 变为两列布局 */
61
+ grid-template-rows: repeat(2, minmax(175px, auto)); /* 定义两行,每行最小高度175px */
62
+ }
63
+ /* 定义网格区域,方便控制卡片位置 */
64
+ .main-countdown-box { grid-area: 1 / 1 / 2 / 2; } /* 左上角卡片 */
65
+ .next-refresh-box { grid-area: 1 / 2 / 2 / 3; } /* 右上角卡片 */
66
+ .last-refresh-box { grid-area: 2 / 1 / 3 / 2; } /* 左下角卡片 */
67
+ .base-time-box { grid-area: 2 / 2 / 3 / 3; } /* 右下角卡片 */
68
+ }
69
+
70
+ /* Bento Box (卡片) 通用样式 */
71
+ .bento-box {
72
+ border-radius: 1.25rem; /* 卡片圆角 */
73
+ padding: 1.75rem; /* 卡片内边距 */
74
+ box-shadow: 0 12px 45px 0 rgba(0, 0, 0, 0.4); /* 卡片阴影效果 */
75
+ transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; /* 过渡动画:变形和阴影 */
76
+ display: flex; /* 使用 Flexbox 布局 */
77
+ flex-direction: column; /* 子元素垂直排列 */
78
+ justify-content: space-around; /* 子元素在垂直方向上均匀分布空间 */
79
+ text-align: center; /* 文字居中 */
80
+ color: #ffffff; /* 卡片内文字颜色为白色 */
81
+ }
82
+
83
+ /* 卡片鼠标悬浮效果 */
84
+ .bento-box:hover {
85
+ transform: translateY(-10px) scale(1.04); /* 轻微上移并放大 */
86
+ box-shadow: 0 18px 60px 0 rgba(0, 0, 0, 0.45); /* 增强阴影效果 */
87
+ }
88
+
89
+ /* 特定卡片的背景渐变样式 */
90
+ /* 左上角:下次刷新倒计时卡片 */
91
+ .main-countdown-box {
92
+ background: linear-gradient(135deg, #5433FF 0%, #20BDFF 50%, #A5FECB 100%); /* 靛蓝 -> 亮蓝 -> 薄荷绿 */
93
+ }
94
+ /* 左下角:上次刷新时间卡片 */
95
+ .last-refresh-box {
96
+ background: linear-gradient(135deg, #00b09b 0%, #96c93d 50%, #00d2ff 100%); /* 青绿 -> 亮青柠 -> 海洋蓝 */
97
+ }
98
+ /* 右上角:预计下次刷新卡片 */
99
+ .next-refresh-box {
100
+ background: linear-gradient(135deg, #6a11cb 0%, #fc00ff 50%, #00dbde 100%); /* 深紫 -> 亮粉 -> 青蓝 */
101
+ }
102
+ /* 右下角:基准刷新时间卡片 */
103
+ .base-time-box {
104
+ background: linear-gradient(135deg, #ff4e50 0%, #f9d423 50%, #ffc947 100%); /* 亮红 -> 鲜黄 -> 暖橙黄 */
105
+ }
106
+
107
+ /* 卡片内标题 (h2) 样式 */
108
+ .bento-box h2 {
109
+ font-size: 1.0rem; /* 字体大小 */
110
+ font-weight: 700; /* 字体粗细 (加粗) */
111
+ color: rgba(255, 255, 255, 0.95); /* 标题颜色 (略透明的白色) */
112
+ margin-bottom: 0.6rem; /* 标题下外边距 */
113
+ text-shadow: 0 1px 4px rgba(0,0,0,0.3); /* 文字阴影,增强可读性 */
114
+ }
115
+
116
+ /* 卡片内段落 (p) 和强调文本 (span.accent-text) 样式 */
117
+ .bento-box p, .bento-box span.accent-text {
118
+ font-size: 1.3rem; /* 字体大小 */
119
+ font-weight: 500; /* 字体粗细 (中等) */
120
+ color: #ffffff; /* 文字颜色 */
121
+ text-shadow: 0 1px 3px rgba(0,0,0,0.2); /* 文字阴影 */
122
+ }
123
+
124
+ /* 卡片内小号文本 (通常用于 "(北京时间)") 样式 */
125
+ .bento-box .text-sm {
126
+ font-size: 0.8rem; /* 字体大小 */
127
+ color: rgba(255, 255, 255, 0.85); /* 文字颜色 (更透明的白色) */
128
+ display: block; /* 块级元素,确保换行 */
129
+ margin-top: 0.3rem; /* 上外边距 */
130
+ }
131
+
132
+ /* 倒计时数字特定样式 */
133
+ .countdown-timer {
134
+ font-size: 2.85rem; /* 字体大小 */
135
+ font-weight: 800; /* 字体粗细 (特粗) */
136
+ color: #ffffff; /* 文字颜色 */
137
+ text-shadow: 0 2px 6px rgba(0,0,0,0.35); /* 文字阴影 */
138
+ letter-spacing: -0.025em; /* 字间距 */
139
+ margin: 0.5rem 0; /* 上下外边距 */
140
+ }
141
+
142
+ /* 响应式设计:小屏幕及以上 (640px) 的倒计时数字调整 */
143
+ @media (min-width: 640px) {
144
+ .countdown-timer {
145
+ font-size: 3.4rem; /* 增大字体 */
146
+ }
147
+ }
148
+ </style>
149
+ </head>
150
+ <body>
151
+ <div class="bento-grid">
152
+ <div class="bento-box main-countdown-box">
153
+ <h2>下次刷新倒计时</h2>
154
+ <span id="countdownDisplay" class="countdown-timer">--:--:--</span>
155
+ </div>
156
+
157
+ <div class="bento-box next-refresh-box">
158
+ <h2>预计下次刷新</h2>
159
+ <p><span id="nextRefreshTimeDisplay" class="accent-text">正在计算...</span><br><span class="text-sm">(北京时间)</span></p>
160
+ </div>
161
+
162
+ <div class="bento-box last-refresh-box">
163
+ <h2>上次刷新时间</h2>
164
+ <p><span id="lastRefreshTimeDisplay" class="accent-text">正在计算...</span><br><span class="text-sm">(北京时间)</span></p>
165
+ </div>
166
+
167
+ <div class="bento-box base-time-box">
168
+ <h2>基准刷新时间</h2>
169
+ <p><span id="baseTimeDisplay" class="accent-text">加载中...</span><br><span class="text-sm">(北京时间)</span></p>
170
+ </div>
171
+ </div>
172
+
173
+ <script>
174
+ // --- 配置常量 ---
175
+ // 基准刷新时间 (北京时间 ISO 8601 格式, +08:00 表示东八区)
176
+ // 这是计算所有未来刷新时间的基础锚点。
177
+ const baseRefreshTimeCST_ISO = "2025-05-08T19:00:00+08:00";
178
+ // 刷新周期 (小时)
179
+ const refreshIntervalHours = 5;
180
+ // 将刷新周期转换为毫秒
181
+ const intervalMilliseconds = refreshIntervalHours * 60 * 60 * 1000;
182
+
183
+ // --- DOM 元素获取 ---
184
+ // 获取用于显示倒计时的元素
185
+ const countdownDisplay = document.getElementById('countdownDisplay');
186
+ // 获取用于显示下一次刷新时间的元素
187
+ const nextRefreshTimeDisplay = document.getElementById('nextRefreshTimeDisplay');
188
+ // 获取用于显示上一次刷新时间的元素
189
+ const lastRefreshTimeDisplay = document.getElementById('lastRefreshTimeDisplay');
190
+ // 获取用于显示基准刷新时间的元素
191
+ const baseTimeDisplay = document.getElementById('baseTimeDisplay');
192
+
193
+ // --- 状态变量 ---
194
+ // 用于跟踪已显示的下一次刷新时间点 (Epoch毫秒数),避免不必要的DOM更新
195
+ let displayedTargetTimeEpoch = 0;
196
+
197
+ // --- 辅助函数 ---
198
+
199
+ /**
200
+ * 计算下一次��新时间点。
201
+ * 基于基准刷新时间和当前时间,向前推算直到找到第一个未来的刷新时间点。
202
+ * @returns {Date} 下一次刷新的 Date 对象 (内部为UTC时间)。
203
+ */
204
+ function calculateNextRefresh() {
205
+ // 将ISO格式的基准时间字符串转换为Date对象。
206
+ // Date对象内部总是以UTC存储时间。包含时区信息的字符串会被正确解析。
207
+ const baseTime = new Date(baseRefreshTimeCST_ISO);
208
+ // 获取当前时间的Date对象。
209
+ const now = new Date();
210
+
211
+ // 从基准时间的Epoch毫秒数开始计算。
212
+ let nextRefreshEpoch = baseTime.getTime();
213
+
214
+ // 循环增加刷新间隔,直到计算出的刷新时间点晚于当前时间。
215
+ // 这样可以确保即使页面加载时已经错过了多个刷新周期,也能找到正确的下一个刷新点。
216
+ while (nextRefreshEpoch <= now.getTime()) {
217
+ nextRefreshEpoch += intervalMilliseconds;
218
+ }
219
+ // 返回计算得到的下一个刷新时间点的Date对象。
220
+ return new Date(nextRefreshEpoch);
221
+ }
222
+
223
+ /**
224
+ * 将 Date 对象格式化为北京时间字符串 (YYYY-MM-DD HH:MM:SS)。
225
+ * @param {Date} dateObj - 需要格式化的 Date 对象。
226
+ * @returns {string} 格式化后的北京时间字符串,或在出错时返回错误提示。
227
+ */
228
+ function formatToBeijingTime(dateObj) {
229
+ // 检查传入的是否是有效的Date对象。
230
+ if (!dateObj || isNaN(dateObj.getTime())) {
231
+ return "无效日期";
232
+ }
233
+ try {
234
+ // 使用 toLocaleString 方法进行时区转换和格式化。
235
+ // 'Asia/Shanghai' 代表中国标准时间 (北京时间)。
236
+ return dateObj.toLocaleString('zh-CN', { // 'zh-CN' 用于中文格式
237
+ timeZone: 'Asia/Shanghai',
238
+ year: 'numeric', // 四位数字年份
239
+ month: '2-digit', // 两位数字月份
240
+ day: '2-digit', // 两位数字日期
241
+ hour: '2-digit', // 两位数字小时 (24小时制)
242
+ minute: '2-digit', // 两位数字分钟
243
+ second: '2-digit', // 两位数字秒
244
+ hour12: false // 使用24小时制
245
+ }).replace(/\//g, '-'); // 将日期中的 '/' 替换为 '-',以符合 YYYY-MM-DD 格式。
246
+ } catch (e) {
247
+ // 如果格式化过程中发生错误,则打印错误到控制台并返回提示信息。
248
+ console.error("日期格式化错误:", e);
249
+ return "格式化错误";
250
+ }
251
+ }
252
+
253
+ // --- 主要倒计时逻辑与UI更新函数 ---
254
+
255
+ /**
256
+ * 更新倒计时显示以及相关的刷新时间信息。
257
+ * 此函数会被 setInterval 每秒调用一次。
258
+ */
259
+ function updateCountdown() {
260
+ // 获取当前时间。
261
+ const now = new Date();
262
+ // 计算下一次刷新时间点。
263
+ const targetDate = calculateNextRefresh(); // 内部为UTC
264
+
265
+ // 优化:仅当目标刷新时间点发生变化时 (即进入新的刷新周期),才更新“下次刷新时间”和“上次刷新时间”的显示。
266
+ // 这样可以避免每秒都对这两个DOM元素进行不必要的重绘。
267
+ if (targetDate.getTime() !== displayedTargetTimeEpoch) {
268
+ // 更新“预计下次刷新”的显示。
269
+ nextRefreshTimeDisplay.textContent = formatToBeijingTime(targetDate);
270
+
271
+ // 计算并显示“上次刷新时间”。
272
+ // 上次刷新时间 = 下次刷新时间 - một刷新周期。
273
+ const lastRefreshTimeDate = new Date(targetDate.getTime() - intervalMilliseconds);
274
+ lastRefreshTimeDisplay.textContent = formatToBeijingTime(lastRefreshTimeDate);
275
+
276
+ // 更新已显示的目标时间点。
277
+ displayedTargetTimeEpoch = targetDate.getTime();
278
+ }
279
+
280
+ // 计算距离下一次刷新的剩余时间 (毫秒)。
281
+ const timeRemaining = targetDate.getTime() - now.getTime();
282
+
283
+ // 如果已到达或超过刷新时间点。
284
+ if (timeRemaining <= 0) {
285
+ // 将倒计时显示为 "00:00:00"。
286
+ countdownDisplay.textContent = "00:00:00";
287
+ // 在下一个 setInterval 周期,calculateNextRefresh 会自动计算出新的未来刷新点。
288
+ return; // 提前退出,避免显示负数。
289
+ }
290
+
291
+ // 将剩余毫秒数转换为时、分、秒。
292
+ const hours = Math.floor(timeRemaining / (1000 * 60 * 60));
293
+ const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));
294
+ const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);
295
+
296
+ // 格式化为 HH:MM:SS 并更新倒计时显示。
297
+ // String().padStart(2, '0') 用于确保单位数时前面补零 (例如 7 -> "07")。
298
+ countdownDisplay.textContent =
299
+ `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
300
+ }
301
+
302
+ // --- 初始化函数 ---
303
+
304
+ /**
305
+ * 页面加载完成后执行的初始化操作。
306
+ */
307
+ function initializePage() {
308
+ // 1. 显示固定的基准刷新时间。
309
+ const baseDate = new Date(baseRefreshTimeCST_ISO);
310
+ baseTimeDisplay.textContent = formatToBeijingTime(baseDate);
311
+
312
+ // 2. 立即调用一次 updateCountdown,以便页面加载时就能看到正确的初始状态。
313
+ updateCountdown();
314
+
315
+ // 3. 设置定时器,每秒调用一次 updateCountdown 函数来实时更新倒计时。
316
+ setInterval(updateCountdown, 1000); // 1000毫秒 = 1秒
317
+ }
318
+
319
+ // --- 事件监听 ---
320
+ // 确保在整个HTML文档加载并解析完成后再执行初始化脚本。
321
+ document.addEventListener('DOMContentLoaded', initializePage);
322
+ </script>
323
+ </body>
324
+ </html>