У вас уже есть правильная логика, чтобы получить время в формате Часы: Минуты: Секунды.
Чтобы нарисовать как аналоговые часы, вам просто нужно преобразовать эти значения в угол.
На 12-часовых часах мы делаем ((Math.PI * 2) / 12) * (hour % 12)
, или, более буквально, (full_circle / number_of_hours_per_circle) * (hour % number_of_hours_per_circle)
.
В вашем проекте у вас есть 28 часов в день, поэтому вы можете попытаться сделать 14-часовые часы, чтобы сохранить AM / PMформатировать, но вы не обязаны.
Теперь, ваши округленные 56 минут в час очень хорошо отображаются с 28 часами в день (тиканье 4 минуты на часах AM / PM или 2 минуты на тик на 28Hчасы), но знайте, что ваш исходный 55.54920598892
не будет отображаться так хорошо.
// our constants
var ms_per_sec = 1000; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
var countDownDate = new Date().getTime() +
(1 * hrs_per_day * min_per_hr * sec_per_min * ms_per_sec) + // 1 day
(2 * min_per_hr * sec_per_min * ms_per_sec) + // two hours
(1 * sec_per_min * ms_per_sec) + // 1 minutes
(5 * ms_per_sec); // 5 seconds
// Update the count down every frame
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % sec_per_min);
// Output the result in an element with id="demo"
draw(hours, minutes, seconds);
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
radius = radius * 0.90
function draw(hours, minutes, seconds) {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(canvas.height / 2, canvas.height / 2);
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius, hours, minutes, seconds);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.08 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 29; num++) {
ang = num * Math.PI / 14;
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius, hours, minutes, seconds) {
const angle_hours = getAngle(hours, hrs_per_day);
drawHand(ctx, angle_hours, radius * 0.5, radius * 0.07);
//minute
const angle_minutes = getAngle(minutes, min_per_hr);
drawHand(ctx, angle_minutes, radius * 0.8, radius * 0.07);
// second
const angle_seconds = getAngle(seconds, sec_per_min);
drawHand(ctx, angle_seconds, radius * 0.9, radius * 0.02);
}
function getAngle(value, max) {
return (Math.PI*2 / max) * value;
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
loop();
<html>
<body>
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>
</html>
А если вы хотите вариант 14 / AM AM / PM:
// our constants
var ms_per_sec = 1000; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
var countDownDate = new Date().getTime() +
(1 * hrs_per_day * min_per_hr * sec_per_min * ms_per_sec) + // 1 day
(2 * min_per_hr * sec_per_min * ms_per_sec) + // two hours
(1 * sec_per_min * ms_per_sec) + // 1 minutes
(5 * ms_per_sec); // 5 seconds
// Update the count down every frame
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % sec_per_min);
// Output the result in an element with id="demo"
draw(hours, minutes, seconds);
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
radius = radius * 0.90
function draw(hours, minutes, seconds) {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(canvas.height / 2, canvas.height / 2);
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius, hours, minutes, seconds);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.08 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 15; num++) {
ang = num * Math.PI / (14/2);
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius, hours, minutes, seconds) {
const angle_hours = getAngle(hours % hrs_per_day/2, hrs_per_day/2);
drawHand(ctx, angle_hours, radius * 0.5, radius * 0.07);
//minute
const angle_minutes = getAngle(minutes, min_per_hr);
drawHand(ctx, angle_minutes, radius * 0.8, radius * 0.07);
// second
const angle_seconds = getAngle(seconds, sec_per_min);
drawHand(ctx, angle_seconds, radius * 0.9, radius * 0.02);
}
function getAngle(value, max) {
return (Math.PI*2 / max) * value;
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
loop();
<html>
<body>
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>
</html>