LLM-test/test/clock/glm4.7.html

252 lines
8.8 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modern Responsive Analog Clock</title>
<style>
/* CSS Variables for easy theming and sizing */
:root {
--bg-color: #ffffff;
--clock-face: #f9f9f9;
--text-color: #333333;
--accent-color: #e74c3c; /* Red for second hand */
--hand-color: #2c3e50;
--shadow-light: rgba(255, 255, 255, 0.8);
--shadow-dark: rgba(0, 0, 0, 0.1);
--clock-size: min(80vw, 80vh); /* Responsive unit */
}
/* Reset and Base Layout */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: var(--bg-color);
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
overflow: hidden; /* Prevent scrollbars if zoomed */
}
/* Main Clock Container */
.clock-container {
position: relative;
width: var(--clock-size);
height: var(--clock-size);
border-radius: 50%;
background: var(--clock-face);
/* Soft neumorphic shadow */
box-shadow:
20px 20px 60px var(--shadow-dark),
-20px -20px 60px var(--shadow-light),
inset 5px 5px 10px var(--shadow-dark),
inset -5px -5px 10px var(--shadow-light);
display: flex;
justify-content: center;
align-items: center;
}
/* Clock Face Numbers */
.clock-face {
position: relative;
width: 100%;
height: 100%;
text-align: center;
color: var(--text-color);
}
/* Number positioning using transforms */
.number {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
/* Rotate the container to the angle */
transform: rotate(calc(var(--rotation) * 1deg));
pointer-events: none;
}
.number span {
display: block;
font-size: calc(var(--clock-size) * 0.08);
font-weight: 600;
/* Counter-rotate the text so it stays upright */
transform: rotate(calc(var(--rotation) * -1deg));
padding-top: 5%; /* Push number away from absolute center edge */
}
/* Hands Styles */
.hand {
position: absolute;
bottom: 50%;
left: 50%;
transform-origin: bottom center;
border-radius: 4px;
z-index: 10;
/* Using CSS variables updated by JS */
transform: translateX(-50%) rotate(var(--deg));
will-change: transform; /* Performance optimization */
}
/* Hour Hand */
.hand.hour {
width: calc(var(--clock-size) * 0.025);
height: calc(var(--clock-size) * 0.25);
background: var(--hand-color);
z-index: 11;
}
/* Minute Hand */
.hand.min {
width: calc(var(--clock-size) * 0.015);
height: calc(var(--clock-size) * 0.35);
background: var(--hand-color);
z-index: 12;
}
/* Second Hand */
.hand.second {
width: calc(var(--clock-size) * 0.008);
height: calc(var(--clock-size) * 0.40);
background: var(--accent-color);
z-index: 13;
/* Add a tail to the second hand */
}
.hand.second::after {
content: '';
position: absolute;
width: 100%;
height: 20%;
bottom: -20%;
left: 0;
background: var(--accent-color);
border-radius: 4px;
}
/* Center Nut/Pin */
.center-nut {
position: absolute;
width: calc(var(--clock-size) * 0.04);
height: calc(var(--clock-size) * 0.04);
background: var(--accent-color);
border: 2px solid #fff;
border-radius: 50%;
z-index: 14;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
/* Digital Time Display (Optional, for accessibility/clarity) */
.digital-readout {
position: absolute;
bottom: 25%;
font-size: calc(var(--clock-size) * 0.05);
font-family: 'Courier New', monospace;
color: var(--text-color);
opacity: 0.5;
font-weight: bold;
letter-spacing: 2px;
}
</style>
</head>
<body>
<!-- Semantic Clock Container -->
<main class="clock-container" id="clock" aria-label="Analog Clock displaying current time">
<div class="clock-face">
<!-- Numbers 1-12 generated by loop logic below for cleaner HTML -->
<!-- Manually placing 12, 3, 6, 9 for structure, others via JS -->
<div class="number" style="--rotation: 30"><span>1</span></div>
<div class="number" style="--rotation: 60"><span>2</span></div>
<div class="number" style="--rotation: 90"><span>3</span></div>
<div class="number" style="--rotation: 120"><span>4</span></div>
<div class="number" style="--rotation: 150"><span>5</span></div>
<div class="number" style="--rotation: 180"><span>6</span></div>
<div class="number" style="--rotation: 210"><span>7</span></div>
<div class="number" style="--rotation: 240"><span>8</span></div>
<div class="number" style="--rotation: 270"><span>9</span></div>
<div class="number" style="--rotation: 300"><span>10</span></div>
<div class="number" style="--rotation: 330"><span>11</span></div>
<div class="number" style="--rotation: 0"><span>12</span></div>
<!-- Hands -->
<div class="hand hour" id="hour-hand"></div>
<div class="hand min" id="min-hand"></div>
<div class="hand second" id="sec-hand"></div>
<!-- Center Pin -->
<div class="center-nut"></div>
<!-- Optional small digital readout -->
<div class="digital-readout" id="digital-time">00:00:00</div>
</div>
</main>
<script>
/**
* Clock Logic
* Uses requestAnimationFrame for a smooth, high-performance update loop
* rather than a simple setInterval, ensuring the second hand sweeps smoothly.
*/
const hourHand = document.getElementById('hour-hand');
const minHand = document.getElementById('min-hand');
const secHand = document.getElementById('sec-hand');
const clock = document.getElementById('clock');
const digitalReadout = document.getElementById('digital-time');
function updateClock() {
const now = new Date();
// Get precise time components
const seconds = now.getSeconds();
const milliseconds = now.getMilliseconds();
const minutes = now.getMinutes();
const hours = now.getHours();
// Calculate degrees
// Second hand: includes milliseconds for a "sweep" animation
// Formula: (seconds + ms/1000) / 60 * 360
const secDegrees = ((seconds + (milliseconds / 1000)) / 60) * 360;
// Minute hand: includes seconds fraction for smooth movement between ticks
const minDegrees = ((minutes + seconds / 60) / 60) * 360;
// Hour hand: includes minutes fraction
const hourDegrees = ((hours % 12 + minutes / 60) / 12) * 360;
// Apply CSS variables to rotate the hands
// We set the variable --deg on the specific elements
secHand.style.setProperty('--deg', `${secDegrees}deg`);
minHand.style.setProperty('--deg', `${minDegrees}deg`);
hourHand.style.setProperty('--deg', `${hourDegrees}deg`);
// Update Accessibility Label (optional but good practice)
const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
clock.setAttribute('aria-label', `Current time is ${timeString}`);
// Update small digital readout
digitalReadout.textContent = timeString;
// Request next frame
requestAnimationFrame(updateClock);
}
// Initialize the clock
requestAnimationFrame(updateClock);
</script>
</body>
</html>