HTML canvas measureText()。宽度太大

时间:2016-04-22 16:24:27

标签: javascript html css canvas

我试着找出html画布中文本的宽度。 我正在使用measureText方法,但它给了我一个超过预期的两倍的值。我使用toSting方法生成Text。如果我只是硬编码从toSting到measureText的返回它工作正常......

console.log("--->width "+this.ctx.measureText("-100").width);

返回22

console.log(labels[i]);

返回“-100”

console.log("->width "+this.ctx.measureText(labels[i]).width);

返回48

任何想法为什么?

感谢您的帮助!

以下是整个代码:https://jsfiddle.net/falkinator/Lze1rnm5/4/

function createGraph(){
  this.canvas = document.getElementById("graph");
  this.ctx = this.canvas.getContext("2d");
  this.options={};
  this.datasets=[];
  this.options.fontSize=11;
  this.ctx.font=this.options.fontSize+"px Arial";
  this.ctx.textAlign="left";
  this.ctx.textBaseline="middle";
  this.datasetLength=500;
  this.dataset=function(options){
    /*this.strokeColor=options.strokeColor;
        this.signalName=options.signalName;
        this.signalMin=options.signalMin;
        this.signalMax=options.signalMax;
        this.signalUnit=options.signalUnit;*/
    this.data=[];
    this.min;
    this.max;
  };
  this.buildYLabels = function(scaleMin, scaleMax){
    var labels = [];
    var maxLabelWidth=0;
    console.log("--->width "+this.ctx.measureText("-100").width);
    for(i=10;i>=0;i--){
      labels.push((scaleMin+((scaleMax-scaleMin)/10)*i).toString());
      console.log((scaleMin+((scaleMax-scaleMin)/10)*i).toString());
      console.log("->width "+this.ctx.measureText(labels[i]).width);
      if(maxLabelWidth<this.ctx.measureText(labels[i]).width){
        maxLabelWidth=this.ctx.measureText(labels[i]).width;
      }
    }
    return {labels: labels,
            maxLabelWidth: maxLabelWidth};
  };
  this.buildXLabels = function(x){

  };
  this.draw = function (){
    var _this=this;
    each(this.datasets,function(dataset, index){
      //plot data
      if(index>0)return;
      //draw scale
      var canvasHeight = _this.canvas.height;
      console.log("canvas height="+canvasHeight);
      var yLabels = _this.buildYLabels(-100, 500);
      var currX = _this.options.fontSize/2;
      var scaleHeight = canvasHeight-_this.options.fontSize*1.5;
      var maxLabelWidth=yLabels.maxLabelWidth;
      console.log(yLabels.maxLabelWidth);
      each(yLabels.labels,function(label, index){
        _this.ctx.fillText(label,0,currX);
        console.log(label);
        currX+=(scaleHeight/10);
      });
      _this.ctx.beginPath();
      _this.ctx.moveTo(maxLabelWidth,0);
      _this.ctx.lineTo(maxLabelWidth,canvasHeight);
      _this.ctx.stroke();
    });
  };
  this.addSignal = function(){
    var dataset = new this.dataset({});
    this.datasets.push(dataset);
  };
  this.pushData = function(data){
    var _this=this;
    if(data.length!=this.datasets.length){
      console.error("the number of pushed data is diffrent to the number of datasets!");
      return;
    }
    each(data,function(data, index){
      _this.datasets[index].data.push(data);
      if(_this.datasets[index].data.length>_this.datasetLength){
        _this.datasets[index].data.shift();
      }
    });
  };
  this.calculateScaling = function(dataset){
    var range = dataset.max - dataset.min;
    var decStep = Math.pow(10,Math.floor(Math.log10(range)));
    var scaleMin = roundTo(dataset.min/*+(decStep*10)/2*/, decStep);
    var scaleMax = roundTo(dataset.max/*+(decStep*10)/2*/, decStep);
    var scaleStep = (scaleMax - scaleMin)/10;
  };
  var minx=-34, maxx=424;
  var range = maxx - minx;
  var decStep = Math.pow(10, Math.floor(Math.log10(range)));
  var scaleMin = roundTo(minx-(decStep/2), decStep);
  var scaleMax = roundTo(maxx+(decStep/2), decStep);
  var scaleStep = (scaleMax - scaleMin)/10;
  console.log(this.buildYLabels(scaleMin,scaleMax));
  console.log("range="+range);
  console.log("log="+Math.floor(Math.log10(range)));
  console.log("scaleStep="+scaleStep);
  console.log("decStep="+decStep);
  console.log("scaleMin="+scaleMin);
  console.log("scaleMax="+scaleMax);
}
graph = new createGraph();
graph.addSignal();
graph.addSignal();
graph.addSignal();

graph.pushData([1,2,3]);
graph.pushData([1,2,3]);
graph.draw();
function each(array, callback){
  console.log(callback);
  for(i in array){
    callback(array[i], i);
  }
}
function roundTo(num, to){
  return Math.round(num/to)*to;
}
<canvas id="graph"></canvas>

1 个答案:

答案 0 :(得分:1)

在生成标签的代码中,循环索引i从10变为0.每次循环时你都要将新标签推送到数组(即标签[0],标签[1],.. 。)但是你试图使用循环索引i(即标签[10],标签[9],...)来测量标签。因此,前几个测量的文本是“未定义的”。

更改...

console.log("->width "+this.ctx.measureText(labels[i]).width);
if(maxLabelWidth<this.ctx.measureText(labels[i]).width){
    maxLabelWidth=this.ctx.measureText(labels[i]).width;

为...

console.log("->width "+this.ctx.measureText(labels[labels.length-1]).width);
if(maxLabelWidth<this.ctx.measureText(labels[labels.length-1]).width){
    maxLabelWidth=this.ctx.measureText(labels[labels.length-1]).width;