hugo-teek is loading...

v5-给情侣头像下加个昵称

最后更新于:

问题

  1<template>
  2  <div class="page-wrapper">
  3    <!-- 背景装饰元素 - 全屏覆盖 -->
  4    <div class="bg-decoration">
  5      <div class="heart-decoration" style="top: 10%; left: 5%; animation-delay: 0s;"></div>
  6      <div class="heart-decoration" style="top: 20%; right: 10%; animation-delay: 1s;"></div>
  7      <div class="heart-decoration" style="bottom: 30%; left: 15%; animation-delay: 2s;"></div>
  8      <div class="heart-decoration" style="bottom: 20%; right: 5%; animation-delay: 3s;"></div>
  9      <div class="heart-decoration" style="top: 40%; right: 20%; animation-delay: 1.5s;"></div>
 10    </div>
 11
 12    <!-- 内容容器 - 居中且有最大宽度 -->
 13    <div class="content-container">
 14      <!-- 标题区域 -->
 15      <header class="header">
 16        <h1 class="main-title">我们的爱情计时器</h1>
 17        <p class="subtitle">记录从相遇的那一刻起,每一段珍贵的时光</p>
 18        <div class="divider">
 19          <div class="divider-dot"></div>
 20        </div>
 21      </header>
 22
 23      <!-- 情侣头像区域 -->
 24      <div class="avatar-container">
 25        <!-- 左侧头像 -->
 26        <div class="avatar-wrapper left-avatar">
 27          <img src="https://img.onedayxyy.cn/images/hg.jpg" alt="情侣头像1" class="avatar-image">
 28          <div class="gender-indicator male">
 29            <span class="icon">♂</span>
 30          </div>
 31        </div>
 32        
 33        <!-- 中间跳动的爱心 -->
 34        <div class="heart-connector">
 35          <div class="heart-pulse"></div>
 36          <div class="heart-icon">❤</div>
 37        </div>
 38        
 39        <!-- 右侧头像 -->
 40        <div class="avatar-wrapper right-avatar">
 41          <img src="https://img.onedayxyy.cn/images/fxj.jpg" alt="情侣头像2" class="avatar-image">
 42          <div class="gender-indicator female">
 43            <span class="icon">♀</span>
 44          </div>
 45        </div>
 46      </div>
 47
 48      <!-- 相识日期展示 -->
 49      <div class="meet-date">
 50        我们相识于:<span class="highlight">2025年5月29日 17:00</span>
 51      </div>
 52
 53      <!-- 计时器主区域 -->
 54      <div class="timer-grid">
 55        <!-- 年 -->
 56        <div class="timer-card">
 57          <div :class="{'number-change': isChanged.years}" class="time-value">{{ years }}</div>
 58          <div class="time-label">年</div>
 59        </div>
 60        
 61        <!-- 月 -->
 62        <div class="timer-card">
 63          <div :class="{'number-change': isChanged.months}" class="time-value">{{ months }}</div>
 64          <div class="time-label">月</div>
 65        </div>
 66        
 67        <!-- 日 -->
 68        <div class="timer-card">
 69          <div :class="{'number-change': isChanged.days}" class="time-value">{{ days }}</div>
 70          <div class="time-label">日</div>
 71        </div>
 72        
 73        <!-- 时 -->
 74        <div class="timer-card">
 75          <div :class="{'number-change': isChanged.hours}" class="time-value">{{ hours }}</div>
 76          <div class="time-label">时</div>
 77        </div>
 78        
 79        <!-- 分 -->
 80        <div class="timer-card">
 81          <div :class="{'number-change': isChanged.minutes}" class="time-value">{{ minutes }}</div>
 82          <div class="time-label">分</div>
 83        </div>
 84        
 85        <!-- 秒 -->
 86        <div class="timer-card">
 87          <div :class="{'number-change': isChanged.seconds}" class="time-value">{{ seconds }}</div>
 88          <div class="time-label">秒</div>
 89        </div>
 90      </div>
 91
 92      <!-- 爱情寄语 -->
 93      <div class="love-message">
 94        <p>"时光荏苒,爱意渐浓<br>你愿意,我值得<br>每一秒都是我们爱情的见证"</p>
 95        <div class="message-heart">❤</div>
 96      </div>
 97
 98      <!-- 页脚 -->
 99      <footer class="footer">
100        愿我们的故事,永远继续下去...
101      </footer>
102    </div>
103  </div>
104</template>
105
106<script setup>
107import { ref, onMounted, onUnmounted } from 'vue';
108
109// 时间数据
110const years = ref(0);
111const months = ref(0);
112const days = ref(0);
113const hours = ref(0);
114const minutes = ref(0);
115const seconds = ref(0);
116
117// 用于检测数值变化的状态
118const isChanged = ref({
119  years: false,
120  months: false,
121  days: false,
122  hours: false,
123  minutes: false,
124  seconds: false
125});
126
127// 存储上一次的值
128let previousValues = {
129  years: 0,
130  months: 0,
131  days: 0,
132  hours: 0,
133  minutes: 0,
134  seconds: 0
135};
136
137// 相识日期:2025年5月29日17:00
138const meetDate = new Date(2025, 4, 29, 17, 0, 0);
139let timer = null;
140
141// 计算时间差
142function calculateTimeDifference() {
143  const now = new Date();
144  const diff = now - meetDate;
145
146  // 计算总秒数
147  const totalSeconds = Math.floor(diff / 1000);
148  
149  // 计算秒
150  const seconds = totalSeconds % 60;
151  
152  // 计算总分钟数
153  const totalMinutes = Math.floor(totalSeconds / 60);
154  const minutes = totalMinutes % 60;
155  
156  // 计算总小时数
157  const totalHours = Math.floor(totalMinutes / 60);
158  const hours = totalHours % 24;
159  
160  // 计算总天数
161  const totalDays = Math.floor(totalHours / 24);
162  
163  // 计算年、月、日
164  let years = 0;
165  let months = 0;
166  let remainingDays = totalDays;
167  
168  // 计算年数(按365天计算)
169  years = Math.floor(remainingDays / 365);
170  remainingDays = remainingDays % 365;
171  
172  // 计算月数(按平均30.44天计算)
173  months = Math.floor(remainingDays / 30.44);
174  const days = Math.floor(remainingDays % 30.44);
175  
176  return { years, months, days, hours, minutes, seconds };
177}
178
179// 更新计时器显示
180function updateTimer() {
181  const timeDiff = calculateTimeDifference();
182  
183  // 检查每个值是否变化,更新并添加动画
184  Object.keys(timeDiff).forEach(key => {
185    const value = timeDiff[key];
186    const displayValue = ['hours', 'minutes', 'seconds'].includes(key) 
187      ? value.toString().padStart(2, '0') 
188      : value;
189      
190    if (previousValues[key] !== value) {
191      // 更新值
192      eval(`${key}.value = '${displayValue}'`);
193      // 触发动画
194      isChanged.value[key] = true;
195      setTimeout(() => {
196        isChanged.value[key] = false;
197      }, 500);
198      // 更新上一次的值
199      previousValues[key] = value;
200    }
201  });
202}
203
204// 组件挂载时初始化计时器
205onMounted(() => {
206  updateTimer();
207  timer = setInterval(updateTimer, 1000);
208});
209
210// 组件卸载时清除计时器
211onUnmounted(() => {
212  if (timer) clearInterval(timer);
213});
214</script>
215
216<style>
217/* 全局样式 */
218:root {
219  --color-love-light: #FFD1DC; /* 浅粉色 */
220  --color-love: #FF69B4; /* 粉色 */
221  --color-love-dark: #C71585; /* 深粉色 */
222  --color-romantic-light: #E6E6FA; /* 浅紫色 */
223  --color-romantic-dark: #9370DB; /* 深紫色 */
224  --shadow-soft: 0 4px 15px rgba(0, 0, 0, 0.05);
225  --shadow-medium: 0 10px 25px -5px rgba(255, 105, 180, 0.3);
226}
227
228* {
229  margin: 0;
230  padding: 0;
231  box-sizing: border-box;
232}
233
234html, body {
235  width: 100%;
236  min-height: 100vh;
237  overflow-x: hidden; /* 防止横向滚动 */
238}
239</style>
240
241<style scoped>
242/* 页面外层容器 - 全屏覆盖 */
243.page-wrapper {
244  width: 100%;
245  min-height: 100vh;
246  /* 粉色渐变背景 - 全屏覆盖 */
247  background: linear-gradient(135deg, 
248    var(--color-love-light) 20%, 
249    var(--color-romantic-light) 50%, 
250    var(--color-love-light) 80%);
251  position: relative;
252}
253
254/* 背景装饰 - 全屏覆盖 */
255.bg-decoration {
256  position: absolute;
257  width: 100%;
258  height: 100%;
259  top: 0;
260  left: 0;
261  z-index: 0;
262  overflow: hidden;
263  pointer-events: none;
264}
265
266.heart-decoration {
267  position: absolute;
268  color: var(--color-love);
269  font-size: 40px;
270  opacity: 0.15;
271  animation: float 6s ease-in-out infinite, heartbeat 1.5s ease-in-out infinite;
272}
273
274.heart-decoration::before {
275  content: '❤';
276}
277
278/* 内容容器 - 居中显示,有最大宽度限制 */
279.content-container {
280  width: 100%;
281  max-width: 1200px; /* 大屏幕最大宽度 */
282  min-height: 100vh;
283  margin: 0 auto; /* 水平居中 */
284  padding: 20px;
285  display: flex;
286  flex-direction: column;
287  align-items: center;
288  justify-content: center;
289  position: relative;
290  z-index: 1;
291}
292
293/* 标题区域 */
294.header {
295  text-align: center;
296  margin: 20px 0 30px;
297  width: 100%;
298  max-width: 600px;
299}
300
301.main-title {
302  font-family: 'Dancing Script', cursive;
303  font-size: clamp(2.5rem, 8vw, 4.5rem);
304  font-weight: 700;
305  color: var(--color-love-dark);
306  margin-bottom: 15px;
307  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
308  line-height: 1.2;
309}
310
311.subtitle {
312  font-family: 'Montserrat', sans-serif;
313  font-size: clamp(1rem, 2vw, 1.25rem);
314  color: #666;
315  max-width: 400px;
316  margin: 0 auto 20px;
317  line-height: 1.5;
318}
319
320.divider {
321  width: 100px;
322  height: 2px;
323  background: linear-gradient(to right, transparent, var(--color-love), transparent);
324  margin: 0 auto;
325  position: relative;
326}
327
328.divider-dot {
329  position: absolute;
330  top: 50%;
331  left: 50%;
332  transform: translate(-50%, -50%);
333  width: 8px;
334  height: 8px;
335  border-radius: 50%;
336  background-color: var(--color-love);
337  animation: pulse 4s ease-in-out infinite;
338}
339
340/* 头像区域 */
341.avatar-container {
342  display: flex;
343  align-items: center;
344  justify-content: center;
345  width: 100%;
346  max-width: 500px;
347  margin-bottom: 30px;
348  gap: 20px;
349}
350
351.avatar-wrapper {
352  position: relative;
353}
354
355.avatar-image {
356  width: 90px;
357  height: 90px;
358  border-radius: 50%;
359  object-fit: cover;
360  border: 4px solid white;
361  box-shadow: 0 0 0 2px var(--color-love);
362  animation: float 6s ease-in-out infinite;
363}
364
365.left-avatar .avatar-image {
366  animation-delay: 0.5s;
367}
368
369.right-avatar .avatar-image {
370  animation-delay: 1s;
371}
372
373.gender-indicator {
374  position: absolute;
375  bottom: -5px;
376  right: -5px;
377  width: 30px;
378  height: 30px;
379  border-radius: 50%;
380  background-color: white;
381  display: flex;
382  align-items: center;
383  justify-content: center;
384  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
385}
386
387.male .icon {
388  color: #3B82F6;
389}
390
391.female .icon {
392  color: #EC4899;
393}
394
395.heart-connector {
396  position: relative;
397}
398
399.heart-icon {
400  font-size: 40px;
401  color: var(--color-love-dark);
402  animation: heartbeat 1.5s ease-in-out infinite;
403  position: relative;
404  z-index: 2;
405}
406
407.heart-pulse {
408  position: absolute;
409  top: 50%;
410  left: 50%;
411  transform: translate(-50%, -50%);
412  width: 50px;
413  height: 50px;
414  background-color: var(--color-love);
415  border-radius: 50%;
416  opacity: 0.3;
417  animation: heartbeat 1.5s ease-in-out infinite;
418  z-index: 1;
419}
420
421/* 相识日期 */
422.meet-date {
423  background-color: rgba(255, 255, 255, 0.6);
424  backdrop-filter: blur(8px);
425  padding: 10px 20px;
426  border-radius: 20px;
427  box-shadow: var(--shadow-soft);
428  margin-bottom: 30px;
429  color: #666;
430  font-family: 'Montserrat', sans-serif;
431}
432
433.highlight {
434  font-weight: 600;
435  color: var(--color-love-dark);
436}
437
438/* 计时器网格 */
439.timer-grid {
440  display: grid;
441  grid-template-columns: repeat(2, 1fr);
442  gap: 15px;
443  width: 100%;
444  margin-bottom: 40px;
445}
446
447@media (min-width: 640px) {
448  .timer-grid {
449    grid-template-columns: repeat(3, 1fr);
450  }
451}
452
453@media (min-width: 768px) {
454  .timer-grid {
455    grid-template-columns: repeat(6, 1fr);
456    gap: 20px;
457  }
458  
459  .avatar-image {
460    width: 120px;
461    height: 120px;
462  }
463  
464  .heart-icon {
465    font-size: 50px;
466  }
467  
468  .heart-pulse {
469    width: 60px;
470    height: 60px;
471  }
472}
473
474/* 大屏幕适配 */
475@media (min-width: 1200px) {
476  .content-container {
477    padding: 40px;
478  }
479  
480  .timer-grid {
481    gap: 30px;
482  }
483}
484
485.timer-card {
486  background-color: rgba(255, 255, 255, 0.7);
487  backdrop-filter: blur(8px);
488  border-radius: 10px;
489  padding: 15px 10px;
490  text-align: center;
491  box-shadow: var(--shadow-medium);
492  transition: all 0.3s ease;
493}
494
495.timer-card:hover {
496  transform: scale(1.05);
497  box-shadow: 0 15px 30px -5px rgba(255, 105, 180, 0.4);
498}
499
500.time-value {
501  font-size: clamp(1.5rem, 5vw, 3rem);
502  font-weight: 700;
503  color: var(--color-love-dark);
504  margin-bottom: 5px;
505  font-family: 'Montserrat', sans-serif;
506}
507
508.time-label {
509  color: #666;
510  font-size: 14px;
511  font-family: 'Montserrat', sans-serif;
512}
513
514/* 爱情寄语 */
515.love-message {
516  text-align: center;
517  max-width: 500px;
518  margin: 30px 0 40px;
519}
520
521.love-message p {
522  font-family: 'Dancing Script', cursive;
523  font-size: clamp(1.5rem, 4vw, 2.5rem);
524  color: var(--color-romantic-dark);
525  font-style: italic;
526  line-height: 1.6;
527}
528
529.message-heart {
530  color: var(--color-love);
531  font-size: 24px;
532  margin-top: 20px;
533  animation: heartbeat 1.5s ease-in-out infinite;
534}
535
536/* 页脚 */
537.footer {
538  color: #888;
539  font-size: 14px;
540  margin-top: auto;
541  padding: 20px 0;
542  font-family: 'Montserrat', sans-serif;
543}
544
545/* 动画定义 */
546@keyframes heartbeat {
547  0% { transform: scale(1); }
548  14% { transform: scale(1.1); }
549  28% { transform: scale(1); }
550  42% { transform: scale(1.1); }
551  70% { transform: scale(1); }
552}
553
554@keyframes float {
555  0% { transform: translateY(0px) rotate(0deg); }
556  50% { transform: translateY(-20px) rotate(5deg); }
557  100% { transform: translateY(0px) rotate(0deg); }
558}
559
560@keyframes pulse {
561  0% { opacity: 0.6; }
562  50% { opacity: 1; }
563  100% { opacity: 0.6; }
564}
565
566@keyframes numberChange {
567  0% { transform: scale(1); }
568  50% { transform: scale(1.2); }
569  100% { transform: scale(1); }
570}
571
572.number-change {
573  animation: numberChange 0.5s ease-out;
574  color: var(--color-love) !important;
575}
576
577/* 字体引入 */
578@font-face {
579  font-family: 'Dancing Script';
580  font-style: normal;
581  font-weight: 400;
582  src: local('Dancing Script Regular'), local('DancingScript-Regular'),
583       url('https://fonts.gstatic.com/s/dancingscript/v24/If2RXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8hNX6p.woff2') format('woff2');
584}
585
586@font-face {
587  font-family: 'Dancing Script';
588  font-style: normal;
589  font-weight: 700;
590  src: local('Dancing Script Bold'), local('DancingScript-Bold'),
591       url('https://fonts.gstatic.com/s/dancingscript/v24/If2RXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BOk3Sup8hNX6p.woff2') format('woff2');
592}
593
594@font-face {
595  font-family: 'Montserrat';
596  font-style: normal;
597  font-weight: 400;
598  src: local('Montserrat Regular'), local('Montserrat-Regular'),
599       url('https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXp-p7K4KLg.woff2') format('woff2');
600}
601
602@font-face {
603  font-family: 'Montserrat';
604  font-style: normal;
605  font-weight: 600;
606  src: local('Montserrat SemiBold'), local('Montserrat-SemiBold'),
607       url('https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu173w5aXp-p7K4KLg.woff2') format('woff2');
608}
609</style>
610
611请对上面这个代码的2个情侣头像下方,再各自加一个昵称,分别叫做hg 和 fxj

回答

我在两个情侣头像下方分别添加了昵称“hg”和“fxj”,并调整了样式使其与整体设计协调:

  1<template>
  2  <div class="page-wrapper">
  3    <!-- 背景装饰元素 - 全屏覆盖 -->
  4    <div class="bg-decoration">
  5      <div class="heart-decoration" style="top: 10%; left: 5%; animation-delay: 0s;"></div>
  6      <div class="heart-decoration" style="top: 20%; right: 10%; animation-delay: 1s;"></div>
  7      <div class="heart-decoration" style="bottom: 30%; left: 15%; animation-delay: 2s;"></div>
  8      <div class="heart-decoration" style="bottom: 20%; right: 5%; animation-delay: 3s;"></div>
  9      <div class="heart-decoration" style="top: 40%; right: 20%; animation-delay: 1.5s;"></div>
 10    </div>
 11
 12    <!-- 内容容器 - 居中且有最大宽度 -->
 13    <div class="content-container">
 14      <!-- 标题区域 -->
 15      <header class="header">
 16        <h1 class="main-title">我们的爱情计时器</h1>
 17        <p class="subtitle">记录从相遇的那一刻起每一段珍贵的时光</p>
 18        <div class="divider">
 19          <div class="divider-dot"></div>
 20        </div>
 21      </header>
 22
 23      <!-- 情侣头像区域 -->
 24      <div class="avatar-container">
 25        <!-- 左侧头像 -->
 26        <div class="avatar-wrapper left-avatar">
 27          <img src="https://img.onedayxyy.cn/images/hg.jpg" alt="情侣头像1" class="avatar-image">
 28          <div class="gender-indicator male">
 29            <span class="icon"></span>
 30          </div>
 31          <div class="nickname">hg</div> <!-- 左侧昵称 -->
 32        </div>
 33        
 34        <!-- 中间跳动的爱心 -->
 35        <div class="heart-connector">
 36          <div class="heart-pulse"></div>
 37          <div class="heart-icon"></div>
 38        </div>
 39        
 40        <!-- 右侧头像 -->
 41        <div class="avatar-wrapper right-avatar">
 42          <img src="https://img.onedayxyy.cn/images/fxj.jpg" alt="情侣头像2" class="avatar-image">
 43          <div class="gender-indicator female">
 44            <span class="icon"></span>
 45          </div>
 46          <div class="nickname">fxj</div> <!-- 右侧昵称 -->
 47        </div>
 48      </div>
 49
 50      <!-- 相识日期展示 -->
 51      <div class="meet-date">
 52        我们相识于<span class="highlight">2025年5月29日 17:00</span>
 53      </div>
 54
 55      <!-- 计时器主区域 -->
 56      <div class="timer-grid">
 57        <!--  -->
 58        <div class="timer-card">
 59          <div :class="{'number-change': isChanged.years}" class="time-value">{{ years }}</div>
 60          <div class="time-label"></div>
 61        </div>
 62        
 63        <!--  -->
 64        <div class="timer-card">
 65          <div :class="{'number-change': isChanged.months}" class="time-value">{{ months }}</div>
 66          <div class="time-label"></div>
 67        </div>
 68        
 69        <!--  -->
 70        <div class="timer-card">
 71          <div :class="{'number-change': isChanged.days}" class="time-value">{{ days }}</div>
 72          <div class="time-label"></div>
 73        </div>
 74        
 75        <!--  -->
 76        <div class="timer-card">
 77          <div :class="{'number-change': isChanged.hours}" class="time-value">{{ hours }}</div>
 78          <div class="time-label"></div>
 79        </div>
 80        
 81        <!--  -->
 82        <div class="timer-card">
 83          <div :class="{'number-change': isChanged.minutes}" class="time-value">{{ minutes }}</div>
 84          <div class="time-label"></div>
 85        </div>
 86        
 87        <!--  -->
 88        <div class="timer-card">
 89          <div :class="{'number-change': isChanged.seconds}" class="time-value">{{ seconds }}</div>
 90          <div class="time-label"></div>
 91        </div>
 92      </div>
 93
 94      <!-- 爱情寄语 -->
 95      <div class="love-message">
 96        <p>"时光荏苒,爱意渐浓<br>你愿意,我值得<br>每一秒都是我们爱情的见证"</p>
 97        <div class="message-heart"></div>
 98      </div>
 99
100      <!-- 页脚 -->
101      <footer class="footer">
102        愿我们的故事永远继续下去...
103      </footer>
104    </div>
105  </div>
106</template>
107
108<script setup>
109import { ref, onMounted, onUnmounted } from 'vue';
110
111// 时间数据
112const years = ref(0);
113const months = ref(0);
114const days = ref(0);
115const hours = ref(0);
116const minutes = ref(0);
117const seconds = ref(0);
118
119// 用于检测数值变化的状态
120const isChanged = ref({
121  years: false,
122  months: false,
123  days: false,
124  hours: false,
125  minutes: false,
126  seconds: false
127});
128
129// 存储上一次的值
130let previousValues = {
131  years: 0,
132  months: 0,
133  days: 0,
134  hours: 0,
135  minutes: 0,
136  seconds: 0
137};
138
139// 相识日期:2025年5月29日17:00
140const meetDate = new Date(2025, 4, 29, 17, 0, 0);
141let timer = null;
142
143// 计算时间差
144function calculateTimeDifference() {
145  const now = new Date();
146  const diff = now - meetDate;
147
148  // 计算总秒数
149  const totalSeconds = Math.floor(diff / 1000);
150  
151  // 计算秒
152  const seconds = totalSeconds % 60;
153  
154  // 计算总分钟数
155  const totalMinutes = Math.floor(totalSeconds / 60);
156  const minutes = totalMinutes % 60;
157  
158  // 计算总小时数
159  const totalHours = Math.floor(totalMinutes / 60);
160  const hours = totalHours % 24;
161  
162  // 计算总天数
163  const totalDays = Math.floor(totalHours / 24);
164  
165  // 计算年、月、日
166  let years = 0;
167  let months = 0;
168  let remainingDays = totalDays;
169  
170  // 计算年数(按365天计算)
171  years = Math.floor(remainingDays / 365);
172  remainingDays = remainingDays % 365;
173  
174  // 计算月数(按平均30.44天计算)
175  months = Math.floor(remainingDays / 30.44);
176  const days = Math.floor(remainingDays % 30.44);
177  
178  return { years, months, days, hours, minutes, seconds };
179}
180
181// 更新计时器显示
182function updateTimer() {
183  const timeDiff = calculateTimeDifference();
184  
185  // 检查每个值是否变化,更新并添加动画
186  Object.keys(timeDiff).forEach(key => {
187    const value = timeDiff[key];
188    const displayValue = ['hours', 'minutes', 'seconds'].includes(key) 
189      ? value.toString().padStart(2, '0') 
190      : value;
191      
192    if (previousValues[key] !== value) {
193      // 更新值
194      eval(`${key}.value = '${displayValue}'`);
195      // 触发动画
196      isChanged.value[key] = true;
197      setTimeout(() => {
198        isChanged.value[key] = false;
199      }, 500);
200      // 更新上一次的值
201      previousValues[key] = value;
202    }
203  });
204}
205
206// 组件挂载时初始化计时器
207onMounted(() => {
208  updateTimer();
209  timer = setInterval(updateTimer, 1000);
210});
211
212// 组件卸载时清除计时器
213onUnmounted(() => {
214  if (timer) clearInterval(timer);
215});
216</script>
217
218<style>
219/* 全局样式 */
220:root {
221  --color-love-light: #FFD1DC; /* 浅粉色 */
222  --color-love: #FF69B4; /* 粉色 */
223  --color-love-dark: #C71585; /* 深粉色 */
224  --color-romantic-light: #E6E6FA; /* 浅紫色 */
225  --color-romantic-dark: #9370DB; /* 深紫色 */
226  --shadow-soft: 0 4px 15px rgba(0, 0, 0, 0.05);
227  --shadow-medium: 0 10px 25px -5px rgba(255, 105, 180, 0.3);
228}
229
230* {
231  margin: 0;
232  padding: 0;
233  box-sizing: border-box;
234}
235
236html, body {
237  width: 100%;
238  min-height: 100vh;
239  overflow-x: hidden; /* 防止横向滚动 */
240}
241</style>
242
243<style scoped>
244/* 页面外层容器 - 全屏覆盖 */
245.page-wrapper {
246  width: 100%;
247  min-height: 100vh;
248  /* 粉色渐变背景 - 全屏覆盖 */
249  background: linear-gradient(135deg, 
250    var(--color-love-light) 20%, 
251    var(--color-romantic-light) 50%, 
252    var(--color-love-light) 80%);
253  position: relative;
254}
255
256/* 背景装饰 - 全屏覆盖 */
257.bg-decoration {
258  position: absolute;
259  width: 100%;
260  height: 100%;
261  top: 0;
262  left: 0;
263  z-index: 0;
264  overflow: hidden;
265  pointer-events: none;
266}
267
268.heart-decoration {
269  position: absolute;
270  color: var(--color-love);
271  font-size: 40px;
272  opacity: 0.15;
273  animation: float 6s ease-in-out infinite, heartbeat 1.5s ease-in-out infinite;
274}
275
276.heart-decoration::before {
277  content: '❤';
278}
279
280/* 内容容器 - 居中显示,有最大宽度限制 */
281.content-container {
282  width: 100%;
283  max-width: 1200px; /* 大屏幕最大宽度 */
284  min-height: 100vh;
285  margin: 0 auto; /* 水平居中 */
286  padding: 20px;
287  display: flex;
288  flex-direction: column;
289  align-items: center;
290  justify-content: center;
291  position: relative;
292  z-index: 1;
293}
294
295/* 标题区域 */
296.header {
297  text-align: center;
298  margin: 20px 0 30px;
299  width: 100%;
300  max-width: 600px;
301}
302
303.main-title {
304  font-family: 'Dancing Script', cursive;
305  font-size: clamp(2.5rem, 8vw, 4.5rem);
306  font-weight: 700;
307  color: var(--color-love-dark);
308  margin-bottom: 15px;
309  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
310  line-height: 1.2;
311}
312
313.subtitle {
314  font-family: 'Montserrat', sans-serif;
315  font-size: clamp(1rem, 2vw, 1.25rem);
316  color: #666;
317  max-width: 400px;
318  margin: 0 auto 20px;
319  line-height: 1.5;
320}
321
322.divider {
323  width: 100px;
324  height: 2px;
325  background: linear-gradient(to right, transparent, var(--color-love), transparent);
326  margin: 0 auto;
327  position: relative;
328}
329
330.divider-dot {
331  position: absolute;
332  top: 50%;
333  left: 50%;
334  transform: translate(-50%, -50%);
335  width: 8px;
336  height: 8px;
337  border-radius: 50%;
338  background-color: var(--color-love);
339  animation: pulse 4s ease-in-out infinite;
340}
341
342/* 头像区域 */
343.avatar-container {
344  display: flex;
345  align-items: center;
346  justify-content: center;
347  width: 100%;
348  max-width: 500px;
349  margin-bottom: 30px;
350  gap: 20px;
351}
352
353.avatar-wrapper {
354  position: relative;
355  display: flex;
356  flex-direction: column;
357  align-items: center; /* 使头像和昵称居中对齐 */
358}
359
360.avatar-image {
361  width: 90px;
362  height: 90px;
363  border-radius: 50%;
364  object-fit: cover;
365  border: 4px solid white;
366  box-shadow: 0 0 0 2px var(--color-love);
367  animation: float 6s ease-in-out infinite;
368}
369
370/* 昵称样式 */
371.nickname {
372  margin-top: 10px;
373  font-family: 'Montserrat', sans-serif;
374  font-weight: 600;
375  color: var(--color-love-dark);
376  font-size: 16px;
377  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
378}
379
380.left-avatar .avatar-image {
381  animation-delay: 0.5s;
382}
383
384.right-avatar .avatar-image {
385  animation-delay: 1s;
386}
387
388.gender-indicator {
389  position: absolute;
390  bottom: -5px;
391  right: -5px;
392  width: 30px;
393  height: 30px;
394  border-radius: 50%;
395  background-color: white;
396  display: flex;
397  align-items: center;
398  justify-content: center;
399  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
400}
401
402.male .icon {
403  color: #3B82F6;
404}
405
406.female .icon {
407  color: #EC4899;
408}
409
410.heart-connector {
411  position: relative;
412}
413
414.heart-icon {
415  font-size: 40px;
416  color: var(--color-love-dark);
417  animation: heartbeat 1.5s ease-in-out infinite;
418  position: relative;
419  z-index: 2;
420}
421
422.heart-pulse {
423  position: absolute;
424  top: 50%;
425  left: 50%;
426  transform: translate(-50%, -50%);
427  width: 50px;
428  height: 50px;
429  background-color: var(--color-love);
430  border-radius: 50%;
431  opacity: 0.3;
432  animation: heartbeat 1.5s ease-in-out infinite;
433  z-index: 1;
434}
435
436/* 相识日期 */
437.meet-date {
438  background-color: rgba(255, 255, 255, 0.6);
439  backdrop-filter: blur(8px);
440  padding: 10px 20px;
441  border-radius: 20px;
442  box-shadow: var(--shadow-soft);
443  margin-bottom: 30px;
444  color: #666;
445  font-family: 'Montserrat', sans-serif;
446}
447
448.highlight {
449  font-weight: 600;
450  color: var(--color-love-dark);
451}
452
453/* 计时器网格 */
454.timer-grid {
455  display: grid;
456  grid-template-columns: repeat(2, 1fr);
457  gap: 15px;
458  width: 100%;
459  margin-bottom: 40px;
460}
461
462@media (min-width: 640px) {
463  .timer-grid {
464    grid-template-columns: repeat(3, 1fr);
465  }
466}
467
468@media (min-width: 768px) {
469  .timer-grid {
470    grid-template-columns: repeat(6, 1fr);
471    gap: 20px;
472  }
473  
474  .avatar-image {
475    width: 120px;
476    height: 120px;
477  }
478  
479  .nickname {
480    font-size: 18px; /* 大屏幕昵称稍大 */
481    margin-top: 12px;
482  }
483  
484  .heart-icon {
485    font-size: 50px;
486  }
487  
488  .heart-pulse {
489    width: 60px;
490    height: 60px;
491  }
492}
493
494/* 大屏幕适配 */
495@media (min-width: 1200px) {
496  .content-container {
497    padding: 40px;
498  }
499  
500  .timer-grid {
501    gap: 30px;
502  }
503}
504
505.timer-card {
506  background-color: rgba(255, 255, 255, 0.7);
507  backdrop-filter: blur(8px);
508  border-radius: 10px;
509  padding: 15px 10px;
510  text-align: center;
511  box-shadow: var(--shadow-medium);
512  transition: all 0.3s ease;
513}
514
515.timer-card:hover {
516  transform: scale(1.05);
517  box-shadow: 0 15px 30px -5px rgba(255, 105, 180, 0.4);
518}
519
520.time-value {
521  font-size: clamp(1.5rem, 5vw, 3rem);
522  font-weight: 700;
523  color: var(--color-love-dark);
524  margin-bottom: 5px;
525  font-family: 'Montserrat', sans-serif;
526}
527
528.time-label {
529  color: #666;
530  font-size: 14px;
531  font-family: 'Montserrat', sans-serif;
532}
533
534/* 爱情寄语 */
535.love-message {
536  text-align: center;
537  max-width: 500px;
538  margin: 30px 0 40px;
539}
540
541.love-message p {
542  font-family: 'Dancing Script', cursive;
543  font-size: clamp(1.5rem, 4vw, 2.5rem);
544  color: var(--color-romantic-dark);
545  font-style: italic;
546  line-height: 1.6;
547}
548
549.message-heart {
550  color: var(--color-love);
551  font-size: 24px;
552  margin-top: 20px;
553  animation: heartbeat 1.5s ease-in-out infinite;
554}
555
556/* 页脚 */
557.footer {
558  color: #888;
559  font-size: 14px;
560  margin-top: auto;
561  padding: 20px 0;
562  font-family: 'Montserrat', sans-serif;
563}
564
565/* 动画定义 */
566@keyframes heartbeat {
567  0% { transform: scale(1); }
568  14% { transform: scale(1.1); }
569  28% { transform: scale(1); }
570  42% { transform: scale(1.1); }
571  70% { transform: scale(1); }
572}
573
574@keyframes float {
575  0% { transform: translateY(0px) rotate(0deg); }
576  50% { transform: translateY(-20px) rotate(5deg); }
577  100% { transform: translateY(0px) rotate(0deg); }
578}
579
580@keyframes pulse {
581  0% { opacity: 0.6; }
582  50% { opacity: 1; }
583  100% { opacity: 0.6; }
584}
585
586@keyframes numberChange {
587  0% { transform: scale(1); }
588  50% { transform: scale(1.2); }
589  100% { transform: scale(1); }
590}
591
592.number-change {
593  animation: numberChange 0.5s ease-out;
594  color: var(--color-love) !important;
595}
596
597/* 字体引入 */
598@font-face {
599  font-family: 'Dancing Script';
600  font-style: normal;
601  font-weight: 400;
602  src: local('Dancing Script Regular'), local('DancingScript-Regular'),
603       url('https://fonts.gstatic.com/s/dancingscript/v24/If2RXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup8hNX6p.woff2') format('woff2');
604}
605
606@font-face {
607  font-family: 'Dancing Script';
608  font-style: normal;
609  font-weight: 700;
610  src: local('Dancing Script Bold'), local('DancingScript-Bold'),
611       url('https://fonts.gstatic.com/s/dancingscript/v24/If2RXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BOk3Sup8hNX6p.woff2') format('woff2');
612}
613
614@font-face {
615  font-family: 'Montserrat';
616  font-style: normal;
617  font-weight: 400;
618  src: local('Montserrat Regular'), local('Montserrat-Regular'),
619       url('https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXp-p7K4KLg.woff2') format('woff2');
620}
621
622@font-face {
623  font-family: 'Montserrat';
624  font-style: normal;
625  font-weight: 600;
626  src: local('Montserrat SemiBold'), local('Montserrat-SemiBold'),
627       url('https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu173w5aXp-p7K4KLg.woff2') format('woff2');
628}
629</style>

主要修改内容:

  1. 在左右两个avatar-wrapper中分别添加了<div class="nickname">hg</div><div class="nickname">fxj</div>
  2. 为昵称添加了专用样式:
    • 居中显示在头像下方
    • 使用深粉色(var(--color-love-dark))作为文字颜色
    • 设置适当的字体大小和间距
    • 在大屏幕上自动调整大小
  3. 调整了avatar-wrapperflex-direction: column,确保头像和昵称垂直排列并居中对齐

昵称样式与整体浪漫风格协调,位置在头像正下方,既清晰可见又不破坏原有布局。

效果

image-20251022191610020

推荐使用微信支付
微信支付二维码
推荐使用支付宝
支付宝二维码
最新文章

文档导航

本页导航