* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #03045e 0%, #0077b6 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 8px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
padding: 40px;
width: 100%;
max-width: 600px;
}
h1 {
font-size: 28px;
color: #03045e;
margin-bottom: 10px;
text-align: center;
font-weight: 500;
}
.subtitle {
color: #666;
font-size: 14px;
margin-bottom: 30px;
text-align: center;
}
.time-input-wrapper {
position: relative;
margin-bottom: 30px;
}
.time-input {
width: 100%;
padding: 16px 50px 16px 16px;
border: 2px solid #e0e0e0;
border-radius: 4px;
font-size: 16px;
transition: all 0.3s ease;
cursor: pointer;
background: white;
}
.time-input:focus,
.time-input.active {
outline: none;
border-color: #03045e;
box-shadow: 0 0 0 2px rgba(3, 4, 94, 0.1);
}
.time-input-icon {
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
color: #03045e;
font-size: 24px;
pointer-events: none;
}
.time-picker-dialog {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
animation: fadeIn 0.3s ease;
}
.time-picker-dialog.active {
display: flex;
align-items: center;
justify-content: center;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.time-picker {
background: white;
border-radius: 8px;
box-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2),
0 24px 38px 3px rgba(0, 0, 0, 0.14),
0 9px 46px 8px rgba(0, 0, 0, 0.12);
overflow: hidden;
animation: slideUp 0.3s ease;
max-width: 340px;
width: 100%;
}
@keyframes slideUp {
from {
transform: translateY(50px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.time-picker-header {
background: #03045e;
color: white;
padding: 24px;
text-align: center;
}
.time-picker-header-label {
font-size: 14px;
opacity: 0.7;
margin-bottom: 8px;
}
.time-display {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 48px;
font-weight: 300;
}
.time-display span {
cursor: pointer;
padding: 8px;
border-radius: 4px;
transition: background 0.2s ease;
}
.time-display span:hover {
background: rgba(255, 255, 255, 0.1);
}
.time-display span.active {
background: rgba(255, 255, 255, 0.2);
}
.period-selector {
display: flex;
flex-direction: column;
gap: 4px;
margin-left: 12px;
}
.period-btn {
background: transparent;
border: 1px solid rgba(255, 255, 255, 0.3);
color: white;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s ease;
}
.period-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.period-btn.active {
background: rgba(255, 255, 255, 0.2);
border-color: white;
}
.time-picker-body {
padding: 24px;
}
.clock-container {
width: 260px;
height: 260px;
margin: 0 auto;
position: relative;
background: #f5f5f5;
border-radius: 50%;
}
.clock-center {
position: absolute;
top: 50%;
left: 50%;
width: 8px;
height: 8px;
background: #03045e;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 2;
}
.clock-hand {
position: absolute;
top: 50%;
left: 50%;
width: 2px;
height: 100px;
background: #03045e;
transform-origin: bottom center;
transform: translate(-50%, -100%) rotate(0deg);
transition: transform 0.3s ease;
z-index: 1;
}
.clock-hand::after {
content: '';
position: absolute;
top: -20px;
left: 50%;
width: 40px;
height: 40px;
background: #03045e;
border-radius: 50%;
transform: translateX(-50%);
}
.clock-numbers {
position: absolute;
width: 100%;
height: 100%;
}
.clock-number {
position: absolute;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
cursor: pointer;
font-size: 14px;
color: #333;
transition: all 0.2s ease;
user-select: none;
}
.clock-number:hover {
background: rgba(3, 4, 94, 0.1);
}
.clock-number.active {
background: #03045e;
color: white;
}
.time-picker-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
padding: 8px 16px 16px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
text-transform: uppercase;
transition: all 0.2s ease;
}
.btn-text {
background: transparent;
color: #03045e;
}
.btn-text:hover {
background: rgba(3, 4, 94, 0.08);
}
.btn-primary {
background: #03045e;
color: white;
}
.btn-primary:hover {
background: #02033d;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.result-display {
background: #f5f5f5;
padding: 20px;
border-radius: 4px;
margin-top: 20px;
text-align: center;
}
.result-display h3 {
font-size: 14px;
color: #666;
margin-bottom: 8px;
font-weight: 500;
}
.result-time {
font-size: 32px;
color: #03045e;
font-weight: 300;
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
.time-picker {
max-width: 90vw;
}
.clock-container {
width: 220px;
height: 220px;
}
.clock-hand {
height: 80px;
}
}
const timeInput = document.getElementById('timeInput');
const timePickerDialog = document.getElementById('timePickerDialog');
const hourDisplay = document.getElementById('hourDisplay');
const minuteDisplay = document.getElementById('minuteDisplay');
const amBtn = document.getElementById('amBtn');
const pmBtn = document.getElementById('pmBtn');
const clockNumbers = document.getElementById('clockNumbers');
const clockHand = document.getElementById('clockHand');
const cancelBtn = document.getElementById('cancelBtn');
const okBtn = document.getElementById('okBtn');
const resultTime = document.getElementById('resultTime');
let selectedHour = 12;
let selectedMinute = 0;
let selectedPeriod = 'AM';
let isSelectingHour = true;
// Initialize clock numbers
function initializeClock() {
clockNumbers.innerHTML = '';
const numbers = isSelectingHour ?
[12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] :
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];
numbers.forEach((num, index) => {
const angle = (index * 30) - 90;
const radius = 100;
const x = 130 + radius * Math.cos(angle * Math.PI / 180);
const y = 130 + radius * Math.sin(angle * Math.PI / 180);
const numberEl = document.createElement('div');
numberEl.className = 'clock-number';
numberEl.textContent = num;
numberEl.style.left = `${x - 20}px`;
numberEl.style.top = `${y - 20}px`;
numberEl.addEventListener('click', () => {
if (isSelectingHour) {
selectedHour = num;
hourDisplay.textContent = num.toString().padStart(2, '0');
updateClockHand(num, true);
setTimeout(() => {
isSelectingHour = false;
hourDisplay.classList.remove('active');
minuteDisplay.classList.add('active');
initializeClock();
}, 300);
} else {
selectedMinute = num;
minuteDisplay.textContent = num.toString().padStart(2, '0');
updateClockHand(num, false);
}
});
clockNumbers.appendChild(numberEl);
});
updateClockHand(isSelectingHour ? selectedHour : selectedMinute, isSelectingHour);
}
function updateClockHand(value, isHour) {
let angle;
if (isHour) {
angle = (value % 12) * 30;
} else {
angle = (value / 5) * 30;
}
clockHand.style.transform = `translate(-50%, -100%) rotate(${angle}deg)`;
// Update active number
document.querySelectorAll('.clock-number').forEach(el => {
el.classList.remove('active');
if (parseInt(el.textContent) === value) {
el.classList.add('active');
}
});
}
// Open time picker
timeInput.addEventListener('click', () => {
timePickerDialog.classList.add('active');
timeInput.classList.add('active');
isSelectingHour = true;
hourDisplay.classList.add('active');
minuteDisplay.classList.remove('active');
initializeClock();
});
// Close dialog on backdrop click
timePickerDialog.addEventListener('click', (e) => {
if (e.target === timePickerDialog) {
timePickerDialog.classList.remove('active');
timeInput.classList.remove('active');
}
});
// Hour/Minute toggle
hourDisplay.addEventListener('click', () => {
isSelectingHour = true;
hourDisplay.classList.add('active');
minuteDisplay.classList.remove('active');
initializeClock();
});
minuteDisplay.addEventListener('click', () => {
isSelectingHour = false;
hourDisplay.classList.remove('active');
minuteDisplay.classList.add('active');
initializeClock();
});
// AM/PM buttons
amBtn.addEventListener('click', () => {
selectedPeriod = 'AM';
amBtn.classList.add('active');
pmBtn.classList.remove('active');
});
pmBtn.addEventListener('click', () => {
selectedPeriod = 'PM';
pmBtn.classList.add('active');
amBtn.classList.remove('active');
});
// Cancel button
cancelBtn.addEventListener('click', () => {
timePickerDialog.classList.remove('active');
timeInput.classList.remove('active');
});
// OK button
okBtn.addEventListener('click', () => {
const formattedTime = `${selectedHour.toString().padStart(2, '0')}:${selectedMinute.toString().padStart(2, '0')} ${selectedPeriod}`;
timeInput.value = formattedTime;
resultTime.textContent = formattedTime;
timePickerDialog.classList.remove('active');
timeInput.classList.remove('active');
});
No comments yet. Be the first!