首页 文章

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

提问于
浏览
2

我正在尝试使用JavaScript和HTML画布为我正在进行的一个小项目创建一个小的循环“均衡器”效果,并且除了一件小事之外它工作得很好 . 它只是一系列矩形条在时间上移动到一个mp3 - 没有什么过于花哨,但此刻所有的条都指向一个方向(即0弧度,或90度) .

我希望围绕圆圈边缘的每个相应矩形直接指向远离中心点,而不是指向右边 . 我有360条,所以每个都应该比以前旋转1度 .

我认为做角度= 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 回答

  • 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>
    
  • 0

    这是另一种解决方案,我保留了你最初的三角学方法 .
    但是我没有使用直线来代替线条,我觉得它对你没什么影响,如果您需要的是 bars moving in time to an mp3 所有你需要做的就是将 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)
    
    <canvas id="c"></canvas>
    

相关问题