Автор: Bump Man - Арвин
введение
В веб-приложениях фронтенд-студенты часто используют несколько схем для достижения анимационных эффектов:
- css3 transition/animation — реализовать анимацию перехода
- setInterval/setTimeout — постоянно менять положение изображения, задавая интервал
- requestAnimationFrame — измените положение изображения с помощью функции обратного вызова, и система определяет время выполнения этой функции обратного вызова, которая имеет лучшую производительность, чем изменение времени, и нет явления потери кадров.
В большинстве требований CSS3transition / animation
Все может удовлетворить наши потребности, и по сравнению с реализацией js это может значительно повысить эффективность нашей разработки и снизить затраты на разработку.
Эта статья будет посвященаanimation
Подводя итог использованию , если у вас есть дополнительные требования к анимации в вашей работе, я считаю, что эта статья может помочь вам что-то получить:
- Анимация Общие свойства анимации
- Анимация реализует непрерывную трансляцию
- Анимация для достижения эффекта отскока
- Анимация реализует аналогичный эффект прямого эфира ❤️
- Какую искру создадут Animation и Svg? 🔥
- Загрузка компонента
- компонент индикатора выполнения
- Шаги анимации () с использованием ⏰
- добиться эффекта набора текста
- рисовать кадр анимации
Анимация Общие свойства анимации
После знакомства с общими свойствами анимации, чтобы лучше понять и использовать эти свойства, далее будут подробно описаны некоторые демонстрации.
Анимация реализует непрерывную трансляцию
Реализовать непрерывную трансляцию DEMO
Эффект трансляции за счет изменения положения содержимого по оси Y в родительском элементе.
@keyframes scroll {
0%{
transform: translate(0, 0);
}
100%{
transform: translate(0, -$height);
}
}
.ul {
animation-name: scroll;
animation-duration: 5s;
animation-timing-function: linear;
animation-iteration-count: infinite;
/* animation: scroll 5s linear infinite; 动画属性简写 */
}
Здесь, чтобы сохранить непрерывность эффекта прокрутки трансляции и предотвратить прокрутку до последнего кадра без контента,Нужно добавить еще один дубликат данных для заполнения
<div class="ul">
<div class="li">小刘同学加入了凹凸实验室</div>
<div class="li">小邓同学加入了凹凸实验室</div>
<div class="li">小李同学加入了凹凸实验室</div>
<div class="li">小王同学加入了凹凸实验室</div>
<!-- 插入用于填充的数据数据 -->
<div class="li">小刘同学加入了凹凸实验室</div>
</div>
Анимация для достижения эффекта отскока
Это достигается путем разделения анимации перехода на несколько этапов, в каждом из которых верхнее свойство остается в другом положении.
Реализуйте эффект отскока DEMO
/* 规定动画,改变top,opacity */
@keyframes animate {
0% {
top: -100%;
opacity: 0;
}
25% {
top: 60;
opacity: 1;
}
50% {
top: 48%;
opacity: 1;
}
75% {
top: 52%;
opacity: 1;
}
100%{
top: 50%;
opacity: 1;
}
}
Чтобы сделать эффект перехода более естественным, здесьcubic-bezier()
Функция определяет кривую Безье для управления скоростью воспроизведения анимации.
После выполнения анимации перехода, чтобы применить к элементу значение атрибута последнего кадра анимации, нам нужно использоватьanimation-fill-mode: forwards
.popup {
animation-name: animate;
animation-duration: 0.5s;
animation-timing-function: cubic-bezier(0.21, 0.85, 1, 1);
animation-iteration-count: 1;
animation-fill-mode: forwards;
/* animation: animate 0.5s cubic-bezier(0.21, 0.85, 1, 1) 1 forwards; 动画属性简写 */
}
Анимация реализует подобный эффектOnline Code
Реализовать подобный эффект DEMO
Я считаю, что большинству студентов известен подобный эффект.Эта статья реализует простую версию подобного эффекта, в основном об идеях реализации:
- Чтобы пузыри были смещены вверх, нам нужно реализовать анимацию @keyframes, которая перемещается в направлении оси Y.
/* 规定动画,改变y轴偏移距离*/
@keyframes animation-y {
0%{
transform: translate(-50%, 100px) scale(0);
}
50%{
transform: translate(-50%, -100px) scale(1.5);
}
100%{
transform: translate(-50%, -300px) scale(1.5);
}
}
- Чтобы пузырек казался менее монотонным, когда он смещен вверх, мы можем реализовать другую анимацию @keyframes, которая перемещается в направлении оси x.
/* 规定动画,改变x轴偏移距离 */
@keyframes animation-x {
0%{
margin-left: 0px;
}
25%{
margin-left: 25px;
}
75%{
margin-left: -25px;
}
100%{
margin-left: 0px;
}
}
Вот я понимаю:
- Хотя это является
修改 margin
для изменения расстояния смещения по оси X, но на самом деле это то же самое, что и修改 transform
Не большая разница в производительности - потому что через
@keyframes animation-y
серединаtransform
создал новый渲染层 ( PaintLayers )
-
animation
Атрибут позволяет повысить уровень этого слоя рендеринга до合成层(Compositing Layers)
иметь отдельный图形层 ( GraphicsLayer )
, то есть включено аппаратное ускорение, на другие слои рендеринга оно не повлияетpaint、layout
- за
合成层(Compositing Layers)
Студенты, которые не очень хорошо владеют соответствующими знаниями, могут прочитать эту статьюАнализ принципа оптимизации динамических эффектов css3 с уровня рендеринга браузера - Как показано ниже:
Если понимание автора здесь неверно, я также прошу читателей указать на это, большое спасибо~
- Примените две анимации @keyframes, которые мы реализовали к пузырю.
.bubble {
animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1;
/* 给 bubble 开启了硬件加速 */
}
- В подобном случае динамически добавляйте/удаляйте элементы пузыря с помощью операций js.
function like() {
const likeDom = document.createElement('div');
likeDom.className = 'bubble'; // 添加样式
document.body.appendChild(likeDom); // 添加元素
setTimeout( () => {
document.body.removeChild(likeDom); // 移除元素
}, 4000)
}
Компоненты загрузки/индикатора загрузки анимации и рисования Svg 🔥Online Code
Компонент загрузки/индикатора загрузки анимации и Svg-рисования 🔥 DEMO
- Во-первых, мы используем svg, чтобы нарисовать круг с окружностью
2 * 25 * PI = 157
круг
<svg with='200' height='200' viewBox="0 0 100 100" >
<circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke="#0079f5" ></circie>
</svg>
- Нарисуйте сплошной круг как пунктирный круг, здесь вам нужно использовать
stoke-dasharray:50, 50 (可简写为50)
свойство рисовать пунктирные линии,сток-дашаррай
- Его значение представляет собой последовательность чисел, разделенных запятыми или пробелами, указывающую
短划线(50px)
и缺口(50px)
длина. - так как
50(短划线) + 50(缺口) + 50(段划线) = 150, 150 < 157
, полный круг нельзя нарисовать, поэтому правая сторона будет существовать缺口(7px)
<svg with='200' height='200' viewBox="0 0 100 100" >
<circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke-dasharray="50" stroke="#0079f5" ></circie>
</svg>
-
stroke-dashoffset
Свойство может компенсировать штрихи и пробелы в круге, а добавление анимации @keyframes может добиться эффекта с нуля.stoke-dashoffset Ссылки
- настраивать
stroke-dasharray="157 157
", уточнить短划线(157px)
и缺口(157px)
длина. - Добавить анимацию @keyframes
修改stroke-dashoffset值
, значение正数
Время逆时针偏移
🔄, значение равно负数
час,顺时针偏移
🔃
@keyframes loading {
0%{
stroke-dashoffset: 0;
}
100%{
stroke-dashoffset: -157; /* 线条顺时针偏移 */
}
}
circle{
animation: loading 1s 0s ease-out infinite;
}
- Изменить значения тире и пробела
- Чтобы сделать линии загрузки компонентов видимыми, нам нужен
50px
тире, наборstroke-dasharray="50"
- Чтобы черточка полностью исчезла после смещения,
缺口需要大于或等于圆周长157
,настраиватьstroke-dasharray="50 157"
- Добавлена анимация @keyframes, чтобы сделать
动画结束时仍处理动画开始位置
,необходимость修改 stroke-dashoffset:-207(短划线+缺口长度)
- Индикатор выполнения также представляет собой аналогичный принцип, помогающий понять
stroke-dashoffset
Атрибут, см. конкретную реализациюПример
@keyframes loading {
0%{
stroke-dashoffset: 0;
}
100%{
stroke-dashoffset: -207; /* 保证动画结束时仍处理动画开始位置 */
}
}
circle{
animation: loading 1s 0s ease-out infinite;
}
Приложение шагов анимации ()
steps()
даanimation-timing-function
стоимость имущества
animation-timing-function : steps(number[, end | start])
- Функция шагов задает ступенчатую функцию, которая принимает
两个参数
-
第一个参数接受一个整数值
, указывая на то, что два ключевых кадра завершены в несколько шагов -
第二个参数有两个值 start or end
. Значение по умолчанию — конец - step-start эквивалентно step(1, start). шаг-конец эквивалентен шагу (1, конец)
шаги предназначены для анимации по ключевым кадрам, первый параметр будет两个关键帧
подразделяется наN帧
, используется второй параметр, определяющий промежуточный интервал от одного кадра к другому开始帧
все еще结束帧
заполнять.
Посмотрите на изображение ниже, чтобы узнать:
-
steps(N, start)
Разделить анимацию наN段
, анимация в каждом сегменте起点
Происходит шаг (то есть пустой круг на рисунке → сплошной круг), и анимация заканчивается на N-м кадре. -
steps(N, end)
Разделить анимацию наN段
, анимация в каждом сегменте终点
Происходит шаг (то есть пустой круг → сплошной круг на рисунке), и N-й кадр был пропущен в конце анимации (то есть пустой круг → сплошной круг на рисунке), и он остается на кадр N+1.
Практикуйте правду!
Анимация реализует эффект набора текста
Анимация реализует эффект набора текста DEMO
- Вот пример английских букв (я O2man.), всего
13
символы. [После тестирования большинство китайских шрифтов имеют одинаковую ширину и высоту для каждого символа] -
steps(13)
Анимации @keyframes можно разделить на13阶段
бежать, и每一阶段运行距离相等
.
Эффект следующий:
/* 改变容器宽度 */
@keyframes animate-x {
0%{
width: 0;
}
}
p {
width: 125px;
overflow: hidden;
border-right: 1px solid transparent;
animation: animate-x 3s 0s steps(13) 1 forwards;
}
- Можно обнаружить, что этого недостаточно, символы усекаются во время выполнения анимации.Чтобы гарантировать, что символы текущего этапа могут отображаться точно после запуска каждого этапа, нам также необходимо обеспечить
每个字符的width与动画每一阶段运行的距离相等
- настраивать
Monaco
Свойства шрифта для обеспечения每个字符的 width 相同
, на конкретный пиксель влияетfontSize
эффект атрибута, ширина шрифта в примере около 9,6 пикселей,9.6px * 13(段数) = 124.8px (125px)
, поэтому, когда мы установим ширину контейнера на 125 пикселей, мы сможем достичь цели:每个字符的 width 与动画每一阶段运行的距离相等(约为 9.6px )
.
p {
/* 设置 Monaco 字体属性,字体大小为16px,用以保证每个字符的 width 相同,width 约为9.6p */
font-family: Monaco;
/* 9.6px * 13 = 124.8px (125px) */
width: 125px ;
font-size: 16px;
overflow: hidden;
border-right: 1px solid transparent;
/* 同时应用动画 animate-x、cursor-x */
animation: animate-x 3s 0s steps(13) 1 forwards,cursor-x 0.4s 0s linear infinite;
}
Анимация реализует покадровую анимацию ⏰
Animation реализует покадровую анимацию ⏰ DEMO
- Здесь мы получили
47帧
изСпрайт (css дух), установить фоновое изображение
.main {
width: 260px;
height: 200px;
background: url(url) no-repeat;
background-size: 100%;
background-position: 0 0;
}
- добавить @ключевые кадры
修改 background-position
, чтобы переместить фоновое изображение
@keyframes animate {
0% {
background-position: 0 0;
}
100% {
background-position: 0 100%;
}
}
.main{
width: 260px;
height: 200px;
background: url(url) no-repeat;
background-size: 100%;
background-position: 0 0;
animation: animate 2s 1s steps(47) infinite alternate;
}
- В то же время css также предоставляет
animation-play-state
Используется для управления приостановкой анимации.
input:checked+.main{
animation-play-state: paused;
}
Статья длинная, спасибо за прочтение, надеюсь, вы сможете что-то почерпнуть из аудитории~ ~ ~
использованная литература
Анимация Общие свойства анимации
Справочное руководство по CSS
ссылка на шаги()
Подробное объяснение stroke-dasharray и stroke-dashoffset для изучения SVG
Понимание steps() в анимации CSS3
[Перевод] Подробное объяснение использования steps() в анимации CSS
CSS Will Change