如何在基于Canvas的模拟时钟中组装以下代码库,并使Clockface具有28小时112分钟

时间:2019-04-12 16:00:33

标签: javascript html html5-canvas

当分针在112分钟的时钟中击中56分钟时,小时将发生变化(根据以下代码,在56的位置将是第14小时。

我们经过了许多天的尝试,终于在Stackoverflow社区的Kaiido的帮助下取得了突破。它已成为我们月亮时钟系统第一部分的完整解决方案。

我们目前阻止将数字值组装到模拟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 :(得分:0)

您已经具有正确的逻辑以小时:分钟:秒格式来获取时间。

要将其绘制为类似的时钟,只需将这些值转换为角度。

在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小时的映射非常吻合(AM / PM时钟为4分钟宠物滴答声,或28H时钟为2分钟滴答滴答),但请注意, 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>

如果要使用14H 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>