HTML5画布文字方向盘内轮

时间:2018-09-29 14:00:32

标签: javascript html5 canvas text rotation

https://jsfiddle.net/5e7hwn8m/

嗨,我想先设置一个带有数字的轮子,然后在从A到F(A,B,C,D,E和F)中标识的选定数字内。

问题是A-F像数字一样在旋转,我不希望那样,而且我似乎也无法弄清楚如何使它们面对我的方向。

有人能指出我正确的方向吗? jsfiddle代码供参考:https://jsfiddle.net/5e7hwn8m/

var wheelNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"];
//16 20 18 55 5 25
var wheelABCDEF = ["", "", "", "", "E", "", "", "", "",
  "", "", "", "", "", "", "A", "", "C", "",
  "B", "", "", "", "", "F", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "D", "", "", "", ""
];


var backgroundColours = ["#ffff00", "#ffff00", "#ffff00", "#ffff00", "#005def", "#ffff00", "#ffff00", "#ffff00", "#ffff00", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#005def", "#66ffff", "#005def", "#66ffff", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#005def", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb"];
var startAngle = 4.7;
var arc = Math.PI / (wheelNumbers.length / 2);


var ctx;

function drawWheel() {
  var canvas = document.getElementById("canvas");

  canvas.width = canvas.scrollWidth;
  canvas.height = canvas.scrollHeight;

  if (canvas.getContext) {
    var outsideRadius = 150;
    var insideRadius = 120;
    var textRadius = 160;

    ctx = canvas.getContext("2d");
    //ctx.clearRect(0,0,400,400);

    //ctx.strokeStyle = "black";
    ctx.lineWidth = 0.8;

    ctx.font = 'bold 12px Helvetica, Arial';

    for (var i = 0; i < wheelNumbers.length; i++) {
      var angle = startAngle + i * arc;
      ctx.fillStyle = backgroundColours[i];

      ctx.beginPath();
      ctx.arc(200, 200, outsideRadius, angle, angle + arc, false);
      ctx.arc(200, 200, insideRadius, angle + arc, angle, true);
      ctx.stroke();
      ctx.fill();
      //
      ctx.save();
      //ctx.shadowOffsetX = -1;
      //ctx.shadowOffsetY = -1;
      //ctx.shadowBlur    = 0;
      //ctx.shadowColor   = "rgb(220,220,220)";
      //'#005def'
      ctx.fillStyle = '#444';
      ctx.translate(200 + Math.cos(angle + arc / 2) * textRadius, 200 + Math.sin(angle + arc / 2) * textRadius);
      ctx.rotate(angle + arc / 2 + Math.PI / 2);
      var text = wheelNumbers[i];
      ctx.fillText(text, -ctx.measureText(text).width / 2, 0);

      text = wheelABCDEF[i];
      ctx.fillStyle = '#005def';

      ctx.rotate(0);
      ctx.fillText(text, 0, 60);


      ctx.restore();

    }

  }
}



drawWheel();
html,
body {
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>

  <body>
    <canvas id="canvas" width="400" height="400"></canvas>

    <script src="sketch.js"></script>
  </body>

</html>

谢谢!

3 个答案:

答案 0 :(得分:0)

一种方法是在转轮后呈现字母。

使用它们在阵列中的位置确定车轮上的角度。 而不是使用cos和sin在像素中找到它们的位置。

答案 1 :(得分:0)

我不确定这是否是您要的。我正在计算字母应该出现的点,并且我在不旋转的情况下绘制字母。 在代码中,我标记了所做的更改。

var wheelNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"];
//16 20 18 55 5 25
var wheelABCDEF = ["", "", "", "", "E", "", "", "", "",
  "", "", "", "", "", "", "A", "", "C", "",
  "B", "", "", "", "", "F", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "D", "", "", "", ""
];


var backgroundColours = ["#ffff00", "#ffff00", "#ffff00", "#ffff00", "#005def", "#ffff00", "#ffff00", "#ffff00", "#ffff00", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#005def", "#66ffff", "#005def", "#66ffff", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#005def", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb"];
var startAngle = 4.7;
var arc = Math.PI / (wheelNumbers.length / 2);


var ctx;

function drawWheel() {
  var canvas = document.getElementById("canvas");

  canvas.width = canvas.scrollWidth;
  canvas.height = canvas.scrollHeight;

  if (canvas.getContext) {
    var outsideRadius = 150;
    var insideRadius = 120;
    var textRadius = 160;

    ctx = canvas.getContext("2d");
    //ctx.clearRect(0,0,400,400);

    //ctx.strokeStyle = "black";
    ctx.lineWidth = 0.8;

    ctx.font = 'bold 12px Helvetica, Arial';

    for (var i = 0; i < wheelNumbers.length; i++) {
      var angle = startAngle + i * arc;
      ctx.fillStyle = backgroundColours[i];

      ctx.beginPath();
      ctx.arc(200, 200, outsideRadius, angle, angle + arc, false);
      ctx.arc(200, 200, insideRadius, angle + arc, angle, true);
      ctx.stroke();
      ctx.fill();
      //
      ctx.save();
      //ctx.shadowOffsetX = -1;
      //ctx.shadowOffsetY = -1;
      //ctx.shadowBlur    = 0;
      //ctx.shadowColor   = "rgb(220,220,220)";
      //'#005def'
      ctx.fillStyle = '#444';
      
      /////////////////////////////////////////////////
      // calculating the position for the letter
      var x = 200 + Math.cos(angle + arc / 2) * 100;
      var y = 200 + Math.sin(angle + arc / 2) * 100;
      /////////////////////////////////////////////////
      
      ctx.translate(200 + Math.cos(angle + arc / 2) * textRadius, 200 + Math.sin(angle + arc / 2) * textRadius);
      ctx.rotate(angle + arc / 2 + Math.PI / 2);
      var text = wheelNumbers[i];
      ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
      ctx.restore();// restore goes here
      
      
      text = wheelABCDEF[i];
      ctx.fillStyle = '#005def';

      // paint the letter  without rotating
      ctx.fillText(text, x, y);


      

    }

  }
}



drawWheel();
<canvas id="canvas" width="400" height="400"></canvas>

答案 2 :(得分:0)

您的问题是 ctx.rotate()是相对于当前矩阵变换的,还是相对于当前旋转角度的关系。

这意味着您的rotate(0)将不执行任何操作。您想要的是rotate( -currentAngle )
但是在调用它之前,您必须将文本的位置设置为旋转的枢轴,即作为我们的转换矩阵的原点,这可以通过调用ctx.translate(text_x, text_x)来完成,因为我们现在位于文本位置,我们可以使用0、0参数调用fillText:

// set the origin to the text's position
ctx.translate(0,60);
// reverse rotate
ctx.rotate(-currentAngle);
// draw at origin (0,0)
ctx.fillText(text, 0, 0);

var wheelNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"];
//16 20 18 55 5 25
var wheelABCDEF = ["", "", "", "", "E", "", "", "", "",
  "", "", "", "", "", "", "A", "", "C", "",
  "B", "", "", "", "", "F", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "", "", "", "", "",
  "", "", "", "", "", "D", "", "", "", ""
];


var backgroundColours = ["#ffff00", "#ffff00", "#ffff00", "#ffff00", "#005def", "#ffff00", "#ffff00", "#ffff00", "#ffff00", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#66ffff", "#005def", "#66ffff", "#005def", "#66ffff", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#005def", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#c0c0c0", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#33cc33", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ff99ff", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb", "#005def", "#ffffbb", "#ffffbb", "#ffffbb", "#ffffbb"];
var startAngle = 4.7;
var arc = Math.PI / (wheelNumbers.length / 2);


var ctx;

function drawWheel() {
  var canvas = document.getElementById("canvas");

  canvas.width = canvas.scrollWidth;
  canvas.height = canvas.scrollHeight;

  if (canvas.getContext) {
    var outsideRadius = 150;
    var insideRadius = 120;
    var textRadius = 160;

    ctx = canvas.getContext("2d");
    //ctx.clearRect(0,0,400,400);

    //ctx.strokeStyle = "black";
    ctx.lineWidth = 0.8;

    ctx.font = 'bold 12px Helvetica, Arial';

    for (var i = 0; i < wheelNumbers.length; i++) {
      var angle = startAngle + i * arc;
      ctx.fillStyle = backgroundColours[i];

      ctx.beginPath();
      ctx.arc(200, 200, outsideRadius, angle, angle + arc, false);
      ctx.arc(200, 200, insideRadius, angle + arc, angle, true);
      ctx.stroke();
      ctx.fill();
      //
      ctx.save();
      //ctx.shadowOffsetX = -1;
      //ctx.shadowOffsetY = -1;
      //ctx.shadowBlur    = 0;
      //ctx.shadowColor   = "rgb(220,220,220)";
      //'#005def'
      ctx.fillStyle = '#444';
      ctx.translate(200 + Math.cos(angle + arc / 2) * textRadius, 200 + Math.sin(angle + arc / 2) * textRadius);
/* BEGIN EDIT*/
      // save the currentAngle in a variable
      var currentAngle = angle + arc / 2 + Math.PI / 2;
      ctx.rotate(currentAngle);
      var text = wheelNumbers[i];
      ctx.fillText(text, -ctx.measureText(text).width / 2, 0);

      text = wheelABCDEF[i];
      ctx.fillStyle = '#005def';
      // set the origin to the text's position
      ctx.translate(0,60);
      // reverse rotate
      ctx.rotate(-currentAngle);
      // draw at origin (0,0)
      ctx.fillText(text, 0, 0);
/* END EDIT*/
      ctx.restore();

    }

  }
}



drawWheel();
html,
body {
  margin: 0;
  padding: 0;
}
<!DOCTYPE html>
<html>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>

  <body>
    <canvas id="canvas" width="400" height="400"></canvas>

    <script src="sketch.js"></script>
  </body>

</html>