При создании веб-сайтов разработчики сталкиваются с выбором между использованием CSS анимаций и JavaScript для создания динамических и интерактивных элементов. В этой статье мы рассмотрим основные мифы о CSS анимациях и JavaScript, чтобы помочь разработчикам сделать информированный выбор при создании веб-интерфейсов.
CSS анимации
CSS анимации предоставляют простой и эффективный способ добавления анимированных переходов и визуальных эффектов на веб-сайт. Вот некоторые ключевые моменты, которые стоит учитывать⁚
Простота использования
CSS анимации легко создавать и поддерживать. Они позволяют определить анимацию с помощью набора простых правил CSS, что делает процесс создания анимаций более доступным для начинающих разработчиков.
Производительность
CSS анимации могут быть более производительными, поскольку браузеры могут оптимизировать их выполнение. Они также могут использовать аппаратное ускорение для улучшения производительности анимаций.
Ограничения
Однако CSS анимации имеют определенные ограничения в сравнении с JavaScript. Например, сложные сценарии анимации, динамические эффекты и управление анимацией в зависимости от пользовательского взаимодействия могут быть более сложными для реализации с помощью CSS анимаций.
JavaScript анимации
JavaScript предоставляет более широкие возможности для создания сложных и интерактивных анимаций на веб-сайтах. Вот некоторые ключевые моменты, которые стоит учитывать⁚
Гибкость
JavaScript анимации предлагают более широкий спектр возможностей для создания сложных анимаций с динамическими эффектами. Они позволяют более тонкую настройку взаимодействия анимаций с пользовательским интерфейсом.
Управление
С помощью JavaScript можно легко управлять анимациями в зависимости от пользовательского взаимодействия, что делает их более гибкими и адаптивными к различным сценариям использования.
Производительность
Однако при использовании сложных JavaScript анимаций следует обратить внимание на производительность, поскольку неправильное использование JavaScript может привести к ухудшению производительности веб-сайта.
Расхождение мифов
Миф 1⁚ CSS анимации всегда производительнее٫ чем JavaScript анимации.
Расхождение⁚ В зависимости от конкретной задачи и контекста использования, как CSS, так и JavaScript анимации могут быть производительными, если правильно применены.
Миф 2⁚ JavaScript анимации всегда предпочтительнее из-за своей гибкости.
Расхождение⁚ Для простых анимаций и переходов использование CSS может быть более простым и эффективным способом.
В зависимости от конкретных потребностей проекта разработчикам следует выбирать между CSS анимациями и JavaScript в соответствии с требуемыми эффектами, производительностью и уровнем управления. Комбинирование CSS анимаций и JavaScript может оказаться наилучшим решением для создания баланса между производительностью и функциональностью веб-интерфейсов.
Теперь, основываясь на мифах и расхождениях, вам будет проще принимать информированные решения при выборе между CSS анимациями и JavaScript в своих веб-проектах.
var $ start = $ (& quot; # start & quot;), $ dotQtyInput = $ ("# dotQuantity"), $ engineInput = $ ("# двигатель"), $ propertiesInput = $ ("# свойств"), $ инструкций = $ (& quot; # инструкций & quot;), $ field = $ (& quot; # поле & quot;), $ window = $ (окно), $ input = $ (& quot; выбрать & quot;), inProgress = false, tests = {}, длительность, радиус, centerX, centerY, точки, rawDots, currentTest, startCSS;
/**
* Цель этого теста — сравнить, как разные инструменты создания анимации работают под нагрузкой, получая относительно общие задачи анимации и выполняя их в большом количестве, чтобы увидеть чистую производительность. Цель состоит не в том, чтобы найти наиболее эффективный способ перемещения точек по схеме звездного поля.
*
* Один и тот же код используется для всего, кроме самих анимаций. Каждый тест в объекте «test» имеет 4 свойства:
*
* — миллисекунды [логическое] — истина, если продолжительность должна быть указана в миллисекундах
*
* — wrapDot [функция] — когда каждый & lt; img & gt; точка создается, ее необходимо передать методу wrapDot (), а то, что возвращает функция, сохраняется в массиве точек для анимации. Это полезно для повышения производительности таких вещей, как jQuery, потому что вместо передачи элемента DOM методу tween () (который потребовал бы, чтобы jQuery запрашивал DOM и заключал элемент в объект, специфичный для движка, перед вызовом animate ()) , можно использовать природный объект. Проще говоря, это позволит кэшировать перенос точек для повышения производительности.
*
* — tween [функция] является ядром всего теста. tween () вызывается для каждой точки, точка передается как параметр. Функция tween () должна установить cssText точки на начальное значение CSS (которое просто помещает точку в центр экрана и устанавливает значение для ее ширины и высоты на 1 пиксель), а затем после произвольной задержки 0 для продолжительность анимации, функция должна анимировать точку под произвольным углом, изменяя значения left/top или translate (), и устанавливать ее размер на 32 пикселя в ширину и в высоту, используя width/height или scale (). Затем, после завершения анимации, метод tween () должен быть вызван снова для той же точки. Таким образом, одна и та же точка будет продолжать удаляться от центра под случайным углом и с произвольно выбранным временем задержки.
*
* — stop [функция] — эта функция вызывается, когда пользователь останавливает тест. Точка передается как параметр. Функция должна немедленно остановить/уничтожить анимацию (или анимацию), запущенную для этой точки (или для всех точек — это тоже нормально).
*
* — nativeSize [Boolean] — установите значение true, если начальная ширина/высота изображения должна быть в его собственном размере (обычно требуется для преобразований, но не при анимации ширины/высоты).
*
* Я не претендую на звание эксперта по различным движкам анимации, поэтому, если есть способы оптимизации, которые вы можете применить для повышения производительности тестирования, дайте мне знать. Я постарался сделать это максимально беспристрастным.
**/
//стандартный jQuery нормальный (вверху/слева/ширина/высота)
tests.jquery_normal = {
миллисекунды: истина,
wrapDot: function (точка) {
вернуть jQuery (точка);//оборачиваем точку в объект jQuery для повышения производительности (таким образом нам не нужно запрашивать DOM каждый раз при анимации — мы можем просто вызвать animate () непосредственно для объекта jQuery)
},
tween: function (точка) {
var angle = Math.random () * Math.PI * 2;
точка [0] .style.cssText = startCSS;
dot.delay (Math.random () * duration) .animate ({left: Math.cos (угол) * радиус + centerX,
вверху: Math.sin (угол) * радиус + centerY,
ширина: 32,
height: 32}, duration, «cubicIn», function () {tests.jquery_normal.tween (точка)})
},
stop: function (period) {
для остановки (истина);
},
nativeSize: false
};
//стандартный GSAP (вверху/слева/ширина/высота)
tests.gsap_normal = {
миллисекунды: ложь,
wrapDot: функция (точка){
точка возврата;//не нужно переносить
},
tween: function (точка) {
var angle = Math.random () * Math.PI * 2;
dot.style.cssText = startCSS;
TweenLite.to (точка, продолжительность, {css: {left: Math.cos (угол) * радиус + centerX,
вверху: Math.sin (угол) * радиус + centerY,
ширина: 32,
высота: 32},
задержка: Math.random () * продолжительность,
легкость: Cubic.easeIn,
перезапись: & quot; отсутствует & quot;,
onComplete: tests.gsap_normal.tween,
onCompleteParams: [точка]});
},
stop: function (period) {
TweenLite.killTweensOf (точка);
},
nativeSize: false
};
//преобразования GSAP (translate ()/scale ())
tests.gsap_transforms = {
миллисекунды: ложь,
wrapDot: function (точка) {
точка возврата;//не нужно переносить
},
tween: function (точка) {
var angle = Math.random () * Math.PI * 2;
TweenLite.set (точка, {css: {x: 0, y: 0, масштаб: 0,06}, перезапись: «нет»});
TweenLite.to (точка, продолжительность, {css: {x: (Math.cos (угол) * радиус),
y: (Math.sin (угол) * радиус),
масштаб X: 2,
scaleY: 2},
задержка: Math.random () * продолжительность,
легкость: Cubic.easeIn,
перезапись: & quot; отсутствует & quot;,
onComplete: tests.gsap_transforms.tween,
onCompleteParams: [точка]});
},
stop: function (period) {
TweenLite.killTweensOf (точка);
},
nativeSize: true
};
//стандартный Zepto (сверху/слева/ширина/высота)
tests.zepto_normal = {
миллисекунды: истина,
wrapDot: function (точка) {
вернуть Zepto (точка);//wrapDot в jQuery для повышения производительности (таким образом нам не нужно опрашивать DOM каждый раз при анимации — мы можем просто вызвать animate () непосредственно в jQuery)
},
tween: function (точка) {
var angle = Math.random () * Math.PI * 2;
точка [0] .style.cssText = startCSS;
//Функция задержки давления в Zepto работает ПЛОХО, поэтому вместо этого мы используем setTimeout () для повышения производительности.
setTimeout (function () {
if (! dot.isKilled) {//Zepto не имеет функции, которая позволяет нам убивать запущенную анимацию, поэтому мы просто устанавливаем для нашего собственного свойства isKilled значение true, когда анимация собирается остановиться, а затем останавливаем рекурсию, давая нам эффект, который мы хотим.
dot.animate ({слева: Math.cos (угол) * радиус + centerX,
вверху: Math.sin (угол) * радиус + centerY,
ширина: 32,
высота: 32}, продолжительность, «кубический безье (0,550, 0,055, 0,675, 0,190)», функция () {tests.zepto_normal.tween (точка)});
}
}, продолжительность * Math.random ());
},
stop: function (period) {
isKilled = true;
},
nativeSize: false
};
//Zepto преобразует (translate ()/scale ())
tests.zepto_transforms = {
миллисекунды: истина,
wrapDot: function (точка) {
вернуть Zepto (точка);//wrapDot в jQuery для повышения производительности (таким образом нам не нужно опрашивать DOM каждый раз при анимации — мы можем просто вызвать animate () непосредственно в jQuery)
},
tween: function (точка) {
//Не удалось установить функцию css () в Zepto (сбой), поэтому пришлось использовать вызов animate () с нулевой продолжительностью. Хорошо, потому что в TweenLite мы также делаем анимацию с нулевой продолжительностью.
aboutanimate ({translateX: «0px», translateY: «0px», rotateY: «0rad», rotateX: «0rad», scale: «0,06, 0,06 & quot;}, 0);
//Функция задержки под давлением Zepto работает ПОЛНОСТЬЮ, поэтому вместо этого мы используем setTimeout () для повышения производительности.
setTimeout (function () {
if (! dot.isKilled) {//Zepto не имеет функции, которая позволяет нам убивать запущенную анимацию, поэтому мы просто устанавливаем для нашего собственного свойства isKilled значение true, когда анимация собирается остановиться, а затем останавливаем рекурсию, давая нам эффект, который мы хотим.
var angle = Math.random () * Math.PI * 2;
dot.animate ({translateX: (Math.cos (угол) * радиус) + & quot; px & quot;,
translateY: (Math.sin (угол) * радиус) + & quot; px & quot;,
Масштаб: «2,2»
delay: duration * Math.random ()}, duration, «кубическая шкала Безье (0,550, 0,055, 0,675, 0,190)», function () {tests.zepto_transforms.tween (точка); });
}
}, продолжительность * Math.random ());
},
stop: function (period) {
isKilled = true;
},
nativeSize: true
};
function toggleTest () {
var i, size;inProgress =!
if (inProgress) {
$ inputs.prop («отключено», истина);
$ field.css ({pointerEvents: & quot; none & quot;});//улучшение производительности — игнорировать события указателя во время анимации
$ start.html («СТОП»);
$ start.css ({фон: & quot; # C00 & quot;});
TweenLite.to ($ instructions, 0.7, {autoAlpha: 0, overwrite: & quot; all & quot;});
currentTest = тесты [$ engineInput.val () + & quot; _ & quot; + $ propertiesInput.val ()];
size = (currentTest.nativeSize? «16px «:» 1px «);
centerX = $ field.width ()/2;
centerY = $ field.height ()/2;
startCSS = & quot; позиция: абсолютная; слева: & quot; + centerX + & quot; px; вверху: & quot; + centerY + & quot; px; ширина: & quot; + размер + & quot; высота: & quot; + размер
& quot ;; & quot ;;
радиус = Math.sqrt (centerX * centerX + центры * центры);
продолжительность = currentTest.milliseconds? 750: 0,75;
//ждем миллисекунду перед построением точек и запуском анимации, чтобы пользовательский интерфейс воспроизводился вперед (превращая кнопку «старт» в кнопку «стоп»), иначе пользователи могут запутаться во время долгой паузы, когда Zepto и преобразование выбираются с помощью из-за того, что браузеру может потребоваться некоторое время, чтобы поместить все точки на свои слои.
setTimeout (function () {
createDots ();
i = длина точки;
while (—i & gt; -1) {
currentTest.tween (точки [я]);
}
}, 1);
} еще {
$ start.html (& quot; НАЧАТЬ & quot;);
$ start.css ({backgroundColor: «# 9af600», background: «linear-gradient (to bottom, # 9af600 0%, # 71B200 100%»});
TweenLite.to ($ инструкции, 0,7, {autoAlpha: 1, задержка: 0,2});
$ inputs.prop («отключено», ложь);
calibrateInputs ();
$ field.css ({pointerEvents: & quot; auto & quot;});
//остановить анимацию и удалить точки.
i = длина точки;
while (—i & gt; -1) {
currentTest.stop (точки [i]);
$ field [0] .removeChild (rawDots [i]);//удаляем точку (и)
}
точки = ноль;
rawDots = ноль;
}
}
function createDots () {
var i = parseInt ($ dotQtyInput.val ()),
точка;
точки = [];
rawDots = [];
while (—i & gt; -1) {
точка = документ.createElement (& quot; img & quot;);
dot.src = & quot; https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/dot.png" ;;
для ширины = 1;
reheight = 1;
dot.id = «точка» + и;
dot.style.cssText = startCSS;
$ field [0] .appendChild (период);
rawDots.push (точка);
dots.push (currentTest.wrapDot (точка))
}
}
function calibrateInputs (e) {
if ($ engineInput.val () == & quot; jquery & quot;) {//jQuery не может анимировать преобразования без стороннего плагина, поэтому отключите эту опцию.
$ propertiesInput [0] .selectedIndex = 0;
$ propertiesInput.prop («отключено», истина);
} еще {
$ propertiesInput.prop («отключено», ложь);
}
}
$ start.click (toggleTest);
$ inputs.change (calibrateInputs);
jQuery.easing.cubicIn = $ .easing.cubicIn = function (p, n, firstNum, diff) {//нам нужно добавить стандартную функцию смягчения CubicIn в jQuery
вернуть firstNum + p * p * diff;
}
jQuery.fx.interval = 16;//обеспечивает обновления jQuery со скоростью около 60 кадров в секунду, аналогично GSAP и другим, чтобы показывать более равномерные/предвзятые результаты.