Перезапустить фоновый SVG-анимацию

У меня есть SVG-набор как фоновое изображение элемента. При первом отображении элемента анимация воспроизводится правильно.

На последующих дисплеях (например, если дубликат элемента вводится с помощью JavaScript или если фоновое изображение удаляется и добавляется обратно с помощью CSS/JavaScript), анимация начинается не с самого начала. Я думаю, что это предполагаемая функциональность, поскольку изображение не считается перезагруженным браузером - оно использует версию с уже существующей памятью.

Вот демо этого (не мое): http://www.luigifab.info/public/svg-smil/test.html

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

Есть ли способ получить мою анимацию SVG до reset/replay всякий раз, когда отображается изображение?

Я в идеале ищу решение, используя только CSS и SVG - иначе это решение с JavaScript, если это невозможно.

Ответ 1

Я думаю, что ваше предположение "... поскольку изображение не считается перезагруженным браузером - оно использует версию памяти, которая уже анимируется", является правильной, поскольку файл SVG кэшируется! Таким образом, без (реальной) "перезагрузки" анимация не запускается (снова).

Хорошо, во-первых, давайте посмотрим на анимацию SVG. Есть два атрибута, которые вы можете использовать внутри элемента анимации, которые используются для повторения анимации - см. Повторяющиеся анимации и Анимированный элемент. В вашем случае анимация запускается только один раз (без повторения).

Итак, вам нужно, чтобы Javascript каким-то образом "запускал" анимацию.
Это возможно в принципе (например: Advanced SVG Animation Techniques), но только если SVG файл является частью DOM, к которому вы можете получить доступ через Javascript. Поэтому вам нужно включить SVG файл в качестве <object>.

Как только вы используете SVG файл в теге <img> или как CSS background-image, у вас нет доступа к файлу script.

Таким образом, единственный способ, который я мог бы придумать для достижения вашей цели, - это не позволять браузеру кэшировать SVG файл (см. Как (и как не) управлять Cache) или использовать SVG файл в элементе <object>, чтобы вы могли управлять анимацией через Javascript.

Кстати: ответ luigifab не так уж плох. Это часто используемый "трюк" для принудительной перезагрузки файла/изображения - см. The Cache Trick

Ответ 2

Возможность изменить URL-адрес изображения, чтобы перезагрузить браузер.

Ответ 3

Как сказал @netsurfer, я решил эту проблему, используя object. Вот пример:

<object type="image/svg+xml" data="my.svg"></object>

Каждый раз, когда я динамически вставляю SVG object, анимация начинается с начала.

Ответ 4

Реализация для ответа luigifab. поместите некоторые random things в конце параметра url, это заставит браузер думать, что ресурс является "новым ресурсом". Демо

Ответ 5

Используйте случайный ключ в URL-адресе для перебора кеша. Хотя ваш пример не имеет длинной анимации, чтобы правильно протестировать его, я добавил повторение загрузки изображения, чтобы сделать разницу заметной.

url + "&" + Math.random()

Не загружать демо с постоянным URL: http://jsfiddle.net/4ZBLr/8/

Перезагрузить демо со случайным URL-адресом src: http://jsfiddle.net/4ZBLr/9/

Ответ 6

Я думаю, что во многих сценариях setCurrentTime(0) - лучшее решение - если поддерживается браузером. Вот пример (предположим, что вы используете тег <object> для встраивания, конечно):

let content = document.getElementById("object-id").contentDocument;
let svg = content.getElementsByTagName("svg")[0];
if(svg.getCurrentTime() > 10)
  svg.setCurrentTime(0);

Более подробную информацию о соответствующем API можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/API/SVGSVGElement