Странное поведение изменения размера шрифта в окне просмотра - PullRequest
0 голосов
/ 05 декабря 2018

https://jsfiddle.net/diegojsrw/od12s9b4/14/

c.font = "100vh sans-serif";
c.fillStyle = "white";
c.fillText(fps.toFixed(0), w/2, 0);

Изначально высота текста кажется хорошей.

Однако, когда я изменяю размер окна, текст не изменяется вместе.Текст постоянно рисуется на холсте (используя requestAnimationFrame).

Размер текста корректируется только тогда, когда я переключаюсь на другую вкладку, а затем переключаюсь обратно на эту вкладку.

Есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 06 декабря 2018

Вы столкнулись с ошибкой webkit.Это касается как последних версий Chrome, так и Safari.

В API Canvas2D относительные единицы / значения должны вычисляться при установке, и это вычисленное значение будет сохраняться и использоваться.

Это означает, что ваш относительный *Значение 1005 * будет вычислено до соответствующего ему значения в абсолютных единицах px.

Это одна из причин, по которой рекомендуется всегда использовать абсолютные единицы измерения из API холста (среди прочих, например, настройки в округлениях и т. Д.).).

Но если вы действительно хотите использовать это устройство, то вы должны устанавливать его каждый раз, когда он меняется, чтобы вы могли зайти вслепую, и внутри вашего цикла просто установите ctx.font снова перед вызовом fillText(),но для исполнения я бы посоветовал вам использовать dirty flag , который будет вызываться в событии resize окна, и обновлять свойство ctx.font только при поднятии этого флага.

Но это хорошо только для браузеров, которые следуют спецификациям ...

Я не имею ни малейшего понятия, когда браузеры webkit будут вычислять это значение, даже еслисброс свойства font на что-то другое не подойдет, и даже установка его на другое значение (например, переключение между 20vh и 21vh) не подойдет ...

Так что единственный способ обойти этопосмотрим сейчас, это на самом деле вычислить себе это значение.Для размера области просмотра это не так сложно (innerWidth / (100 / vw_val)), но даже для других относительных единиц вы можете фактически установить этот fontSize на холсте и вызвать getComputedStyle() на холсте.

let dirtySize = true; // this is our resize flag
const ctx = canvas.getContext('2d');
let fontStyle = ' Arial, sans-serif';

anim(0);
// the animation loop
function anim(time) {
  // call the drawing methods
  draw(Math.round(time/1e2));
  // lwoer the flags
  dirtySize = false;
  // do it again next frame
  requestAnimationFrame(anim);
}

function draw(txt) {
  // clear
  ctx.clearRect(0,0,canvas.width, canvas.height);
  // only if needed
  if(dirtySize) {
    // get the cpmputed style from our DOM element
    const fontSize = getComputedStyle(canvas).fontSize;
    // or could be 
    // const fontSize = (innerWidth / (100 / 20)) + 'px';

    ctx.font = fontSize + fontStyle;
  }
  // draw everytime
  ctx.fillText(txt, 0, 100);
}
// on window's resize event
window.addEventListener('resize',
  evt => dirtySize = true, // raise our flag
  { passive: true }
);
#canvas {
  font-size: 20vw;
}
<canvas id="canvas"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...