<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高级全屏动态时钟</title>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;700&family=Orbitron:wght@400;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
:root {
--bg-primary: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
--accent-color: #FF5F85;
--menu-bg: rgba(0, 0, 0, 0.4);
--font-heading: 'Orbitron', sans-serif;
--font-body: 'Nunito', sans-serif;
--notification-bg: rgba(20, 20, 30, 0.95);
--notification-accent: #6A89CC;
--box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
--transition-all: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
body {
font-family: var(--font-body);
background: var(--bg-primary);
color: white;
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: background 1.2s cubic-bezier(0.23, 1, 0.32, 1);
overflow: hidden;
position: relative;
}
/* 时钟容器 */
.clock-container {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 20;
perspective: 1000px;
}
/* 弹跳动画类 */
.bounce {
animation: bounce 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes bounce {
0%, 100% { transform: scale(1); }
40% { transform: scale(1.25); }
60% { transform: scale(0.9); }
80% { transform: scale(1.1); }
}
.time {
font-family: var(--font-heading);
font-size: 14vw;
font-weight: 700;
text-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
margin-bottom: 10px;
display: flex;
letter-spacing: 2px;
transition: var(--transition-all);
}
.time span {
display: inline-block;
min-width: 0.75em;
text-align: center;
}
.date {
font-size: 3.5vw;
font-weight: 400;
opacity: 0.9;
letter-spacing: 2px;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
font-family: var(--font-heading);
transition: var(--transition-all);
}
/* 菜单栏样式 - 透明设计 */
.menu-bar {
position: fixed;
top: -80px;
left: 0;
width: 100%;
height: 80px;
background: var(--menu-bg);
backdrop-filter: blur(12px);
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
transition: top 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.3);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.menu-bar.active {
top: 0;
}
.menu-buttons {
display: flex;
gap: 20px;
padding: 0 20px;
width: 100%;
max-width: 1200px;
justify-content: center;
}
.menu-btn {
background: rgba(255, 255, 255, 0.1);
color: white;
border: none;
border-radius: 50px;
padding: 12px 28px;
font-size: 18px;
font-weight: 600;
cursor: pointer;
transition: var(--transition-all);
display: flex;
align-items: center;
gap: 10px;
backdrop-filter: blur(5px);
box-shadow: var(--box-shadow);
font-family: var(--font-heading);
}
.menu-btn:hover {
background: rgba(255, 255, 255, 0.25);
transform: translateY(-5px);
}
.menu-btn i {
font-size: 22px;
transition: var(--transition-all);
}
/* 颜色选择弹窗 */
.color-picker {
position: absolute;
top: 90px;
background: rgba(30, 30, 45, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
padding: 20px;
box-shadow: var(--box-shadow);
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 15px;
z-index: 110;
opacity: 0;
pointer-events: none;
transform: translateY(20px);
transition: var(--transition-all);
width: 500px;
max-width: 90%;
}
.color-picker.active {
opacity: 1;
pointer-events: all;
transform: translateY(0);
}
.color-option {
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
transition: var(--transition-all);
border: 2px solid transparent;
}
.color-option:hover {
transform: scale(1.15);
border-color: white;
}
.color-option.active {
transform: scale(1.2);
box-shadow: 0 0 0 4px white;
}
/* 水波纹效果 */
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple 0.6s linear;
pointer-events: none;
z-index: 5;
background: rgba(255, 255, 255, 0.3);
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
/* 浮动元素动画 */
.floating-element {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
animation: float 25s infinite linear;
pointer-events: none;
z-index: 1;
box-shadow: 0 0 30px rgba(255, 255, 255, 0.2);
}
@keyframes float {
0%, 100% {
transform: translate(0, 0);
}
25% {
transform: translate(calc(90vw - 100px), calc(80vh - 100px));
}
50% {
transform: translate(calc(100vw - 200px), calc(10vh - 100px));
}
75% {
transform: translate(calc(10vw - 100px), calc(90vh - 100px));
}
}
/* 彩色线条边框 */
.glow-border {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
.glow-line {
position: absolute;
background: linear-gradient(90deg, transparent, var(--accent-color), transparent);
animation: slide 20s linear infinite;
height: 2px;
}
@keyframes slide {
0% {
left: -100%;
}
100% {
left: 100%;
}
}
/* 时间颗粒效果 */
.particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 2;
}
.particle {
position: absolute;
width: 6px;
height: 6px;
background: white;
border-radius: 50%;
box-shadow: 0 0 15px rgba(255, 255, 255, 0.7);
animation: particleAnimation 3s infinite alternate;
}
@keyframes particleAnimation {
0% {
transform: translate(0, 0);
opacity: 0.8;
}
100% {
transform: translate(100px, 100px);
opacity: 0.1;
}
}
/* 提示文字 */
.hint-text {
position: absolute;
bottom: 30px;
font-size: 16px;
color: rgba(255, 255, 255, 0.7);
text-align: center;
transition: opacity 0.5s ease;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
padding: 0 20px;
max-width: 90%;
z-index: 20;
background: rgba(0, 0, 0, 0.3);
padding: 10px 20px;
border-radius: 50px;
font-family: var(--font-body);
}
/* 通知系统 - 增强版本 */
.notifications-container {
position: fixed;
top: 20px;
right: 20px;
width: 350px;
z-index: 200;
display: flex;
flex-direction: column;
gap: 15px;
}
.notification {
background: var(--notification-bg);
border-radius: 12px;
padding: 20px;
box-shadow: var(--box-shadow);
backdrop-filter: blur(10px);
transform: translateX(calc(100% + 50px));
opacity: 0;
transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease;
animation: notificationSlideIn 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
border-left: 5px solid var(--notification-accent);
position: relative;
overflow: hidden;
}
.notification::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
z-index: -1;
}
@keyframes notificationSlideIn {
0% {
transform: translateX(calc(100% + 50px));
opacity: 0;
}
70% {
transform: translateX(-30px);
opacity: 1;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
.notification-title {
font-weight: 700;
margin-bottom: 8px;
color: var(--notification-accent);
font-family: var(--font-heading);
font-size: 18px;
display: flex;
align-items: center;
gap: 10px;
}
.notification-title::before {
content: "🔔";
font-size: 16px;
}
.notification-content {
font-size: 14px;
opacity: 0.9;
line-height: 1.6;
}
.notification.hiding {
animation: notificationSlideOut 0.5s forwards;
}
@keyframes notificationSlideOut {
to {
transform: translateX(calc(100% + 50px));
opacity: 0;
}
}
/* 响应式布局 */
@media (max-width: 768px) {
.time {
font-size: 22vw;
}
.date {
font-size: 5vw;
}
.menu-buttons {
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
.menu-btn {
padding: 8px 15px;
font-size: 14px;
}
.color-picker {
grid-template-columns: repeat(3, 1fr);
width: 300px;
}
.color-option {
width: 40px;
height: 40px;
}
.hint-text {
font-size: 14px;
bottom: 10px;
}
.notifications-container {
width: 90%;
top: 90px;
left: 50%;
transform: translateX(-50%);
right: unset;
}
}
</style>
</head>
<body>
<div class="clock-container">
<div class="time" id="time">
<span>0</span><span>0</span><span>:</span><span>0</span><span>0</span><span>:</span><span>0</span><span>0</span>
</div>
<div class="date" id="date">2023年1月1日 星期一</div>
</div>
<div class="menu-bar" id="menuBar">
<div class="menu-buttons">
<button class="menu-btn" id="settingsBtn"><i>⚙️</i> 设置</button>
<button class="menu-btn" id="fullscreenBtn"><i>⛶</i> 全屏</button>
<button class="menu-btn" id="colorBtn"><i>🎨</i> 颜色</button>
<button class="menu-btn" id="dynamicBtn"><i>🌀</i> 更动态</button>
<button class="menu-btn" id="visualBtn"><i>✨</i> 更好看</button>
<button class="menu-btn" id="effectsBtn"><i>💫</i> 更动效</button>
<button class="menu-btn" id="notifyBtn"><i>🔔</i> 通知</button>
</div>
<div class="color-picker" id="colorPicker">
<div class="color-option" data-accent="#FF5F85" data-notify="#6A89CC" style="background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);"></div>
<div class="color-option" data-accent="#8E54E9" data-notify="#A16BFE" style="background: linear-gradient(135deg, #4776E6, #8E54E9, #4776E6);"></div>
<div class="color-option" data-accent="#38ef7d" data-notify="#43cea2" style="background: linear-gradient(135deg, #0B486B, #1e5799, #7DB9E8);"></div>
<div class="color-option" data-accent="#FF4B2B" data-notify="#FF9A8B" style="background: linear-gradient(135deg, #ff416c, #ff4b2b, #ff416c);"></div>
<div class="color-option" data-accent="#4ECDC4" data-notify="#8FE3E9" style="background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);"></div>
<div class="color-option" data-accent="#7A75FF" data-notify="#C2AAF2" style="background: linear-gradient(135deg, #1a1a2e, #16213e, #0f3460);"></div>
<div class="color-option" data-accent="#DA22FF" data-notify="#9C55FF" style="background: linear-gradient(135deg, #4a00e0, #8e2de2, #4a00e0);"></div>
<div class="color-option" data-accent="#11998e" data-notify="#38ef7d" style="background: linear-gradient(135deg, #11998e, #38ef7d, #11998e);"></div>
<div class="color-option" data-accent="#FF9A8B" data-notify="#FF6A88" style="background: linear-gradient(135deg, #FF9A8B, #FF6A88, #FF99AC);"></div>
<div class="color-option" data-accent="#d16ba5" data-notify="#aa8fd8" style="background: linear-gradient(135deg, #d16ba5, #c777b9, #ba83ca, #aa8fd8);"></div>
<div class="color-option" data-accent="#43cea2" data-notify="#185a9d" style="background: linear-gradient(135deg, #43cea2, #185a9d, #43cea2);"></div>
<div class="color-option" data-accent="#fd1d1d" data-notify="#fcb045" style="background: linear-gradient(135deg, #833ab4, #fd1d1d, #fcb045);"></div>
</div>
</div>
<div class="glow-border"></div>
<div class="particles"></div>
<div class="hint-text" id="hint">点击任意位置显示/隐藏菜单 | 按空格键测试通知</div>
<div class="notifications-container" id="notificationsContainer"></div>
<script>
// 获取DOM元素
const timeElement = document.getElementById('time');
const timeSpans = Array.from(timeElement.children);
const dateElement = document.getElementById('date');
const menuBar = document.getElementById('menuBar');
const colorPicker = document.getElementById('colorPicker');
const hintText = document.getElementById('hint');
const fullscreenBtn = document.getElementById('fullscreenBtn');
const colorBtn = document.getElementById('colorBtn');
const dynamicBtn = document.getElementById('dynamicBtn');
const visualBtn = document.getElementById('visualBtn');
const effectsBtn = document.getElementById('effectsBtn');
const notifyBtn = document.getElementById('notifyBtn');
const notificationsContainer = document.getElementById('notificationsContainer');
const body = document.body;
const colorOptions = Array.from(document.querySelectorAll('.color-option'));
const root = document.documentElement;
// 状态变量
let menuVisible = false;
let dynamicLevel = 2; // 动态效果级别
let visualLevel = 2; // 视觉效果级别
let effectsLevel = 2; // 动效级别
let colorPickerVisible = false;
let lastHours = "00";
let lastMinutes = "00";
let lastSeconds = "00";
let pulseInterval;
// 更新时间
function updateTime() {
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
// 更新时间显示
timeSpans[0].textContent = hours[0];
timeSpans[1].textContent = hours[1];
timeSpans[3].textContent = minutes[0];
timeSpans[4].textContent = minutes[1];
timeSpans[6].textContent = seconds[0];
timeSpans[7].textContent = seconds[1];
// 检查小时是否变化 - 动画处理
if (hours[0] !== lastHours[0]) {
timeSpans[0].classList.add('bounce');
setTimeout(() => timeSpans[0].classList.remove('bounce'), 800);
}
if (hours[1] !== lastHours[1]) {
timeSpans[1].classList.add('bounce');
setTimeout(() => timeSpans[1].classList.remove('bounce'), 800);
}
// 检查分钟是否变化 - 动画处理
if (minutes[0] !== lastMinutes[0]) {
timeSpans[3].classList.add('bounce');
setTimeout(() => timeSpans[3].classList.remove('bounce'), 800);
}
if (minutes[1] !== lastMinutes[1]) {
timeSpans[4].classList.add('bounce');
setTimeout(() => timeSpans[4].classList.remove('bounce'), 800);
}
// 检查秒是否变化 - 动画处理(确保秒也有动画)
if (seconds[0] !== lastSeconds[0]) {
timeSpans[6].classList.add('bounce');
setTimeout(() => timeSpans[6].classList.remove('bounce'), 800);
}
if (seconds[1] !== lastSeconds[1]) {
timeSpans[7].classList.add('bounce');
setTimeout(() => timeSpans[7].classList.remove('bounce'), 800);
}
lastHours = hours;
lastMinutes = minutes;
lastSeconds = seconds;
const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' };
const date = now.toLocaleDateString('zh-CN', dateOptions);
dateElement.textContent = date;
}
// 显示/隐藏菜单
function toggleMenu() {
menuVisible = !menuVisible;
menuBar.classList.toggle('active', menuVisible);
hintText.style.opacity = menuVisible ? 0 : 0.7;
}
// 全屏切换
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
console.error(`全屏请求错误: ${err}`);
});
} else {
document.exitFullscreen();
}
}
// 显示颜色选择器
function toggleColorPicker() {
colorPickerVisible = !colorPickerVisible;
colorPicker.classList.toggle('active', colorPickerVisible);
}
// 改变主题颜色
function changeTheme(colorGradient, accent, notify) {
body.style.background = colorGradient;
root.style.setProperty('--accent-color', accent);
root.style.setProperty('--notification-accent', notify);
}
// 添加点击水波纹效果
function createRipple(e) {
const ripple = document.createElement('div');
ripple.className = 'ripple';
ripple.style.left = e.clientX + 'px';
ripple.style.top = e.clientY + 'px';
document.body.appendChild(ripple);
setTimeout(() => ripple.remove(), 600);
}
// 添加浮动元素
function createFloatingElements() {
// 清除之前的浮动元素
document.querySelectorAll('.floating-element').forEach(el => el.remove());
// 根据视觉效果级别添加元素
const elementsCount = visualLevel * 8;
// 创建浮动元素
for (let i = 0; i < elementsCount; i++) {
const el = document.createElement('div');
el.className = 'floating-element';
// 随机大小
const size = Math.random() * 120 + 30;
el.style.width = `${size}px`;
el.style.height = `${size}px`;
// 随机位置
el.style.left = `${Math.random() * 90}%`;
el.style.top = `${Math.random() * 90}%`;
// 随机动画延迟
el.style.animationDelay = `${Math.random() * 20}s`;
document.body.appendChild(el);
}
}
// 创建光线条
function createGlowLines() {
const glowBorder = document.querySelector('.glow-border');
glowBorder.innerHTML = '';
const positions = [0, 15, 30, 45, 60, 75, 90];
positions.forEach(pos => {
const line = document.createElement('div');
line.className = 'glow-line';
line.style.top = `${pos}%`;
line.style.animationDelay = `${Math.random() * 5}s`;
glowBorder.appendChild(line);
});
}
// 创建时间粒子
function createTimeParticles() {
const particlesContainer = document.querySelector('.particles');
particlesContainer.innerHTML = '';
// 根据效果级别创建粒子
const particleCount = effectsLevel * 80;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
// 随机位置
const startX = Math.random() * 100;
const startY = Math.random() * 100;
particle.style.left = `${startX}%`;
particle.style.top = `${startY}%`;
// 随机动画参数
const duration = 3 + Math.random() * 5;
const delay = Math.random() * 5;
const x = (Math.random() - 0.5) * 200;
const y = (Math.random() - 0.5) * 200;
particle.style.animation = `particleAnimation ${duration}s ${delay}s infinite alternate`;
}
}
// 创建通知
function createNotification(title, content, duration = 5000) {
const notification = document.createElement('div');
notification.className = 'notification';
notification.innerHTML = `
<div class="notification-title">${title}</div>
<div class="notification-content">${content}</div>
`;
notificationsContainer.prepend(notification);
setTimeout(() => {
notification.classList.add('hiding');
setTimeout(() => {
notification.remove();
}, 500);
}, duration);
}
// 初始化动画效果
function initAnimations() {
// 创建动态效果
createFloatingElements();
createGlowLines();
createTimeParticles();
}
// 页面初始化
function init() {
// 初始更新时间
const now = new Date();
lastHours = now.getHours().toString().padStart(2, '0');
lastMinutes = now.getMinutes().toString().padStart(2, '0');
lastSeconds = now.getSeconds().toString().padStart(2, '0');
updateTime();
setInterval(updateTime, 1000);
// 添加页面点击事件
document.addEventListener('click', (e) => {
// 如果点击的是菜单按钮区域,不触发主点击事件
if (e.target.closest('.menu-buttons') || e.target.closest('.color-picker')) {
return;
}
toggleMenu();
createRipple(e);
// 关闭颜色选择器
if (colorPickerVisible) {
toggleColorPicker();
}
});
// 键盘事件:空格键测试通知
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
const titles = ["新通知", "系统提示", "时钟更新"];
const contents = [
"已切换至更动态模式 - 级别2",
"颜色主题已更新为日落色调",
"现在是北京时间:" + new Date().toLocaleTimeString(),
"时钟样式已优化至更好看模式",
"通知系统功能已启用"
];
const title = titles[Math.floor(Math.random() * titles.length)];
const content = contents[Math.floor(Math.random() * contents.length)];
createNotification(title, content);
e.preventDefault();
}
});
// 全屏按钮
fullscreenBtn.addEventListener('click', toggleFullscreen);
// 颜色按钮
colorBtn.addEventListener('click', (e) => {
toggleColorPicker();
e.stopPropagation();
});
// 颜色选项点击
colorOptions.forEach(option => {
option.addEventListener('click', () => {
const style = window.getComputedStyle(option);
const accent = option.dataset.accent;
const notify = option.dataset.notify;
changeTheme(style.background, accent, notify);
colorOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
createNotification("主题更新", "已应用新的背景主题");
});
});
// 动态效果按钮
dynamicBtn.addEventListener('click', (e) => {
dynamicLevel = dynamicLevel < 3 ? dynamicLevel + 1 : 1;
dynamicBtn.innerHTML = `<i>🌀</i> 更动态 ${'●'.repeat(dynamicLevel)}`;
const levels = ["基础", "中级", "高级"];
createNotification("动态模式更新", `已设置为 ${levels[dynamicLevel-1]} 动态模式`);
e.stopPropagation();
});
// 视觉效果按钮
visualBtn.addEventListener('click', (e) => {
visualLevel = visualLevel < 3 ? visualLevel + 1 : 1;
visualBtn.innerHTML = `<i>✨</i> 更好看 ${'★'.repeat(visualLevel)}`;
createFloatingElements();
createGlowLines();
const levels = ["简约", "优雅", "华丽"];
createNotification("视觉模式更新", `已设置为 ${levels[visualLevel-1]} 视觉效果`);
e.stopPropagation();
});
// 动效按钮
effectsBtn.addEventListener('click', (e) => {
effectsLevel = effectsLevel < 3 ? effectsLevel + 1 : 1;
effectsBtn.innerHTML = `<i>💫</i> 更动效 ${'✧'.repeat(effectsLevel)}`;
createTimeParticles();
const levels = ["柔和", "明亮", "强烈"];
createNotification("特效模式更新", `已设置为 ${levels[effectsLevel-1]} 动效模式`);
e.stopPropagation();
});
// 通知按钮
notifyBtn.addEventListener('click', (e) => {
createNotification("通知功能", "这是一个测试通知消息。按空格键可以显示更多通知");
e.stopPropagation();
});
// 初始化按钮标签
visualBtn.innerHTML = `<i>✨</i> 更好看 ${'★'.repeat(visualLevel)}`;
effectsBtn.innerHTML = `<i>💫</i> 更动效 ${'✧'.repeat(effectsLevel)}`;
dynamicBtn.innerHTML = `<i>🌀</i> 更动态 ${'●'.repeat(dynamicLevel)}`;
// 初始创建动画效果
initAnimations();
// 设置提示文字
hintText.style.opacity = 0.7;
// 初始化测试通知
setTimeout(() => {
createNotification("高级动态时钟", "欢迎使用全屏时钟应用", 3000);
}, 1500);
}
// 启动应用
init();
</script>
</body>
</html>
index.html