Velocity.js предоставляет механизм регистрации пользовательских свойств, позволяющий расширять стандартный набор анимируемых параметров. Это особенно важно при работе с нестандартными CSS-свойствами, трансформациями, SVG-атрибутами или при необходимости оптимизации вычислений.
Регистрация свойств осуществляется через внутреннюю систему hooks и Normalizations, которая управляет преобразованием значений между различными форматами.
Система обработки свойств в Velocity.js включает несколько уровней:
transform)Регистрация пользовательского свойства предполагает добавление нового правила нормализации, которое определяет:
Хотя основная цель — эффекты, через них можно внедрять пользовательские свойства:
Velocity.RegisterEffect("custom.fadeAndScale", {
defaultDuration: 500,
calls: [
[{ opacity: 1, scale: 1 }, 1]
]
});
Однако этот подход не добавляет новое свойство напрямую, а лишь комбинирует существующие.
Для работы с составными свойствами используется API hooks:
Velocity.CSS.Hooks.register("clipTop", "clip", 0);
Здесь:
clipTop — новое пользовательское свойствоclip — базовое CSS-свойство0 — индекс значения внутри составного свойстваПример использования:
Velocity(element, { clipTop: "10px" });
Наиболее гибкий способ — использование механизма Normalizations:
Velocity.CSS.Normalizations.register({
name: "customProperty",
// Чтение текущего значения
get: function(element) {
return element.dataset.custom || 0;
},
// Установка значения
set: function(element, value) {
element.dataset.custom = value;
},
// Интерполяция (необязательно)
interpolate: function(start, end, percent) {
return start + (end - start) * percent;
}
});
После регистрации:
Velocity(element, { customProperty: 100 });
Velocity автоматически обрабатывает единицы (px,
%, em), но при создании пользовательских
свойств важно явно учитывать формат:
get: function(element) {
return parseFloat(element.style.getPropertyValue("--my-var")) || 0;
},
set: function(element, value) {
element.style.setProperty("--my-var", value + "px");
}
Пользовательские свойства могут представлять не только числа, но и структуры:
Velocity.CSS.Normalizations.register({
name: "rgbColor",
get: function(element) {
return [255, 0, 0];
},
set: function(element, value) {
element.style.backgroundColor = `rgb(${value.join(",")})`;
},
interpolate: function(start, end, percent) {
return start.map((s, i) => Math.round(s + (end[i] - s) * percent));
}
});
Transform-свойства уже разбиты на hooks (translateX,
scale, rotate), но можно добавить
собственные:
Velocity.CSS.Hooks.register("skewZ", "transform", 5);
Важно учитывать порядок трансформаций — он влияет на итоговый результат.
При регистрации пользовательских свойств следует учитывать:
setinterpolateНежелательно:
set: function(element, value) {
element.offsetHeight; // форсирует reflow
element.style.left = value + "px";
}
Если значение свойства отсутствует, важно задать fallback:
get: function(element) {
return element._customValue || 0;
}
Или:
get: function(element) {
return parseFloat(getComputedStyle(element).width) || 0;
}
Velocity использует собственный цикл анимации, но пользовательские свойства должны быть:
Для диагностики:
get и setПример:
set: function(element, value) {
console.log("Setting value:", value);
element.style.opacity = value;
}
Velocity поддерживает SVG, но пользовательские свойства позволяют управлять атрибутами:
Velocity.CSS.Normalizations.register({
name: "svgX",
get: function(element) {
return element.getAttribute("x") || 0;
},
set: function(element, value) {
element.setAttribute("x", value);
}
});
Velocity.CSS.Normalizations.register({
name: "progressValue",
get: function(element) {
return element._progress || 0;
},
set: function(element, value) {
element._progress = value;
element.style.width = value + "%";
}
});
Использование:
Velocity(progressBar, { progressValue: 100 }, { duration: 1000 });
Пользовательские свойства автоматически поддерживают easing-функции:
Velocity(element, {
customProperty: 200
}, {
easing: "easeInOutQuad"
});
Интерполяция будет учитывать выбранную функцию сглаживания.
Регистрация свойств может быть вынесена в отдельные модули:
export function registerCustomProps(Velocity) {
Velocity.CSS.Normalizations.register({
name: "customScale",
get: () => 1,
set: (el, val) => el.style.transform = `scale(${val})`
});
}
Это позволяет создавать библиотеки расширений для Velocity.
Современный подход — использование CSS Variables:
Velocity.CSS.Normalizations.register({
name: "cssVarX",
get: function(element) {
return getComputedStyle(element).getPropertyValue("--x") || 0;
},
set: function(element, value) {
element.style.setProperty("--x", value);
}
});
Пользовательские свойства могут хранить состояние:
set: function(element, value) {
if (!element._history) element._history = [];
element._history.push(value);
}
Это открывает возможности для сложных анимационных сценариев.
Регистрация пользовательских свойств превращает Velocity.js из простой библиотеки анимации в мощный инструмент: