Как собрать следующую кодовую базу в аналоговых часах на основе Canvas с Clockface, имеющим 28 часов и 112 минут - PullRequest
0 голосов
/ 12 апреля 2019

Часы сместятся, когда минутная стрелка нажмет 56 минут на 112-минутных часах (позиция на 56 будет 14-м часом согласно следующему коду.

Мы пробовали много решений в течение многих дней и, наконец,произошел прорыв с помощью Kaiido из сообщества Stackoverflow, который стал полным решением для первой части нашей системы часов для Луны.

В настоящее время мы заблокировали на этапе объединения цифровых значений в аналоговый Canvas.система часов. Цель этой работы часов состоит в том, чтобы выполнить стремление помочь и объединить усилия с научным сообществом. Ваш вклад в наши усилия высоко ценится.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);

function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
  drawTime(ctx, radius);
}

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) {
  var now = new Date();
  var hour = now.getHours();
  var minute = now.getMinutes();
  var second = now.getSeconds();
  //hour
  hour = hour % 12;
  hour = (hour * Math.PI / 6) +
    (minute * Math.PI / (6 * 60)) +
    (second * Math.PI / (360 * 60));
  drawHand(ctx, hour, radius * 0.5, radius * 0.07);
  //minute
  minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60));
  drawHand(ctx, minute, radius * 0.8, radius * 0.07);
  // second
  second = (second * Math.PI / 30);
  drawHand(ctx, second, radius * 0.9, radius * 0.02);
}

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);
}
<html>

<body>

  <canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>

</html>
    The values are to be inserted from the following code base, where the  
    minutes seconds and hours run using the following format,

    28 hours = 1 day
    56 mins = 1 hour
    56 seconds = 1 minute

// 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"
  document.getElementById("demo").textContent = days + "d " + hours + "h "
  + minutes + "m " + seconds + "s ";
    
  // If the count down is over, write some text 
  if (total_ms < 0) {
    document.getElementById("demo").innerHTML = "EXPIRED";
    return;
  }
  requestAnimationFrame(loop);
 }
 loop();
<html>
<body>

<div id="demo"></div>
</body>
</html>
    The problem faced is that the analog clock has a settimeInterval that  
    makes the looped code execute at a faster rate, messing with the time of  
    the clock. Is there a way to execute the analog clock in a cleaner way.

    We are happy to have arrived at the solution for the digital clock with                                 
    the help of the stackoverflow community. The hours assembled in the 
    digital clock are running perfectly as expected. We are looking forward 
    to the solution on the analog clock. Your help towards our Research work 
    with ourmoonlife is highly respected. We consider our work to be the 
    common property of this planet, we welcome you to join hands with us.
    Thanks for the wonderful opportunity.

1 Ответ

0 голосов
/ 14 апреля 2019

У вас уже есть правильная логика, чтобы получить время в формате Часы: Минуты: Секунды.

Чтобы нарисовать как аналоговые часы, вам просто нужно преобразовать эти значения в угол.

На 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...