java 脚本 canvas 时钟在正确位置旋转数字

java script canvas clock rotate number in correct position

时钟数字显示位置不正确如何旋转正确位置。 我认为没有计算出每个数字的正确角度。

这几行代码有错误,这里是计算每个数字的角度

谁能找到错误以及如何解决这个问题

以及如何计算模拟时钟方向的数字

for (var n = 1; n <=12; n++) {  
        var theta = (n - 12) * (Math.PI * 2) / 12;
        var x = clockRadius * 0.7 * Math.cos(theta);
        var y = clockRadius * 0.7 * Math.sin(theta);  
        ctx.fillText(n, x, y);  
        ctx.rotate(theta); 
    }

clock image here

时钟时钟

<canvas id="canvas" width="150" height="150"></canvas>
<script>


function init(){

  clock();
  setInterval(clock, 1000);
}
function toRad(degrees) {
    return degrees * (Math.PI / 180);
}
function clock(){  

  var ctx = document.getElementById('canvas').getContext('2d');
  var clockRadius = 110;
  ctx.save();
  ctx.clearRect(0,0,150,150);
  ctx.translate(75,75);
  ctx.scale(0.4,0.4);
  ctx.rotate(-Math.PI/2);
  ctx.fillStyle = "white";
  ctx.lineWidth = 8;
  ctx.lineCap = "round"; 
 ctx.font = '22px Helvetica,Arial,sans-serif';
    ctx.fillStyle = '#fff';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

  var now = new Date($("#datetime").val());
  //alert(now);
  var sec = now.getSeconds();
  var min = now.getMinutes();
  var hr  = now.getHours();
  hr = hr>=12 ? hr-12 : hr; 

   for (var n = 1; n <=12; n++) {  
        var theta = (n - 12) * (Math.PI * 2) / 12;
        var x = clockRadius * 0.7 * Math.cos(theta);
        var y = clockRadius * 0.7 * Math.sin(theta);  
        ctx.fillText(n, x, y);  
        ctx.rotate(theta ); 
    }

  ctx.strokeStyle = "white";
  ctx.save();
  for (var i=0; i < 12; i++){
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.moveTo(100,0);
    ctx.lineTo(120,0);
    ctx.stroke();
  }
  ctx.restore();

  // Minute marks
  ctx.save();
  ctx.lineWidth = 5;
  for (i=0;i<60;i++){
    if (i%5!=0) {
      ctx.beginPath();
      ctx.moveTo(117,0);
      ctx.lineTo(120,0);
      ctx.stroke();
    }
    ctx.rotate(Math.PI/30);
  }
  ctx.restore();

  ctx.fillStyle = "black";

  // write Hours

  ctx.strokeStyle = "#4D514E";
  ctx.save();
  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
  ctx.lineWidth = 14;
  ctx.beginPath();
  ctx.moveTo(-20,0);
  ctx.lineTo(80,0);
  ctx.stroke();
  ctx.restore();

  // write Minutes
  ctx.save();
  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(-28,0);
  ctx.lineTo(110,0);
  ctx.stroke();
  ctx.restore();

  // Write seconds
  ctx.save();
  ctx.rotate(sec * Math.PI/30);
  ctx.strokeStyle = "#D40000";
  ctx.fillStyle = "#D40000";
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(-30,0);
  ctx.lineTo(110,0);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.stroke();
  ctx.fillStyle = "rgba(0,0,0,0)";
  ctx.arc(0,0,3,0,Math.PI*2,true);
  ctx.fill();
  ctx.restore();

  ctx.beginPath();
  ctx.lineWidth = 14;
  ctx.strokeStyle = '#494545';
  ctx.arc(0,0,142,0,Math.PI*2,true);
  ctx.stroke();

  ctx.restore();
} init(); 
</script>

由于您在 clock 函数的开头调用了 ctx.rotate(-Math.PI/2),因此您需要将数字旋转回来。为此,您需要先将上下文转换为数字坐标,然后将上下文旋转 Math.PI/2.

替换您的 for 循环中的这部分代码:

ctx.fillText(n, x, y);
ctx.rotate(theta );

有了这个:

ctx.save();
ctx.translate(x, y);
ctx.rotate(Math.PI/2);
ctx.fillText(n, 0, 0);
ctx.restore();

您在时钟函数的第 7 行中旋转了整个上下文。

function clock(){  

  var ctx = document.getElementById('canvas').getContext('2d');
  var clockRadius = 110;
  ctx.save();
  ctx.clearRect(0,0,150,150);
  ctx.translate(75,75);
  ctx.scale(0.4,0.4);
  ctx.rotate(-Math.PI/2); // <-- remove this
  ctx.fillStyle = "white";
  ...

你需要删除它。您可以在绘制手臂时旋转而不是这样做。

// write Hours
ctx.rotate( -Math.PI/2 + hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )

// write Minutes
ctx.rotate( -Math.PI/2 + (Math.PI/30)*min + (Math.PI/1800)*sec )

// Write seconds
ctx.rotate( -Math.PI/2 + sec * Math.PI/30);

(绘制数字的代码需要稍作修改)

var theta = (n - 3) * (Math.PI * 2) / 12;

function init(){

  clock();
  setInterval(clock, 1000);
}
function toRad(degrees) {
    return degrees * (Math.PI / 180);
}
function clock(){  

  var ctx = document.getElementById('canvas').getContext('2d');
  var clockRadius = 110;
  ctx.save();
  ctx.clearRect(0,0,150,150);
  ctx.translate(75,75);
  ctx.scale(0.4,0.4);
  ctx.fillStyle = "white";
  ctx.lineWidth = 8;
  ctx.lineCap = "round"; 
 ctx.font = '22px Helvetica,Arial,sans-serif';
    ctx.fillStyle = '#fff';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

  var now = new Date('2000/1/1 ' + $("#datetime").val());
  //alert(now);
  var sec = now.getSeconds();
  var min = now.getMinutes();
  var hr  = now.getHours();
  hr = hr>=12 ? hr-12 : hr; 

   for (var n = 1; n <=12; n++) {  
        var theta = (n - 3) * (Math.PI * 2) / 12;
        var x = clockRadius * 0.7 * Math.cos(theta);
        var y = clockRadius * 0.7 * Math.sin(theta);  
        ctx.fillText(n, x, y);  
    }

  ctx.strokeStyle = "white";
  ctx.save();
  for (var i=0; i < 12; i++){
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.moveTo(100,0);
    ctx.lineTo(120,0);
    ctx.stroke();
  }
  ctx.restore();

  // Minute marks
  ctx.save();
  ctx.lineWidth = 5;
  for (i=0;i<60;i++){
    if (i%5!=0) {
      ctx.beginPath();
      ctx.moveTo(117,0);
      ctx.lineTo(120,0);
      ctx.stroke();
    }
    ctx.rotate(Math.PI/30);
  }
  ctx.restore();

  ctx.fillStyle = "black";

  // write Hours

  ctx.strokeStyle = "#4D514E";
  ctx.save();
  ctx.rotate( -Math.PI/2 + hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
  ctx.lineWidth = 14;
  ctx.beginPath();
  ctx.moveTo(-20,0);
  ctx.lineTo(80,0);
  ctx.stroke();
  ctx.restore();

  // write Minutes
  ctx.save();
  ctx.rotate( -Math.PI/2 +(Math.PI/30)*min + (Math.PI/1800)*sec )
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(-28,0);
  ctx.lineTo(110,0);
  ctx.stroke();
  ctx.restore();

  // Write seconds
  ctx.save();
  ctx.rotate(-Math.PI/2 +sec * Math.PI/30);
  ctx.strokeStyle = "#D40000";
  ctx.fillStyle = "#D40000";
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(-30,0);
  ctx.lineTo(110,0);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.stroke();
  ctx.fillStyle = "rgba(0,0,0,0)";
  ctx.arc(0,0,3,0,Math.PI*2,true);
  ctx.fill();
  ctx.restore();

  ctx.beginPath();
  ctx.lineWidth = 14;
  ctx.strokeStyle = '#494545';
  ctx.arc(0,0,142,0,Math.PI*2,true);
  ctx.stroke();


  ctx.restore();
} init(); 
canvas {
background: blue;
}
<input type="time" id="datetime" value="03:45:01">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="150" height="150"></canvas>
<script>



</script>