Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么需要多个rotate()来将每个数字放置在正确的位置上帆布钟号码_Javascript_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 为什么需要多个rotate()来将每个数字放置在正确的位置上帆布钟号码

Javascript 为什么需要多个rotate()来将每个数字放置在正确的位置上帆布钟号码,javascript,canvas,html5-canvas,Javascript,Canvas,Html5 Canvas,下面展示了如何使用HTML画布制作模拟时钟,我很难理解到底发生了什么 代码是,下面是我想问的部分 function drawNumbers(ctx, radius) { var ang; var num; ctx.font = radius * 0.15 + "px arial"; ctx.textBaseline = "middle"; ctx.textAlign = "center"; for(num =

下面展示了如何使用HTML画布制作模拟时钟,我很难理解到底发生了什么

代码是,下面是我想问的部分

function drawNumbers(ctx, radius) {
  var ang;
  var num;
  ctx.font = radius * 0.15 + "px arial";
  ctx.textBaseline = "middle";
  ctx.textAlign = "center";

  for(num = 1; num < 13; num++){
    ang = num * Math.PI / 6;
    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);
  }
}
功能图纸编号(ctx,半径){
瓦朗;
var-num;
ctx.font=半径*0.15+“px arial”;
ctx.textb基线=“中间”;
ctx.textAlign=“中心”;
对于(num=1;num<13;num++){
ang=num*Math.PI/6;
ctx.旋转(ang);
平移(0,-半径*0.85);
ctx.旋转(-ang);
ctx.fillText(num.toString(),0,0);
ctx.旋转(ang);
平移(0,半径*0.85);
ctx.旋转(-ang);
}
}
在for循环中,第一个
ctx.rotate(ang)
设置它应该在的位置上的数字

下一个旋转
ctx.rotate(-ang)
将数字恢复为竖直,因为它是倾斜的。(虽然我不知道为什么它会这样工作,不会将数字放回第一位。)

然后,在
ctx.fillText(…)
向上显示数字之后,它似乎又做了同样的事情


为什么需要这两个
rotate()
?它们的工作原理与上面的不同吗?如果执行,如何执行?

此代码尝试执行的是返回到其以前的位置,即画布的中心

把上下文想象成一张纸,你可以用一支固定的笔在上面旋转和移动(
translate

  • 首先,他们确实会旋转那张纸,以便沿着所需的方向追踪垂直线
  • 然后垂直移动纸张,使笔处于正确的位置。然而,在这里,这张纸仍然是旋转的,因此如果他们从这里水平地绘制文本,绘图将是倾斜的
  • 因此,它们会以另一种方式再次旋转,以使文本处于正确的角度
  • 他们画课文
  • 现在他们想回到第1点来画下一个记号。为此,它们执行相同的路径,但方式不同:将纸张旋转回所需的角度,以便它们可以垂直移动到中心
  • 垂直移动到中心
  • 最后,向后旋转,以便纸张在下一次勾选时处于其原始方向
但是您不应该这样做。
rotate()
可能会出现舍入问题,因此执行
旋转(角度);旋转(-angle)
无法返回到初始方向,但会返回到稍微旋转的状态,这对应用程序来说可能是灾难性的,因为现在当您尝试绘制像素完美线时,您将无法恢复,并且会破坏应用程序的整个性能

而是使用绝对法返回到原始位置:

var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
变量半径=画布高度/2;
半径=半径*0.90
图纸编号(ctx、半径);
功能图纸编号(ctx、半径){
瓦朗;
var-num;
ctx.font=半径*0.15+“px arial”;
ctx.textb基线=“中间”;
ctx.textAlign=“中心”;
对于(num=1;num<13;num++){
ang=num*Math.PI/6;
//回到中间
setTransform(1,0,0,1,radius,radius);
ctx.旋转(ang);
平移(0,-半径*0.85);
ctx.旋转(-ang);
ctx.fillText(num.toString(),0,0);
}
//重置为单位矩阵;
setTransform(1,0,0,1,0,0);
}
画布{
背景色:白色;
}

这里是另一个不使用rotate的实现。
相反,我用一点三角法计算
x,y

起始角度为
var ang=Math.PI
然后在循环中,我们减少它
ang-=Math.PI/6

一旦知道以下公式,计算位置就很容易了:

let x = radius * Math.sin(ang)
let y = radius * Math.cos(ang)
下面是一个功能完整的示例

var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
ctx.translate(canvas.width/2,canvas.height/2);
ctx.font=“16px arial”;
ctx.textAlign=“中心”;
var半径=60
var ang=Math.PI;
for(设num=1;num<13;num++){
ang-=Math.PI/6;
设x=radius*Math.sin(ang)
设y=radius*Math.cos(ang)
ctx.fillText(num.toString(),x,y);
ctx.beginPath()
弧(x,y-6,12,0,2*Math.PI);
ctx.stroke();
ctx.beginPath()
弧(x,y-6,45,-ang-2,-ang);
ctx.stroke();
}

非常感谢您的回答!现在,我无法进行第一轮旋转。我相信它是顺时针旋转的,看起来1号应该放在11号点上。。。我试着用一张方形的便笺和固定在便笺中心的笔来理解这个概念。我现在误解了什么?是的,很抱歉混淆了,实际上是绘图工具在旋转,而不是纸张,因此旋转与纸张相反。与第一次平移(半径)一样,它会将笔从左上角移动到中心,如果我们将纸张作为参考,变换也会反转。我已经写了这篇文章,我仍然不确定我的理解是否正确。如果你能查一下,我会很感激的@卡霍:是的,我听起来很对,你的解释比我的更清楚;-)