在画布上围绕圆周长旋转矩形

时间:2018-10-01 20:36:35

标签: javascript canvas html5-canvas geometry trigonometry

我正在尝试使用JavaScript和HTML画布为我正在处理的一个小项目创建一个圆形的“均衡器”效果,并且除一件小事情外,效果很好。它只是一系列随时间移动到mp3的矩形条-一点也不花哨,但此刻所有的条都指向一个方向(即0弧度或90度)。

我希望围绕圆的边缘的每个矩形都直接指向远离中心点的位置,而不是指向右边。我有360个小节,因此自然而然地,每个小节应比前一个多旋转1度。

我认为做angle = i * Math.PI / 180可以解决这个问题,但是我对旋转功能的作用似乎并不重要-它们总是总是指向奇怪而奇妙的方向,并被平移距离他们一百万英里。我不明白为什么。谁能看到我要去哪里错了?

我的框架代码如下:

function frames() {

  // Clear the canvas and get the mp3 array
  window.webkitRequestAnimationFrame(frames);
  musicArray = new Uint8Array(analyser.frequencyBinCount);
  analyser.getByteFrequencyData(musicArray);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  bars = 360;


  for (var i = 0; i < bars; i++) {

    // Find the rectangle's position on circle edge
    distance = 100;
    var angle = i * ((Math.PI * 2) / bars);
    var x = Math.cos(angle) * distance + (canvas.width / 2);
    var y = Math.sin(angle) * distance + (canvas.height / 2);
    barWidth = 5;
    barHeight = (musicArray[i] / 4);

    // Fill with a blue-green gradient
    var grd = ctx.createLinearGradient(x, 0, x + 40, 0);
    grd.addColorStop(0, "#00CCFF");
    grd.addColorStop(1, "#00FF7F");
    ctx.fillStyle = grd;

    // Rotate the rectangle according to position
    // ctx.rotate(i*Math.PI/180); - DOESN'T WORK

    // Draw the rectangle
    ctx.fillRect(x, y, barHeight, barWidth);

  }

2 个答案:

答案 0 :(得分:2)

为清楚起见,我已删除了部分代码。我正在按照您的预期使用旋转。另外,我使用barHeight = (Math.random()* 50);代替了(musicArray[i]/4);,因为我想展示一些东西。

我也将您的小节更改为180。很有可能您将没有360小节,但是32或64或128或256。 。 。现在,您可以将裸机编号更改为这些编号之一,以查看结果。

我正在围绕画布的原点绘制所有内容,并在中间翻译上下文。

希望对您有帮助。

const canvas = document.getElementById("c");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 400;
let ch = canvas.height = 400;


let bars = 180;
let r = 100;

ctx.translate(cw / 2, ch / 2)

for (var i = 0; i < 360; i += (360 / bars)) {

  // Find the rectangle's position on circle edge

  var angle = i * ((Math.PI * 2) / bars);
  //var x = Math.cos(angle)*r+(canvas.width/2);
  //var y = Math.sin(angle)*r+(canvas.height/2);
  barWidth = 2 * Math.PI * r / bars;
  barHeight = (Math.random() * 50);


  ctx.fillStyle = "green";

  // Rotate the rectangle according to position
  // ctx.rotate(i*Math.PI/180); - DOESN'T WORK

  // Draw the rectangle
  ctx.save();
  ctx.rotate(i * Math.PI / 180);

  ctx.fillRect(r, -barWidth / 2, barHeight, barWidth);

  //ctx.fillRect(r ,0, barHeight, barWidth);

  ctx.restore();
}
canvas {
  border: 1px solid
}
<canvas id="c"></canvas>

答案 1 :(得分:0)

这是另一种解决方案,我保留了您最初的三角学方法。
但是,如果我需要的是酒吧及时移动到mp3 ,那么我认为使用的不是矩形,而是线性的,{{1 }}到Amplitude中的读数,这些小节会跳舞。

var v = Math.random() + 1;
const canvas = document.getElementById("c");
canvas.width = canvas.height = 170;
const ctx = canvas.getContext("2d");
ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.lineWidth = 2;

let r = 40;
let bars = 180;

function draw() {
  ctx.clearRect(-100, -100, 200, 200)

  for (var i = 0; i < 360; i += (360 / bars)) {
    var angle = i * ((Math.PI * 2) / bars);
    var x = Math.cos(angle) * r;
    var y = Math.sin(angle) * r;

    ctx.beginPath();
    var v = Math.random() + 1;
    ctx.moveTo(x, y);
    ctx.lineTo(x * v, y * v)

    grd = ctx.createLinearGradient(x, y, x*2, y*2);
    grd.addColorStop(0, "blue");
    grd.addColorStop(1, "red");
    ctx.strokeStyle = grd;
    ctx.stroke();
  }
}

setInterval(draw, 100)