При использовании библиотеки Vivus основной механизм анимации
опирается на свойства SVG, такие как stroke-dasharray и
stroke-dashoffset, а также на управление кадровой
отрисовкой через requestAnimationFrame. В современных
окружениях это работает без дополнительных усилий, однако в старых
версиях браузеров возникают ограничения, требующие дополнительных слоёв
совместимости.
Ключевая проблема заключается не только в отсутствии современных API, но и в частичной поддержке SVG, нестабильной реализации DOM-методов и различиях в обработке CSS-свойств.
В браузерах уровня Internet Explorer 8 и ниже SVG либо отсутствует, либо реализован частично через альтернативные механизмы. В таких условиях невозможна корректная работа анимации обводки, поскольку:
stroke-dasharraygetTotalLengthВ IE9–IE11 поддержка SVG уже присутствует, но остаются ограничения в анимационных API и вычислениях стилей.
Механизм Vivus использует плавную покадровую анимацию. В старых
браузерах отсутствует requestAnimationFrame, что приводит
к:
setIntervalБазовый полифилл реализуется через таймеры:
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback) {
return setTimeout(function () {
callback(Date.now());
}, 16);
};
}
Для более точной эмуляции иногда добавляется отмена кадра:
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
В старых браузерах доступ к вычисленным стилям может отсутствовать или работать нестабильно. Vivus использует стили для вычисления параметров SVG-элементов.
if (!window.getComputedStyle) {
window.getComputedStyle = function (el) {
return el.currentStyle;
};
}
Различие заключается в том, что currentStyle возвращает
значения в другом формате, что требует осторожности при обработке
строковых значений.
Управление классами SVG-элементов критично для состояния анимации. В
старых браузерах отсутствует classList.
if (!('classList' in document.documentElement)) {
Object.defineProperty(Element.prototype, 'classList', {
get: function () {
var element = this;
return {
add: function (className) {
element.className += ' ' + className;
},
remove: function (className) {
element.className = element.className.replace(className, '');
}
};
}
});
}
Такой подход не полностью повторяет стандарт, но обеспечивает базовую совместимость.
Vivus активно использует обход списков путей SVG. В старых окружениях
отсутствует forEach у массивов.
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
При конфигурации экземпляра библиотеки часто требуется объединение параметров.
if (typeof Object.assign !== 'function') {
Object.assign = function (target) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
if (source != null) {
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
to[key] = source[key];
}
}
}
}
return to;
};
}
Метод getTotalLength() может возвращать некорректные
значения или быть недоступным для некоторых типов путей. В таких случаях
применяется упрощённая модель:
Это снижает точность анимации, но сохраняет визуальную целостность эффекта прорисовки.
Ключевой механизм Vivus основан на изменении:
stroke-dashoffsetstroke-dasharrayВ старых версиях IE возможны следующие ограничения:
Для компенсации используется имитация через постепенное изменение видимости элементов или разбиение пути на сегменты.
При невозможности использования нативного API применяется временной цикл:
var lastTime = 0;
function fallbackRAF(callback) {
var currTime = Date.now();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = setTimeout(function () {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
}
Такая реализация приближает поведение к 60 FPS, но не гарантирует стабильность на слабых устройствах.
Некоторые браузеры не предоставляют полноценный набор методов для работы с SVG-элементами.
if (!document.createSVGPoint) {
document.createSVGPoint = function () {
return {
x: 0,
y: 0
};
};
}
Это упрощённая заглушка, используемая только для предотвращения ошибок выполнения.
Старые версии IE используют альтернативную систему событий:
attachEvent вместо addEventListenerПереходный слой:
function addEvent(el, event, handler) {
if (el.addEventListener) {
el.addEventListener(event, handler, false);
} else if (el.attachEvent) {
el.attachEvent('on' + event, handler);
}
}
Использование полифиллов в контексте SVG-анимации приводит к дополнительным затратам:
Особенно заметно это при сложных иллюстрациях, содержащих десятки или сотни SVG-путей.
В условиях ограниченной поддержки браузера применяется каскадное снижение сложности:
Такой подход позволяет сохранять работоспособность интерфейса без полного отказа от визуализации.