效果演示
这段代码实现了一个模拟手表,通过动态更新时间和精心设计的 CSS 样式,呈现出一个具有立体感和真实感的手表外观,并实时显示当前的日期、星期和时间。
HTML
<div class="watchbox">
<div class="watch">
<div class="frame">
<div class="watchicon">
<svg t="1730081002941" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="7896" width="40" height="40">
<path
d="M825.03057 636.638936c-12.515693-28.802222-19.510811-61.118003-19.510811-95.255203 0-14.394711 1.241585-28.349108 3.642837-41.79407 10.311559-58.066519 41.932308-106.008357 85.570837-137.037753 7.793829-5.520575 15.960133-10.544516 24.463073-14.974544-58.85627-92.738753-154.610667-107.052825-184.746634-110.184948-65.548031-6.78648-157.870789 44.008444-208.003961 44.844274l-1.299185 0c-50.121652-0.83455-142.41881-51.629475-208.003961-44.844274-32.617858 3.38812-136.863675 25.031387-199.732698 125.159493-22.051581 35.147108-39.021622 79.945303-46.01674 137.037753-2.52797 20.624398-3.722196 42.802698-3.4214 66.708978 0.302076 23.976679 2.215654 47.465683 5.509055 70.340295 7.029678 48.823748 20.276242 94.850728 37.397322 137.049273 18.988577 46.793691 42.709259 88.852718 67.973603 124.591179 55.921264 79.096673 119.256202 124.880456 154.912744 125.680446 73.35594 1.647341 137.119672-47.940558 189.711696-46.652893 0.556793 0.126719 1.125107 0.185598 1.67038 0.126719l0.650232-0.03456 0.650232 0.03456c0.556793 0.057599 1.102067 0 1.624301-0.126719 52.603543-1.345264 116.390315 48.300234 189.792335 46.652893 35.657822-0.799991 98.991479-46.583774 154.912744-125.680446 25.241304-35.738461 48.985026-77.798768 67.986403-124.591179 2.807007-6.983598 5.520575-14.059355 8.141985-21.227271C894.280318 735.339858 849.308045 692.60628 825.03057 636.638936z"
fill="#bfbfbf" p-id="7897"></path>
<path
d="M654.645368 167.608915C710.960867 100.912737 708.791293 4.890823 703.711032 0.622073c-5.08026-4.29179-98.224768 12.80625-155.967451 77.323893-57.719643 64.516364-54.147205 162.742412-49.042625 166.988122C503.768417 249.224598 598.340108 234.353732 654.645368 167.608915z"
fill="#bfbfbf" p-id="7898"></path>
</svg>
</div>
<div>
<span class="nowDate">{{ nowDate }}</span>
<span class="nowWeek">{{ nowWeek }}</span>
<div class="nowTime">{{ nowTime }}</div>
</div>
</div>
<div class="sideBtn"></div>
<div class="powerBtn"></div>
<div class="dots">
<span class="dot"></span>
<span class="dot"></span>
</div>
</div>
</div>
- watchbox:最外层的容器,用于包裹整个时钟。
- watch:时钟的主体部分,包含了时钟的显示和一些装饰元素。
- frame:时钟的表盘部分,包含了时钟的图标、日期、星期、时间和一些装饰点。
- svg:时钟logo。
- watchicon:时钟图标的容器。
- nowDate:显示当前日期的元素。
- nowWeek:显示当前星期的元素。
- nowTime:显示当前时间的元素。
- sideBtn和powerBtn:时钟的侧边按钮和电源按钮的装饰元素。
- dots:包含两个装饰点的容器,可能用于表示闹钟或其他功能。
JavaScript
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const nowDate = ref('');
const nowWeek = ref('');
const nowTime = ref('');
function dealWithTime() {
const now = new Date();
const Y = now.getFullYear();
const M = now.getMonth() + 1;
const D = now.getDate();
const H = now.getHours().toString().padStart(2, '0');
const Min = now.getMinutes().toString().padStart(2, '0');
const S = now.getSeconds().toString().padStart(2, '0');
const W = now.getDay();
nowDate.value = `${Y}年${M}月${D}日`;
nowWeek.value = `星期${['日', '一', '二', '三', '四', '五', '六'][W]}`;
nowTime.value = `${H}:${Min}:${S}`;
}
let timer = null;
onMounted(() => {
dealWithTime(); // 初始化时间
timer = setInterval(dealWithTime, 1000); // 每秒更新时间
});
onUnmounted(() => {
clearInterval(timer); // 清除定时器
});
</script>
- import { ref, onMounted, onUnmounted } from ‘vue’;:从 Vue 导入了响应式引用 ref 和生命周期钩子 onMounted 与 onUnmounted。
- const nowDate = ref(‘’);:创建一个响应式的引用,用于存储当前日期。
- const nowWeek = ref(‘’);:创建一个响应式的引用,用于存储当前星期。
- const nowTime = ref(‘’);:创建一个响应式的引用,用于存储当前时间。
- function dealWithTime() { … }:定义了一个函数,用于获取当前时间,并格式化后更新到响应式引用中。
- let timer = null;:定义了一个变量,用于存储定时器的 ID。
- onMounted(() => { … });:在组件挂载后执行的函数,初始化时间并设置定时器每秒更新时间。
- onUnmounted(() => { … });:在组件卸载时执行的函数,清除定时器以避免内存泄漏。
CSS
<style scoped>
.watchbox {
background: #212121;
border-radius: 4px;
}
.watch {
position: relative;
transform: scale(0.5);
}
.watch::after,
.watch::before {
content: "";
width: 10rem;
height: 150px;
background: radial-gradient(circle at 150px, rgb(0, 0, 0), rgb(48, 48, 48));
box-shadow: inset 0px -10px 18px #ffffffb9, 10px 0px 30px #00000071;
position: absolute;
left: 50%;
transform: translate(-50%, 0%);
}
.watch::before {
content: "";
width: 10rem;
height: 150px;
background: radial-gradient(circle at 150px, rgb(0, 0, 0), rgb(48, 48, 48));
box-shadow: inset 0px 10px 18px #ffffffb9, 10px 0px 30px #00000071;
position: absolute;
left: 50%;
transform: translate(-50%, -100%);
}
.dots {
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 140%);
padding: 3px;
z-index: 20;
}
.dots .dot {
width: 17px;
aspect-ratio: 1;
background-color: #000000;
border-radius: 100px;
display: block;
margin-bottom: 50px;
box-shadow: inset 2px 0 5px #ffffff48;
}
.frame {
background: #0d0d0d;
border-radius: 92px;
box-shadow: inset 0 0 24px 1px #0d0d0d, inset 0 0 0 12px #606c78,
0 20px 30px #00000071;
height: 380px;
margin: 0 20px;
padding: 28px 26px;
position: relative;
width: 20rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.watchicon {
padding-bottom: 10px;
}
.nowDate {
display: inline-block;
font-size: 22px;
color: #ffffff;
}
.nowWeek {
display: inline-block;
font-size: 22px;
color: #ffffff;
margin-left: 8px;
}
.nowTime {
color: #dddf8f;
font-size: 4rem;
font-family: serif;
font-weight: bolder;
line-height: 0.8;
text-shadow: 0 0 40px #d7d886c7;
padding: 10px 0;
}
.frame::before {
border: 1px solid #0d0d0d;
border-radius: 80px;
box-shadow: 0 0 12px rgba(255, 255, 255, 0.5),
inset 0 0 12px 2px rgba(255, 255, 255, 0.75);
content: "";
height: 356px;
left: 12px;
position: absolute;
top: 12px;
width: 18.625rem;
}
.sideBtn {
background: #606c78;
border-left: 1px solid #000;
border-radius: 8px 6px 6px 8px / 20px 6px 6px 20px;
box-shadow: inset 8px 0 8px 0 #1c1f23, inset -2px 0 6px #272c31,
-4px 0 8px #0d0d0d40;
height: 72px;
position: absolute;
right: 6px;
top: 108px;
width: 18px;
z-index: 9;
}
.sideBtn::before {
background: #272c31;
border-radius: 20%;
box-shadow: 0 -30px rgba(62, 70, 77, 0.75), 0 -27px #272c31, 0 -25px #000,
0 -21px rgba(62, 70, 77, 0.75), 0 -18px #272c31, 0 -16px #000,
0 -12px rgba(62, 70, 77, 0.75), 0 -9px #272c31, 0 -7px #000,
0 -3px rgba(62, 70, 77, 0.75), 0 0 #272c31, 0 2px #000,
0 6px rgba(62, 70, 77, 0.75), 0 9px #272c31, 0 11px #000,
0 15px rgba(62, 70, 77, 0.75), 0 18px #272c31, 0 20px #000,
0 24px rgba(62, 70, 77, 0.75), 0 27px #272c31, 0 29px #000;
content: "";
height: 3px;
margin-top: -2px;
position: absolute;
right: 2px;
top: 50%;
width: 10px;
z-index: 9;
}
.sideBtn::after {
background: #16181b;
border-radius: 2px 4px 4px 2px / 20px 8px 8px 20px;
box-shadow: inset -2px 0 2px 0 #000, inset -6px 0 18px #272c31;
content: "";
height: 72px;
position: absolute;
right: 0;
top: 0;
width: 6px;
}
.powerBtn {
background: #272c31;
border-radius: 2px 4px 4px 2px / 2px 8px 8px 2px;
box-shadow: inset 0 0 2px 1px #101315;
height: 72px;
position: absolute;
right: 18px;
top: 212px;
width: 4px;
}
</style>
- .watchbox、.watch、.frame 等类定义了时钟的外观和布局。
- .nowDate、.nowWeek、.nowTime 类定义了日期、星期和时间的字体样式。
- .dot 类定义了装饰点的样式。