Recently, I encountered an issue with an analog clock component. Every time I click on the time adjustment bubble repeatedly while also moving the cursor position, it tends to drift away from its original placement, which should ideally be between an orange circle and the clock's main content (the white part).
In an attempt to address this problem, I made adjustments to the marginLeft and marginTop properties, but unfortunately, this only exacerbated the situation.
let isDragging = false;
let offsetX, offsetY;
const draggable = document.querySelector('.clock div:nth-child(3)');
const clock = document.querySelector('.clock');
const clockRadius = clock.offsetWidth / 2;
const draggableRadius = draggable.offsetWidth / 2;
const hourDisplay = document.querySelector('.clock div p');
draggable.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - draggable.getBoundingClientRect().left;
offsetY = e.clientY - draggable.getBoundingClientRect().top;
draggable.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const angle = Math.atan2(e.clientY - (clock.offsetTop + clockRadius), e.clientX - (clock.offsetLeft + clockRadius));
let hours = Math.floor((angle + Math.PI / 2) / (Math.PI / 6));
hours = (hours + 12) % 12; // Adjust for 0-11 instead of 1-12
const minuteSegment = ((angle + Math.PI / 2) / (Math.PI / 6 / 60)) % 60;
const minutes = Math.floor(minuteSegment);
// Calculate and display the hour and minutes based on the angle
const formattedHour = hours < 10 ? `0${hours}` : `${hours}`;
const formattedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
hourDisplay.textContent = `${formattedHour}:${formattedMinutes}`;
const x = Math.cos(angle) * (clockRadius - draggableRadius) + clockRadius - draggableRadius;
const y = Math.sin(angle) * (clockRadius - draggableRadius) + clockRadius - draggableRadius;
draggable.style.left = x - offsetX + 'px';
draggable.style.top = y - offsetY + 'px';
});
document.addEventListener('mouseup', () => {
isDragging = false;
draggable.style.cursor = 'grab';
});