【问题标题】:Someone who knows CanvasRenderingContext2D in React, please help :)知道 React 中的 CanvasRenderingContext2D 的人,请帮助:)
【发布时间】:2021-03-20 19:32:18
【问题描述】:

当我单击旋转按钮时,我希望值在画布中一一突出显示。 在这里你可以看到整个代码:https://codesandbox.io/s/spinning-wheel-react-forked-s528m


  renderWheel() {
    // determine number/size of sectors that need to created
    let numOptions = this.state.list.length;
    let arcSize = (2 * Math.PI) / numOptions;
    this.setState({
      angle: arcSize
    });

    // dynamically generate sectors from state list
    let angle = 0;
    for (let i = 0; i < numOptions; i++) {
      let text = this.state.list[i];
      this.renderSector(i + 1, text, angle, arcSize);
      angle += arcSize;
    }
  }

  renderSector(index, text, start, arc) {
    // create canvas arc for each list element
    let canvas = document.getElementById("wheel");
    let ctx = canvas.getContext("2d");
    let x = canvas.width / 2;
    let y = canvas.height / 2;
    let radius = 200;
    let startAngle = start;
    let endAngle = start + arc - 0.02;
    let angle = index * arc;
    let baseSize = radius * 1.25;
    let textRadius = baseSize - 48;

    ctx.beginPath();
    ctx.arc(x, y, radius, startAngle, endAngle, false);
    ctx.lineWidth = radius * 0.25;
    ctx.strokeStyle = "white";

    ctx.font = "25px Arial";
    ctx.fillStyle = "blue";

    ctx.stroke();

    ctx.save();
    ctx.translate(
      baseSize + Math.cos(angle - arc / 2) * textRadius,
      baseSize + Math.sin(angle - arc / 2) * textRadius
    );
    ctx.rotate(0);
    ctx.fillText(text, -ctx.measureText(text).width / 2, 7);
    ctx.restore();
  }

当我点击旋转按钮时,这个 spin() 方法被执行。 如 setTimeout 方法中所写,迭代在 2 到 5 秒之间结束。


spin = () => {
    var index = 0;
    let timer = setInterval(() => {
      index = (index) % this.state.list.length + 1;
      console.log(index)
    }, 150);
  
    // calcalute result after wheel stops spinning
    setTimeout(() => {
     clearInterval(timer);

      this.setState({
        hasFinishedLoading: true,
        display: this.state.list[index]
      });
    }, Math.floor(Math.random() * 5000 + 2000));

    this.setState({
      spinning: true
    });
  };



【问题讨论】:

    标签: reactjs


    【解决方案1】:

    请记住:在画布中您无法访问特定对象,因此解决方案始终是擦除和重绘。不用担心性能,这非常棒。我给你的代码留下一个想法,最后给出一些建议。试试这段代码,我唯一做的就是清理画布并在没有 setTimeOut 索引的情况下重绘

    spin = () => {
      let canvas = document.getElementById("wheel");
      let ctx = canvas.getContext("2d");
      var index = 0;
      index = (index % this.state.list.length) + 1;
      let angle = 0;
      let numOptions = this.state.list.length;
      let arcSize = (2 * Math.PI) / numOptions;
      let timer = setInterval(() => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    
      this.setState({
        angle: arcSize
      });
      for (let i = 0; i < numOptions; i++) {
        if (i !== index) {
          let text = this.state.list[i];
          this.renderSector(i + 1, text, angle, arcSize);
          angle += arcSize;
        } else {
        }
      }
    }, 150);
    
    // calcalute result after wheel stops spinning
    setTimeout(() => {
      clearInterval(timer);
    
      this.setState({
        hasFinishedLoading: true,
        display: this.state.list[index]
      });
    }, Math.floor(Math.random() * 5000 + 2000));
    
    this.setState({
      spinning: true
    });
    };
    
    • 不要在反应中使用“getElementById”,这很危险。使用参考。

    【讨论】:

    • 非常感谢。但是有什么方法可以防止值被删除吗?这对我来说真的很重要
    • @Alex 要在画布上生成更改效果,您必须清理并重绘。在这种情况下,您必须清理整个画布,绘制除轮子所在位置之外的轮子,并在该位置绘制另一种颜色或大小。
    • 我明白了。你认为我可以在没有 CanvasRenderingContext2D 的情况下以更好的方式制作同样的轮子吗?一些建议
    • @Alex 您还可以使用 div 和 css(属性转换、旋转等)。无论如何,我认为最理想的是画布。
    • 嘿,我设法使这些值在渲染时可见。有兴趣的可以看这里:codesandbox.io/s/spinning-wheel-react-forked-s528m
    猜你喜欢
    • 2023-01-19
    • 2015-01-03
    • 2010-11-09
    • 2022-07-07
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    相关资源
    最近更新 更多