画布context.measureText无法正常工作

时间:2020-03-31 15:47:36

标签: javascript html canvas html5-canvas

我正在尝试为句子添加背景并在画布上绘制。

单击“动画”按钮时,第一个单词的文本背景(红色)绘制不正确。在该单词上使用console measure()时,该值要小得多。

这是设置动画和添加文本背景的功能。

const fillMixedText = (canv, ctx, args, x, y) => {
  let defaultFillStyle = "black";
  let defaultFont = "600 54px Arial";
  ctx.save();
  let i = 0;
  args.forEach(({ text, fillStyle, font }) => {


    // console.log("x",x);
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.textBaseline = "top";

    ctx.fillStyle = "red";
      console.log(x,text,ctx.measureText(text).width)
      ctx.fillRect(x, y, ctx.measureText(text).width , 70);

    // console.log(text, ctx.measureText(text).width);
    ctx.fillStyle = fillStyle || defaultFillStyle;

    ctx.font = defaultFont;
    ctx.fillText(text, x, y);
    x += ctx.measureText(text).width;
    i++;
  });
  ctx.restore();
};

这是 JSFiddle

我希望整个句子都有背景知识。

1 个答案:

答案 0 :(得分:0)

measureText将使用当前设置的font属性,并且相对于当前上下文的转换(至少是其缩放比例)。

因此,您必须将其与绘制文本时所用的实际设置一起使用,以获取正确的尺寸:

var canvas = document.getElementById("canvas-1");
var ctx = canvas.getContext("2d");

var args = [
  {text: "constantinople "},
  {text: "is "},
  {text: "a "},
  {text: "city. "}
];


document.getElementById('click').onclick = function() {
  var startTime = new Date().getTime();
  var interval = setInterval(function() {
    if (new Date().getTime() - startTime > 2000) {
      clearInterval(interval);
    }
    ctx.clearRect(0, 0, canvas.width, canvas.width);

    animateText();
  }, 33);

}

var interval;
let distance = 0;
let speed = 15;

function animateText() {
  // interval = setInterval(function() {
  distance = distance + speed;
  textAnimation(
    ctx,
    canvas,
    args, -200,
    canvas.height / 2,
    distance
  ); // console.log(thiscanvas.width/16)
}

textAnimation = (ctx, canv, args, x, y, distance) => {
  if (distance >= 280) {
    distance = 0;
    // clearInterval(interval);
    x = canv.width / 16;
  }

  fillMixedText(canv, ctx, args, x + distance, y);
};

const fillMixedText = (canv, ctx, args, x, y) => {
  let defaultFillStyle = "black";
  let defaultFont = "600 54px Arial";
  ctx.save();
  let i = 0;
  args.forEach(({ text, fillStyle, font }) => {

    // console.log("x",x);
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.textBaseline = "top";

    ctx.fillStyle = "red";
    // set the font first
    ctx.font = defaultFont;
    // now it's correct
    ctx.fillRect(x, y, ctx.measureText(text).width, 70);

    ctx.fillStyle = fillStyle || defaultFillStyle;
    ctx.fillText(text, x, y);

    x += ctx.measureText(text).width;
    i++;
  });
  ctx.restore();
};
canvas {
  border: 2px solid black;
  width: 700px;
  height: 400px;
  margin-left: 30px;
  margin-top: 10px;
}
<canvas id="canvas-1" width="1280px" height="720px"></canvas>
<button id="click">animate</button>