Pixi.js: При изменении размера холста мерцает белый фон

Созданный на 3 дек. 2016  ·  7Комментарии  ·  Источник: pixijs/pixi.js

Я изменяю размер холста с помощью простой автономной функции, например:

function resizeCanvas(width, height) {
    game.canvas.width = width;
    game.canvas.height = height;
    game.canvas.style.width = width / game.resolution + 'px';
    game.canvas.style.height = height / game.resolution + 'px';
}

А при загрузке игры делаю примерно так:

game.renderer = new PIXI.WebGLRenderer(
    game.canvas.width,
    game.canvas.height,
    {
         view: game.canvas,
         backgroundColor: 0x000000,
     }
);

// recompute viewport size & canvas size with  browser window size 
game.scaler.update();  

// resize  renderer with new size.
game.renderer.resize(game.viewportWidth, game.viewportHeight);

Тестовый пример очень прост: нарисуйте небольшое изображение в формате png.

Браузер: Chrome 55 для macOS 10.12

Safari в порядке.

Я знаю, что, возможно, это проблема Chrome, но я надеюсь, что есть способ исправить это.

Спасибо

💾 v4.x (Legacy)

Самый полезный комментарий

Оу спасибо! @mickdekkers , это ResizeObserver .

Все 7 Комментарий

Я использую такой код для исправления этой ошибки:

    game.renderer.resize(game.viewportWidth - 1, game.viewportHeight);
    setTimeout(function() {
        game.renderer.resize(game.viewportWidth, game.viewportHeight);
    }, 1);

Это так уродливо Кто мог бы дать мне лучшее предложение?

Конечно , Лучше всего сообщить об этом команде Chrome.
Кто мог это сделать? Мой английский слишком слаб, чтобы описать эту ошибку。

новый Chrome нет этой проблемы.

Я хотел бы подтвердить, что это все еще происходит на настольных Safari (последняя версия) и Edge. Pixi v4.3.0.

Изменить: в псевдокоде мы делали что-то вроде

handleWindowDimensionChange(function() {
renderer.resize(window.innerWidth, window.innerHeight)
});

Изменение размера окна вызывает некрасивое мерцание в обоих упомянутых браузерах. Не хром и не Firefox.

Кто-нибудь знает, что потенциально может вызвать мерцание при изменении размера? У меня такая же проблема в Electron (проверено с разными версиями, но в основном Chromium 56, 58 и 59) и Pixi 4.5.5 (проверено на Linux и macOS), но только в странном сценарии:

Я изменяю размер средства визуализации (webgl) на основе элемента контейнера в DOM: элемент контейнера может изменять размер, если размер окна изменяется или запускается виджетом с изменяемым размером, реализованным в Javascript. Теперь, если я изменю размер средства визуализации в resize окна и пользовательском обработчике resize виджета (на основе событий mousemove ), все будет в порядке , но если я использую новый ResizeObserver API на элементе контейнера вместо этого у меня очень плохо мерцает.

Пара наблюдений:

  • Мерцание вызвано очисткой всего холста (как упоминается в OP, в моем случае он не белый, а прозрачный): это хорошо видно, когда я делаю запись производительности со снимками экрана в инструментах разработчика: холст пуст примерно на 100 мс при изменении размера.
  • Я предположил, что это проблема производительности / времени, потому что ResizeObserver срабатывает чаще, но это не так: я получаю сопоставимую частоту в обоих сценариях.
  • Более того, я регулирую само изменение размера, поэтому частота фактического вызова renderer.resize в обоих случаях идентична; кроме того, вызов не происходит ни в одном из обработчиков событий, а задерживается, поэтому мне кажется маловероятным, что виноват выбор времени.
  • Мое следующее предположение заключалось в том, что значения, сообщаемые ResizeObserver , отличаются; он сообщает о блоке содержимого контейнера, а не о ограничивающей рамке, но, поскольку нет никаких границ или отступов, значения те же самые. Кроме того, в обоих сценариях я округляю размеры до полных пикселей. На самом деле, и устанавливаемые размеры, и частота в обоих случаях очень похожи.
  • Мерцание прекращается, если я увеличиваю время ожидания дроссельной заслонки примерно до 500 мс или выше.
  • Используя обработчики событий окна / виджета, мне нужно измерить контейнер с помощью getBoundingClientRect() - чтобы сохранить этот вызов (вызывающий перерисовку), на самом деле большая причина для использования ResizeObserver но я решил, что отсутствие дополнительной перерисовки может по какой-то причине вызывать мерцание. Поэтому я добавил ненужный вызов getBoundingClientRect() перед изменением размера, но безрезультатно.

Меня это не слишком беспокоит, потому что существует жизнеспособный обходной путь (с использованием двух отдельных обработчиков вместо ResizeObserver ), но мне бы очень хотелось знать, что вызывает это. Я также отключил autoResize и antialias но это не имело значения. Есть идеи, что еще я мог бы попробовать?

@inukshuk в моем случае решение оказалось действительно простым: просто вызовите render после изменения размера.

app.renderer.resize(width, height)
// Immediately render because resizing clears the canvas
app.render()

Это устранило для меня проблему с мерцанием. Имейте в виду, что если у вас запущена анимация, она будет отображать только последний кадр до следующего цикла обновления, и это может дать эффект «замораживания». Если вы хотите, чтобы он работал бесперебойно, вы захотите вызвать функцию обновления перед вызовом рендеринга.

Оу спасибо! @mickdekkers , это ResizeObserver .

Этот поток был автоматически заблокирован, поскольку после его закрытия в последнее время не было никаких действий. Пожалуйста, откройте новую проблему для связанных ошибок.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги