Javascript Canvas 绘制顺序

标签 javascript html html5-canvas

我正在 JavaScript 循环中绘制带有一些系列值的条形图。尽管绘制系列值的代码位于绘制条形的代码下方,但在循环的下一次迭代中,刚刚绘制的文本会被覆盖。

当警报框出现时,您可以在下面的代码中看到这种效果的发生。

为什么在 Canvas 的另一部分上进行的绘制操作会覆盖之前在完全不同的位置绘制的内容?

更新:有人有用地指出使用 fillRect() 隐藏了这个问题,但我的问题是:为什么它首先发生?

var exampleData = {
  "Series 1": 10,
  "Series 2": 14,
  "Series 3": 2,
  "Series 4": 12
};

var BarChart = function(options) {
  this.options = options;
  this.canvas = options.canvas;
  this.ctx = this.canvas.getContext("2d");
  this.colors = options.colors;

  this.plot = function() {
    var maxValue = 0;
    for (var categ in this.options.data) {
      maxValue = Math.max(maxValue, this.options.data[categ]);
    }

    var noBars = Object.keys(this.options.data).length;
    var barWidth = (this.canvas.height) / noBars;
    var barIdx = 0;

    for (categ in this.options.data) {
      var barLength = Math.round(this.canvas.width * this.options.data[categ] / maxValue);
      this.ctx.save();
      alert("plotting series line " + categ);
      this.ctx.fillStyle = this.colors[barIdx % this.colors.length];
      this.ctx.rect(30, barIdx * barWidth, barLength, barWidth);
      this.ctx.fill();
      alert("plotting series value " + categ);
      this.ctx.fillStyle = "#000000";
      this.ctx.font = "24px Georgia";
      this.ctx.textBaseline = "middle";
      this.ctx.fillText(this.options.data[categ], 25, barIdx * barWidth + barWidth / 2); //will be covered in the loop's next iteration. Why?
      this.ctx.restore();
      barIdx++;
    }
  }
}

function init() {
  var myCanvas = document.getElementById("myCanvas");
  myCanvas.width = 800;
  myCanvas.height = 300;
  var ctx = myCanvas.getContext("2d");
  var myBarChart = new BarChart({
    canvas: myCanvas,
    seriesName: "Example Series",
    padding: 40,
    data: exampleData,
    colors: ["#D1E3F3", "#D1E3F3", "#D1E3F3", "#D1E3F3"]
  });
  myBarChart.plot();
}
document.addEventListener("DOMContentLoaded", init, false);
<canvas id="myCanvas"></canvas>

最佳答案

改变:

this.ctx.rect(30, barIdx * barWidth, barLength, barWidth);
this.ctx.fill();

改为使用fillRect()解决问题:

this.ctx.fillRect(30, barIdx * barWidth, barLength, barWidth);

Working example here (与原始示例 here 相比)

关于Javascript Canvas 绘制顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51143526/

相关文章:

javascript - 更改状态数组而不更改整个状态(REACT/REDUX)

javascript - Meteor:如何覆盖样板 HTML?

javascript - jQuery 的 val() 不适用于隐藏字段

css,点击div下的东西

javascript - HTML5 Canvas 和缩放

javascript - 为什么 jCanvas 绘制错误的像素?

javascript - JS : Sum column values and updating result on change

javascript - 如何将图像放在我使用路径绘制的梯形 html Canvas 上

android - 使用 HTML5 Canvas 和 KineticJS 在 Android Webview 上平移、缩放性能不佳

javascript - 创建包含集合中所有 Azure 团队项目的下拉列表