console
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const wStart = 30;
const wEnd = 670;
canvas.width = 700;
canvas.height = 80;
const timeSelectWidth = wEnd - wStart;
const totalSeconds = 86400;
let animateId;
let mouseDown = false;
let beforeSelectTime;
let beforeCurrentTime;
let currentTime;
let speed = 10;
let hPosition = 0;
let cPosition = 0;
let hTime = "";
let cTime = "";
const drawBg = () => {
ctx.save();
ctx.beginPath();
ctx.moveTo(wStart, 16);
ctx.lineTo(wEnd, 16)
ctx.strokeStyle = "#6bddc4";
ctx.lineWidth = 18;
ctx.lineCap = "round";
ctx.stroke();
ctx.restore();
}
const drawCurrentTime = () => {
currentTime = moment();
cTime = currentTime.format("HH:mm:ss");
const startDay = moment().startOf("day").valueOf();
const diff = Math.floor((currentTime.valueOf() - startDay) / 1000)
cPosition = timeSelectWidth * diff / totalSeconds + wStart;
}
const drawBeforeTime = () => {
if (!beforeCurrentTime) beforeCurrentTime = moment().valueOf();
if (!beforeSelectTime) beforeSelectTime = moment().valueOf();
const currentTime = moment().valueOf();
const timeDiff = (moment().valueOf() - beforeCurrentTime) * speed;
const startDay = moment().startOf("day").valueOf();
if ((currentTime - beforeSelectTime) < 5000) {
beforeSelectTime = currentTime;
beforeCurrentTime = moment().valueOf();
const diff = Math.floor((currentTime.valueOf() - startDay) / 1000)
hPosition = timeSelectWidth * diff / totalSeconds + wStart;
hTime = "";
} else {
beforeSelectTime = beforeSelectTime + timeDiff;
beforeCurrentTime = moment().valueOf();
const diff = Math.floor((beforeSelectTime - startDay) / 1000)
hPosition = timeSelectWidth * diff / totalSeconds + wStart;
hTime = moment(beforeSelectTime).format("HH:mm:ss");
}
};
const drawTime = () => {
ctx.save();
ctx.beginPath();
ctx.moveTo(cPosition, 6);
ctx.lineTo(cPosition, 26);
ctx.strokeStyle = "blue";
ctx.stroke();
ctx.textAlign = "center";
ctx.fillText(cTime, cPosition, 56)
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.moveTo(wStart, 16);
ctx.lineTo(hPosition, 16);
ctx.lineWidth = 12;
ctx.strokeStyle = 'blue';
ctx.lineCap = "round";
ctx.stroke();
ctx.beginPath();
ctx.restore();
ctx.save();
ctx.arc(hPosition, 16, 10, 0, 2 * Math.PI);
ctx.strokeStyle = "red";
ctx.stroke();
ctx.textAlign = "center";
ctx.fillText(hTime, hPosition, 46)
ctx.restore();
}
const draw = () => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawBg();
drawCurrentTime();
drawBeforeTime();
drawTime();
window.cancelAnimationFrame(animateId);
animateId = window.requestAnimationFrame(draw);
};
const update = () => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawBg();
drawCurrentTime();
drawBeforeTime();
drawTime();
}
canvas.onmousedown = (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left * (canvas.width / rect.width);
const y = e.clientY - rect.top * (canvas.height / rect.height);
if (Math.abs(x - hPosition) < 10 && Math.abs(y - 16) < 10) {
mouseDown = true;
window.cancelAnimationFrame(animateId);
animateId = null;
}
}
canvas.onmousemove = (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left * (canvas.width / rect.width);
const y = e.clientY - rect.top * (canvas.height / rect.height);
if (mouseDown) {
if (x >= wStart && x <= wEnd) {
hPosition = x;
} else if (x < wStart) {
hPosition = wStart;
} else {
hPosition = wEnd;
}
beforeSelectTime = totalSeconds * (hPosition - wStart) / (wEnd - wStart) * 1000 + moment().startOf("day");
update();
}
}
canvas.onmouseup = (e) => {
if (mouseDown) {
mouseDown = false;
draw();
}
}
canvas.onmouseleave = (e) => {
if (mouseDown) {
mouseDown = false;
draw();
}
}
draw();
<div class="container">
<div class="placeholder"></div>
<canvas class="canvas" id="canvas"></canvas>
<div class="select"></div>
</div>
.container{
width: 700px;
height: 110px;
display: flex;
flex-direction: column;
}
.placeholder{
height: 30px;
}
.canvas{
height: 80px;
flex: 1;
background: #e3e3e3;
}