автор:внешний интерфейсиз Thunder Front End
Оригинальный адрес:Различные реализации и сравнения производительности покадровой анимации
Содержание этой статьи
Web动画形式
应用场景
素材准备
实现方案
一、GIF图
二、CSS3帧动画
三、JS帧动画
方案总结
注意事项
总结
Форма веб-анимации
Во-первых, давайте посмотрим, какие формы анимации есть в Сети.
1. CSS3动画
Transform(变形)
Transition(过渡)
Animation(动画)
2. JS动画(操作DOM、修改CSS属性值)
3. Canvas动画
4. SVG动画
5. 以Three.js为首的3D动画
Каждая из вышеперечисленных форм анимации может создавать один тип анимации, то естькадр анимации, также называемую последовательной покадровой анимацией, покадровой анимацией, покадровой анимацией и т. д. Здесь мы используем покадровую анимацию, чтобы описать ее единообразно.
Сценарии применения
Покадровая анимация обычно используется для достижения несколько более сложных анимационных эффектов, в то же время есть надежда, что анимация будет более тонкой, и дизайнер сможет играть более свободно. Он может определить отображаемое содержимое в каждой временной шкале.Обычно мы используем анимацию кадра для загрузки страницы, маленьких символов и простой анимации небольших элементов объекта. Кадровая анимация, которую мы себе представляем, должна иметь следующие характеристики:
- Свободно управляйте воспроизведением, паузой и остановкой
- Вы можете контролировать количество воспроизведений и скорость воспроизведения
- Взаимодействия могут быть добавлены для добавления событий после завершения воспроизведения
- хорошая совместимость с браузером
подготовка материала
Материал кадровой анимации обычно разрабатывается дизайнером на временной шкале в PS, а затем изображение экспортируется в интерфейсный персонал.PS Производство анимации на временной шкале обычно используется для создания несколько простой анимации, которая проста и удобна в использовании. работать.
Или он разработан дизайнером на временной шкале AE, потому что AE имеет встроенные более богатые эффекты действия, такие как переходы, перевороты и т. д. AE может помочь нам добиться более сложных эффектов, а затем экспортировать изображения в интерфейсный персонал. .
Вот требования к анимационному материалу каждого кадра.Изображение каждого кадра желательно должно быть четного числа по ширине и высоте, и четное количество картинок, и вокруг него лучше всего иметь пустое пространство.
План реализации
Решения, которые в настоящее время имеются в виду, отсортированы следующим образом, и мы подробно представим каждое решение.
1. Гифка
Мы можем экспортировать анимацию кадра, сделанную выше, в изображение GIF. Изображение GIF будет воспроизводиться непрерывно и не может быть приостановлено. Оно часто используется для реализации анимации с мелкими деталями, что является недорогим и простым в использовании. Но очевидны и его недостатки:
- Что касается качества изображения, gif поддерживает несколько цветов (максимум 256 цветов), плохую поддержку прозрачности альфа-канала и серьезные неровные края изображения;
- С точки зрения взаимодействия, воспроизведение, пауза и время воспроизведения не могут контролироваться напрямую, а гибкость оставляет желать лучшего;
- Производительность, gif приведет к тому, что страница будет периодическикартина, производительность плохая.
Во-вторых, кадровая анимация CSS3.
Кадровая анимация CSS3 — это решение, на котором мы должны сосредоточиться сегодня.Анимация, если быть точным, используяanimation-timing-function
Ступенчатая функцияsteps(number_of_steps, direction)
Для непрерывного воспроизведения покадровой анимации.
Принцип реализации покадровой анимации заключается в непрерывном переключении содержимого изображений в визуальном и использовании физиологического явления визуального удержания для реализации анимационного эффекта непрерывного воспроизведения Давайте представим несколько схем для создания покадровой анимации CSS3.
(1) Постоянно переключайте адрес src анимационного изображения (не рекомендуется)
Ставим изображение на фон элемента (background-image
), путем измененияbackground-image
Значение реализует переключение кадров. Однако этот метод будет иметь следующие недостатки, поэтому это решение не рекомендуется.
- Несколько изображений приводят к нескольким HTTP-запросам
- Первая загрузка каждого изображения вызовет мерцание при переключении между изображениями.
- Плохо для управления файлами
(2) Постоянно переключайте положение изображения спрайта (рекомендуется)
Мы объединяем все изображения кадровой анимации в изображение спрайта, изменивbackground-position
Значение для переключения кадров анимации. Сделайте это в два шага:
шаг первый:Объедините кадры анимации в изображение спрайта, требования к изображению спрайта можно увидеть выше.подготовка материала, такие как следующая анимация кадра спрайта, всего 20 кадров.
Шаг 2:Используйте пошаговую функцию для переключения положения карты спрайтов
Сначала посмотрите на метод письма:
<div class="sprite"></div>
.sprite {
width: 300px;
height: 300px;
background-repeat: no-repeat;
background-image: url(frame.png);
animation: frame 333ms steps(1,end) both infinite;
}
@keyframes frame {
0% {background-position: 0 0;}
5% {background-position: -300px 0;}
10% {background-position: -600px 0;}
15% {background-position: -900px 0;}
20% {background-position: -1200px 0;}
25% {background-position: -1500px 0;}
30% {background-position: -1800px 0;}
35% {background-position: -2100px 0;}
40% {background-position: -2400px 0;}
45% {background-position: -2700px 0;}
50% {background-position: -3000px 0;}
55% {background-position: -3300px 0;}
60% {background-position: -3600px 0;}
65% {background-position: -3900px 0;}
70% {background-position: -4200px 0;}
75% {background-position: -4500px 0;}
80% {background-position: -4800px 0;}
85% {background-position: -5100px 0;}
90% {background-position: -5400px 0;}
95% {background-position: -5700px 0;}
100% {background-position: -6000px 0;}
}
Есть вопросы по анимации выше?
Вопрос 1: Теперь, когда ключевые кадры определены подробно, можем ли мы не использовать функцию шагов и напрямую определить линейное изменение?
animation: frame 10s linear both infinite;
Если мы определим его таким образом, анимация не будет пошаговой и выполняться шаг за шагом, а будет постоянно изменять положение фонового изображения, что представляет собой эффект перемещения, а не эффект переключения, как показано ниже:
Вопрос 2: Не стоит ли поставить 20 шагов, почему стало 1?
Здесь мы сначала понимаемanimation-timing-function
Атрибуты.
CSS animation-timing-function
Свойства определяют ритм, с которым CSS-анимация выполняется во время каждого цикла анимации. Для анимации по ключевым кадрам функция синхронизации действует на цикл ключевых кадров, а не на весь цикл анимации, то есть от начала ключевого кадра до конца ключевого кадра.
Функция синхронизации работает между каждыми двумя ключевыми кадрами, а не со всей анимацией.
Далее давайте посмотрим на функцию ()):
- Функция STEPS определяет пошаговую функцию, которая принимает два параметра.
- Первый параметр принимает целочисленное значение, представляющее количество шагов между двумя ключевыми кадрами.
- Второй параметр имеет два значения
или . Значение по умолчанию — . - step-start эквивалентно step(1, start). шаг-конец эквивалентен шагу (1, конец).
Подводя итог, мы можем знать, поскольку мы подробно определяем период ключевого кадра, от начала до конца, каждые два ключевых кадра делятся между1После того, как шаг отображается, то есть он изменяется один раз между 0% и 5% и один раз изменяется между 5% и 10%, поэтому мы можем добиться желаемого эффекта, написав таким образом.
Посмотрите на второй способ записи:
<div class="sprite"></div>
.sprite {
width: 300px;
height: 300px;
background-repeat: no-repeat;
background-image: url(frame.png);
animation: frame 333ms steps(20) both infinite;
}
@keyframes frame {
0% {background-position: 0 0;}//可省略
100% {background-position: -6000px 0;}
}
Здесь мы определяем начало и конец ключевого кадра, то есть определяем период ключевого кадра, но поскольку мы не определяем детально отображение каждого кадра, нам нужно разделить интервал 0%~100% на 20 шагов, чтобы сценический экспонат.
Его также можно заменить ключевым словом или можно определить только последний кадр, поскольку по умолчанию первый кадр является начальной позицией.
@keyframes frame {
from {background-position: 0 0;}//可省略
to {background-position: -6000px 0;}
}
(3) Постоянно перемещайте положение изображения спрайта (рекомендуется для мобильного терминала).
Он в основном такой же, как и второй, но процесс переключения положения карты Sprite заменен наtransform:translate3d()
достичь, но с дополнительным слоемoverflow: hidden;
Пакет контейнера , здесь мы берем определение только начального и конечного кадров в качестве примера, используемtransformОн может включать ускорение графического процессора, улучшать эффект рендеринга машины и эффективно решать проблему дрожания анимации кадров на мобильном терминале.
<div class="sprite-wp">
<div class="sprite"></div>
</div>
.sprite-wp {
width: 300px;
height: 300px;
overflow: hidden;
}
.sprite {
width: 6000px;
height: 300px;
will-change: transform;
background: url(frame.png) no-repeat center;
animation: frame 333ms steps(20) both infinite;
}
@keyframes frame {
0% {transform: translate3d(0,0,0);}
100% {transform: translate3d(-6000px,0,0);}
}
3. Кадровая JS-анимация
(1) Управляйте переключателем атрибута src img через JS (не рекомендуется)
Переключение элементов в анимации кадра CSS3 вышеbackground-image
Свойства одинаковые, будет несколько запросов и другие проблемы, поэтому мы не рекомендуем это решение, но это решение.
(2) Управление рисованием изображения Canvas через JS
Принцип создания покадровой анимации через Canvas заключается в использовании метода drawImage для рисования изображения на Canvas, и мы можем получить желаемый эффект, постоянно стирая и перерисовывая.
<canvas id="canvas" width="300" height="300"></canvas>
(function () {
var timer = null,
canvas = document.getElementById("canvas"),
context = canvas.getContext('2d'),
img = new Image(),
width = 300,
height = 300,
k = 20,
i = 0;
img.src = "frame.png";
function drawImg() {
context.clearRect(0, 0, width, height);
i++;
if (i == k) {
i = 0;
}
context.drawImage(img, i * width, 0, width, height, 0, 0, width, height);
window.requestAnimationFrame(drawImg);
}
img.onload = function () {
window.requestAnimationFrame(drawImg);
}
})();
Вышеупомянутый эффект анимации достигается путем изменения положения координаты X обрезанного изображения, или его также можно достичь путем изменения положения координат изображения, размещенного на холсте, следующим образом:context.drawImage(img, 0, 0, width*k, height,-i*width,0,width*k,height);
.
(3) Управление изменением значения свойства CSS через JS
Этот метод аналогичен предыдущему кадру анимации CSS3.Есть три метода.Один из них заключается в переключении адреса фонового изображения элемента через JS.background-image
, один из них - переключить позиционирование фонового изображения элемента через JSbackground-position
, последний — переместить элемент через JStransform:translate3d()
, первый не вводим, так как тоже будут множественные запросы и другие проблемы, использовать не рекомендуется, здесь реализованы два последних.
- Переключить положение фонового изображения элемента
background-position
.sprite {
width: 300px;
height: 300px;
background: url(frame.png) no-repeat 0 0;
}
<div class="sprite" id="sprite"></div>
(function(){
var sprite = document.getElementById("sprite"),
picWidth = 300,
k = 20,
i = 0,
timer = null;
// 重置背景图片位置
sprite.style = "background-position: 0 0";
// 改变背景图位置
function changePosition(){
sprite.style = "background-position: "+(-picWidth*i)+"px 0";
i++;
if(i == k){
i = 0;
}
window.requestAnimationFrame(changePosition);
}
window.requestAnimationFrame(changePosition);
})();
- Переместить положение фонового изображения элемента
transform:translate3d()
.sprite-wp {
width: 300px;
height: 300px;
overflow: hidden;
}
.sprite {
width: 6000px;
height: 300px;
will-change: transform;
background: url(frame.png) no-repeat center;
}
<div class="sprite-wp">
<div class="sprite" id="sprite"></div>
</div>
(function () {
var sprite = document.getElementById("sprite"),
picWidth = 300,
k = 20,
i = 0,
timer = null;
// 重置背景图片位置
sprite.style = "transform: translate3d(0,0,0)";
// 改变背景图移动
function changePosition() {
sprite.style = "transform: translate3d(" + (-picWidth * i) + "px,0,0)";
i++;
if (i == k) {
i = 0;
}
window.requestAnimationFrame(changePosition);
}
window.requestAnimationFrame(changePosition);
})();
Краткое содержание программы
Обобщая вышеперечисленные схемы, мы видим, что GIF-изображения имеют определенные преимущества и очевидные недостатки и ограничения, поэтому данная схема выбирается в зависимости от ситуации.
А как насчет производительности других реализаций? Давайте сравним их.Если результаты тестирования необъективны, это может быть связано с изменениями в тестовой среде.
тестовая среда:
系统:Windows 10 专业版
处理器:Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz 3.41GHz
RAM: 8.00GB
浏览器:Chrome 72.0
CSS transform:translate3d()
Данные о производительности программы
Как показано выше, мы проверили FPS, загрузку процессора, загрузку графического процессора, сценарии, рендеринг, отрисовку и использование памяти каждой схемы с помощью различных инструментов браузера Chrome и получили следующие данные:
схема производительности | cssbackground-position
|
csstransform:translate3d()
|
JS Canvas | JSbackground-position
|
JStransform:translate3d()
|
---|---|---|---|---|---|
FPS | 60 | 51 | 60 | 60 | 60 |
CPU | 5%-6.2% | 0.3%-1% | 7%-8% | 6%-8% | 6%-8% |
GPU | 3.8MB | 4-10MB | 0 | 3.8MB | 4-11MB |
Scripting | 0 | 0 | 2.51% | 2.61% | 3.18% |
Rendering | 1.17% | 0.141% | 0.84% | 1.65% | 2.71% |
Painting | 1.58% | 0.01% | 1.63% | 1.75% | 1.05% |
ОЗУ | 20112K | 21120K | 21588K | 20756K | 21576K |
Анализируя приведенные выше данные, мы можем сделать следующие выводы:
- кроме css
transform:translate3d()
FPS других схем может плавно достигать 60FPS, но FPS этой схемы не очень низкий. - Решение с наименьшей загрузкой ЦП — css.
transform:translate3d()
план. - Решение с наименьшим использованием графического процессора — это решение для рисования JS Canvas.
- Схема CSS без накладных расходов на скрипты
- Наименьший рендеринг - css
transform:translate3d()
план. - Минимум отрисовки css
transform:translate3d()
план. - Использование памяти каждой программой не сильно отличается.
в заключении: Мы видим, что среди 7 метрик csstransform:translate3d()
Схема минимизирует их 4. С этой точки зрения у нас есть все основания выбрать именно эту схему для достижения покадровой CSS-анимации.
Что касается абсолютного сравнения других схем, то вывод пока сделать нельзя, выбор зависит от конкретной ситуации и от того, какой показатель производительности преследует разработчик.
Глядя на нашу веб-анимацию в расширении, каждая форма анимации имеет свои преимущества, например, большое количество эффектов частиц можно нарисовать с помощью Canvas, что определенно лучше, чем DOM+CSS.transform
Производительность реализации должна быть лучше.
Меры предосторожности
материал: Ширина и высота анимационных картинок желательно четные числа, общее количество кадров желательно четные числа, а при стыковке картинок присутствует некоторое количество пробелов.
приспособление: лучше не использовать rem для мобильной адаптации, потому что вычисление rem приведет к округлению десятичных знаков, что приведет к определенному эффекту дрожания.Рекомендуется напрямую использовать px в качестве единицы измерения и в то же время помочь с масштабом (увеличение) медиазапрос для адаптации. Если вы используете адаптацию rem, попробуйте использоватьtransform, проблема джиттера может быть решена оптимально.
для кадра в кадрДополнительные прибыли и убыткиЭто явление вызывает дрожание анимации. Чтобы узнать больше, вы можете прочитать«Навыки CSS: решение покадровой анимации с дрожанием».
tips:использоватьwill-change
Можно заранее подготовиться к фактическому изменению свойств элемента.
Суммировать
В данной работе мы в основном разберем несколько схем реализации покадровой анимации в настоящее время, а заодно реализуем эффект от различных схем, обсудим преимущества и недостатки, сравним производительность.При этом кратко ввести меры предосторожности в процессе реализации покадровой анимации.transform:translate3d()
Схема значительно лучше других схем с точки зрения реализации и производительности.
Источник ссылки: