Изменение размера окна на CodePen приводит к появлению полосы прокрутки на полноэкранном холсте - PullRequest
0 голосов
/ 06 августа

У меня странная проблема, раньше она работала, проблема на CodePen. У меня полноразмерный холст:

function width() {
  // why -1 ?
  // without this there is horizontal scrollbar
  // I have no idea what is causing this
  return window.innerWidth - 1;
}

// ---------------------------------------------------------------
function height() {
  return window.innerHeight;
}

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = width();
canvas.height = height();

Я не уверен, что вызывает это, но, как вы видите, я добавил -1 к ширине, иначе есть горизонтальная полоса прокрутки. Я думаю, что это работало раньше, это происходило на GNU / Linux Chrome.

На холсте есть display: block, вы можете увидеть код в этой Демо-версии Matrix Rain , это отлично работает в режиме отладки.

Это что-то с CodePen, кто-нибудь знает, почему это 1px.

Это отлично работает в StackSnippets:

function width() {
  return window.innerWidth;
}

// ---------------------------------------------------------------
function height() {
  return window.innerHeight;
}

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = width();
canvas.height = height();
canvas {
  display: block;
}
body {
  margin: 0;
}
<canvas></canvas>

РЕДАКТИРОВАТЬ:

Проблема появляется только в некоторых окнах. Чтобы увидеть, нужно медленно менять размер. Для моего (у меня ноутбук FullHD) он отображается, например, по адресу: 1594, но работает с 1595. Если я использую -1, полоса прокрутки никогда не появляется без него, она мерцает, она отображается с некоторой шириной.

Чтобы быть точным о браузере и ОС У меня есть Fedora 32 с Google Chrome стабильная (только что обновленная до 84.0.4147.105 (Official version) (64-bit))

EDIT2:

Моя демонстрация работает в Stack Snippet no нужно исправить мою демонстрацию:

var katagana = gen_unicode(0x30A1, 0x30F6);
var hiragana = gen_unicode(0x3041, 0x3096);

// ---------------------------------------------------------------
class Matrix {
  constructor(canvas, { font_size = 14, width, height } = {}) {
    this._canvas = canvas;
    this._ctx = canvas.getContext('2d');
    this._font_size = font_size;
    this._drops = [];
    this._columns = Math.floor(width / font_size);
    this._chars = katagana.concat(hiragana);
    this.resize(width, height);
  }
  random_char() {
    return rnd(this._chars);
  }
  render_char(char, x, y) {
    this._ctx.fillText(char, x, y);
  }
  start() {
    let frames = 0;
    this._run = true;
    const self = this;
    (function loop() {
      if (frames++ % 2 === 0) {
        self.render(); // slower render
      }
      if (self._run) {
        requestAnimationFrame(loop);
      }
    })()
  }
  stop() {
    this._run = false;
  }
  reset() {
    for (let x = 0; x < this._columns; x++) {
      this._drops[x] = 255;
    }
  }
  resize(width, height) {
    this._width = width;
    this._height = height;
    this._canvas.height = height;
    this._canvas.width = width;
    this.reset();
  }
  clear() {
    this._ctx.fillStyle = 'rgba(0, 0,0,0.05)';
    this._ctx.fillRect(0, 0, this._width, this._height);
    this._ctx.fillStyle = '#0F0';
    this._ctx.font = this._font_size + "px monospace";
  }
  render() {
    this.clear();
    for (let col = 0; col < this._drops.length; col++) {
      const char = this.random_char();
      const x = col * this._font_size;
      const y = this._drops[col] * this._font_size;
      this.render_char(char, x, y);
      if (y > this._height && Math.random() > .975) {
        this._drops[col] = 0;
      }
      this._drops[col]++;
    }
  }
}

// ---------------------------------------------------------------
// :: Init code
// ---------------------------------------------------------------
var canvas = document.getElementsByTagName('canvas')[0];

const matrix = new Matrix(canvas, {
  font_size: 14,
  width: width(),
  height: height()
});

matrix.start();

window.addEventListener('resize', e => {
  matrix.resize(width(), height());
});

// ---------------------------------------------------------------
// :: Utils
// ---------------------------------------------------------------
function gen_unicode(start, end) {
  var chars = [];
  for (var i = start; i <= end; ++i) {
    chars.push(String.fromCharCode(i));
  }
  return chars;
}

// ---------------------------------------------------------------
function rnd(array) {
  return array[Math.floor(Math.random() * array.length)]
}

// ---------------------------------------------------------------
function width() {
  // why -1 ?
  // without this there is horizontal scrollbar
  // I have no idea what is causing this
  return window.innerWidth;
}

// ---------------------------------------------------------------
function height() {
  return window.innerHeight;
}
body {
  background: black;
  margin: 0;
  min-width: 100vw;
  min-height: 100vh;
}
canvas {
  display: block;
  margin: 0;
}
<canvas></canvas>

РЕДАКТИРОВАТЬ: 1 пиксель не был исправлением, которое произошло с ним или без него.

Ответы [ 2 ]

0 голосов
/ 07 августа

Нашел эту старую статью Криса Койера в блоге CodePen Полноэкранный холст

Это решение было:

function resizeCanvas() {
  can.style.width = window.innerWidth + "px";
  setTimeout(function() {
    can.style.height = window.innerHeight + "px";
  }, 0);
}

Это то же самое, что:

function resizeCanvas() {
  canvas.width = window.innerWidth;
  setTimeout(function() {
    canvas.height = window.innerHeight;
  }, 0);
}

, и решением было также скрыть полосу прокрутки, используя:

body {
  margin: 0;
  overflow: hidden;
}
0 голосов
/ 07 августа

Это, вероятно, не решит вашу проблему, но есть другая идея, чтобы не обновлять sh холст при изменении размера. Вы просто используете атрибут большой ширины / высоты и учитываете object-fit, чтобы избежать искажения (связано: Как объектное соответствие работает с элементом холста? )

var katagana = gen_unicode(0x30A1, 0x30F6);
var hiragana = gen_unicode(0x3041, 0x3096);

// ---------------------------------------------------------------
class Matrix {
  constructor(canvas, { font_size = 14} = {}) {
    this._canvas = canvas;
    this._ctx = canvas.getContext('2d');
    this._font_size = font_size;
    this._drops = [];
    this._columns = Math.floor(2000 / font_size);
    this._chars = katagana.concat(hiragana);
    this._width = 2000;
    this._height = 2000;
    this.reset();
  }
  random_char() {
    return rnd(this._chars);
  }
  render_char(char, x, y) {
    this._ctx.fillText(char, x, y);
  }
  start() {
    let frames = 0;
    this._run = true;
    const self = this;
    (function loop() {
      if (frames++ % 2 === 0) {
        self.render(); // slower render
      }
      if (self._run) {
        requestAnimationFrame(loop);
      }
    })()
  }
  stop() {
    this._run = false;
  }
  reset() {
    for (let x = 0; x < this._columns; x++) {
      this._drops[x] = 255;
    }
  }
  clear() {
    this._ctx.fillStyle = 'rgba(0, 0,0,0.05)';
    this._ctx.fillRect(0, 0, this._width, this._height);
    this._ctx.fillStyle = '#0F0';
    this._ctx.font = this._font_size + "px monospace";
  }
  render() {
    this.clear();
    for (let col = 0; col < this._drops.length; col++) {
      const char = this.random_char();
      const x = col * this._font_size;
      const y = this._drops[col] * this._font_size;
      this.render_char(char, x, y);
      if (y > this._height && Math.random() > .975) {
        this._drops[col] = 0;
      }
      this._drops[col]++;
    }
  }
}

// ---------------------------------------------------------------
// :: Init code
// ---------------------------------------------------------------
var canvas = document.getElementsByTagName('canvas')[0];

const matrix = new Matrix(canvas, {
  font_size: 14
});

matrix.start();

// ---------------------------------------------------------------
// :: Utils
// ---------------------------------------------------------------
function gen_unicode(start, end) {
  var chars = [];
  for (var i = start; i <= end; ++i) {
    chars.push(String.fromCharCode(i));
  }
  return chars;
}

// ---------------------------------------------------------------
function rnd(array) {
  return array[Math.floor(Math.random() * array.length)]
}
body {
  background: black;
  margin: 0;
  height:100vh;
}
canvas {
  width:100%;
  height:100%;
  display:block;
  object-fit:none;
  object-position:top left;
}
<canvas width="2000" height="2000"></canvas>
...