На самых низких уровнях графического программирования, они используют трюк под названием двойной буферизации для обновления изображений без мерцания. Идея заключается в том, что у вас есть драйвер дисплея где-то, что вы можете сказать, чтобы рисовать изображения, хранящиеся в каком-то регионе вашей памяти.
Интуитивно понятный способ обработки графики в этом случае состоит в том, чтобы просто сделать весь ваш чертеж в этом регионе. Но с двойной буферизацией вы используете два регионов: тот, который занимает последний кадр, который вы закончили, а другой - рисовать рамку, над которой вы работаете. Закончив рисование, вы указываете драйвер дисплея в этом регионе и рисуете следующий кадр в другом регионе. Поскольку переключение назад и вперед связано только с изменением одной переменной (той, которая сообщает драйверу дисплея, какой регион рисовать), переход происходит очень быстро. И поскольку драйвер дисплея только когда-либо видит готовые изображения, нет мерцания.
У нас нет доступа к таким низкоуровневым методам в браузере, но мы можем адаптировать основную идею позади него.. Вы делаете это, загружая свое изображение где-то вне поля зрения, где пользователь не может его увидеть. Как только вы закончите, вы замените старое изображение для своего нового. Одной из возможностей для этого может быть следующим:
// Assume that the new SVG has been loaded into newSVG, like your first example.
var oldSVG = document.getElementById("svg");
oldSVG.parentNode.replaceChild(newSVG, oldSVG);
Волшебство происходит при вызове replaceChild
. Он заменяет старое изображение на новое за один шаг, так что браузер не может отображать какие-либо промежуточные шаги. Это предотвращает мерцание и потенциально экономит на производительности, поскольку браузер должен только один раз перекомпоновать (поскольку элемент был изменен) вместо двух (потому что элемент был удален, а затем, потому что элемент был добавлен).
Технически вызов replaceChild
возвращает узел, который был выгружен, так вы могли бы сделать это как однострочник, если вы готовы назвать document.getElementById
дважды для того же элемент. Но это расточительно, особенно если вы будете делать это много, поэтому мы используем переменную, чтобы избежать необходимости называть document.getElementById
чаще, чем нам нужно.
Загрузите изображение уже при вызове документа. Мигание, которое вы видите, возможно, связано с загрузкой изображения. Поэтому, если вы «загрузите» изображение до его показа, оно больше не будет мигать :) – Refilon
Как выглядит 'newSVG'? –