Как изменить скорость анимации css

I have animation: img.rotate { animation-name: rotate; animation-duration: 1.5s; animation-iteration-count: infinite; animation-timing-function: linear; } @keyframes rotate { from {

It’s a very difficult process to do so. Currently the only way to change an animation mid-animation is to use a setInterval to approximate the current keyframes percentage, save the properties of that keyframe, update the animation (in your case just the speed) then apply the new version of the animation starting from the saved point. I created a similar example in the article I wrote for CSS Tricks called Controlling CSS Animations & Transitions with Javascript

As the article described, it’d be easier to change the speed on animationIteration, in your case that would look like this demo, but it is still far from pretty

 var pfx = ["webkit", "moz", "MS", "o", ""],
    rotates = $('.rotate'),
    prevent = false;

function PrefixedEvent(element, type, callback) {
    for (var p = 0; p < pfx.length; p++) {
        if (!pfx[p]) type = type.toLowerCase();
        element.addEventListener(pfx[p]+type, callback, false);
    }
}

function listen() {
    for(var i = 0, j = rotates.length; i < j; i ++) {
        PrefixedEvent(rotates[i], "AnimationIteration", function() {
            if(!$('#faster').is(':checked') && !prevent) {
                var el = $(this),  
                   newOne = el.clone(true)
                            .css({'animation':'rotate 2s linear infinite'});
                el.before(newOne);        
                $("." + el.attr("class") + ":last").remove();
                rotates = $('.rotate');
                listen();
                prevent = true;
            }
            else if($('#faster').is(':checked') && prevent) {
                prevent = false;
                var el = $(this),
                   newOne = el.clone(true)
                            .css({'animation':'rotate 1.5s linear infinite'});
                el.before(newOne);
                $("." + el.attr("class") + ":last").remove();
                rotates = $('.rotate');
                listen();
            }
        });
    }
}
listen();

At the moment we cannot simply restart the animation with a different timing function (even if you pause it and run it again like Michael said). As a result you either have to use a setInterval (which gives a higher delay) or clone the element with the changed values. For more information on the approach I used look at the demo, I added comments to all the javascript I added

EDIT based on your linked fiddle in comments

Since you’re trying to simulate a roulette, you don’t need to use javascript at all! Simply change your rotation animation to change speed over time (: Here’s an rough version of how you’d do so, but you should add more keyframes to make it appear more smooth than it currently behaves

@-webkit-keyframes rotate {
    0%   { -webkit-transform: rotate(   0deg); }
    30%  { -webkit-transform: rotate(2600deg); }
    60%  { -webkit-transform: rotate(4000deg); }
    80%  { -webkit-transform: rotate(4500deg); }
    100% { -webkit-transform: rotate(4780deg); }
}

EDIT 2

Since you need apparently need have a random ending position and likely run it multiple times you can do something like this which is much simpler, only uses CSS transforms, and incredibly useful

var img = document.querySelector('img');
img.addEventListener('click', onClick, false);    
var deg = 0;

function onClick() {
    this.removeAttribute('style');        
    deg += 5 * Math.abs(Math.round(Math.random() * 500));        
    var css = '-webkit-transform: rotate(' + deg + 'deg);';        
    this.setAttribute(
        'style', css
    );
}

and the CSS

img { -webkit-transition: -webkit-transform 2s ease-out; }

Edit 3

This isn’t fully relevant or irrelevant, but you can do very similar things using GSAP like I did in this project to make it more interactive/dynamic

Очень простое руководство по CSS3-анимациям

Я постарался написать настолько понятное и простое руководство по CSS3-анимациям, насколько это вообще возможно. Итак, приступим!

Чтобы воспользоваться анимацией в своём проекте, вам достаточно сделать две вещи:

  1. Создать саму анимацию.
  2. Подключить её к элементу, который надо анимировать, и указать нужные свойства.

Анимация представляет собой набор ключевых кадров, который содержится в css и выглядит вот так:

@keyframes test-animation {
    0% {
        width: 50px;
    }
    100% {
        width: 150px;
    }
}

Давайте разберёмся что мы здесь видим. Ключевое слово @keyframes указывает на саму анимацию. Далее идет её имя, я назвал её test-animation. В фигурных скобках находится список ключевых кадров. В данном случае это начальный кадр 0% и конечный кадр 100%. Также начальный и конечный кадры можно записать ключевыми словами from и to.

Теперь посмотрите на следующий код. Так тоже можно написать:

@keyframes test-animation {
    from {
        width: 50px;
    }
    30% {
        width: 99px;
    }
    60.8% {
        width: 120px;
    }
    to {
        width: 150px;
    }
}

Обратите внимание, если не задан начальный (from, 0%) или конечный (to, 100%) кадр, браузер установит для них расчётные значения анимируемых свойств такими, какими они были бы если бы не была применена анимация.

Здесь и далее для удобства я написал в примерах несколько строчек JavaScript, которые будут поочередно добавлять или удалять класс с анимацией на элементе, поэтому для воспроизведения анимации просто кликните по этому элементу.

Посмотреть на CodePen: Простая анимация.

Подключение анимации к элементу происходит двумя командами:

element {
    animation-name: current-anim-name;
    animation-duration: 2s;
}

В правиле animation-name задаётся имя созданной вами анимации @keyframes. Правило animation-duration указывает сколько секунд анимация будет воспроизводиться. Его можно указывать в секундах (3s, 65s, .4s) или в миллисекундах (300ms, 1000ms).

Ключевые кадры можно группировать:

@keyframes animation-name {
    0%, 35% {
        width: 100px;
    }
    100% {
        width:200px;
    }
}

Одному элементу можно назначить несколько анимаций, их имена и параметры надо писать в порядке присвоения:

element {
    animation-name: animation-1, animation-2;
    animation-duration: 2s, 4s;
}

Задержка анимации

Свойство animation-delay определяет задержку до начала воспроизведения анимации, задаётся в секундах или миллисекундах:

element {
    animation-name: animation-1;
    animation-duration: 2s;
    animation-delay: 5s; // Перед стартом этой анимации пройдет 5 сек.
}

Количество проигрываний анимации

В качестве значения свойства animation-iteration-count выставляем любое положительное значение от 0, 1, 2, 3… и т.д. либо infinite для бесконечного повторения.

element {
    animation-name: animation-1;
    animation-duration: 2s;
    animation-delay: 5s;
    animation-iteration-count: 3; //эта анимация проиграется 3 раза
}

Состояние ДО и ПОСЛЕ анимации

Свойство animation-fill-mode определяет в каком состоянии будет элемент до начала анимации и после её завершения.

  • animation-fill-mode: forwards; — после завершения анимации состояние элемента будет соответствовать последнему кадру.
  • animation-fill-mode: backwards; — после завершения анимации состояние элемента будет соответствовать первому кадру.
  • animation-fill-mode: both; — до начала анимации состояние элемента будет соответствовать первому кадру, а после окончания — последнему.

В примере ниже трём элементам назначена одна и та же анимация, но каждый элемент имеет разные значения animation-fill-mode:

Посмотреть на CodePen: ДО и ПОСЛЕ анимации.

Запуск и остановка анимации

Осуществляем с помощью свойства animation-play-state, который принимает только 2 значения: либо running, либо paused. Тут всё просто :)

Направление анимации

С помощью свойства animation-direction мы можем управлять направлением воспроизведения анимации. Его параметры могут принимать несколько значений:

  • animation-direction: normal; — анимация проигрывается вперёд, это обычное направление анимации.
  • animation-direction: reverse; — анимация проигрывается в обратном направлении, от to к from.
  • animation-direction: alternate; — чётные проигрывания анимации будут идти в обратном направлении, а нечётные — в обычном.
  • animation-direction: alternate-reverse; — чётные проигрывания вашей анимации будут проигрываться в обычном направлении, а нечётные — в обратном.

Посмотреть на CodePen: Направление анимации.

Функция распределения анимируемых значений по времени

Правило animation-timing-function позволяет задать специальную функцию, отвечающую за скорость воспроизведения анимации. Обратим внимание, что скорость воспроизведения анимации чаще всего нелинейная, т.е. ее мгновенная скорость в разных участках будет отличаться. На данный момент существует несколько уже встроенных аргументов для этого правила: ease, ease-in, ease-out, ease-in-out, linear, step-start, step-end.

Однако такие функции можно создавать самому. Специальная функция animation-timing-function: cubic-bezier(P1x, P1y, P2x, P2y); принимает четыре аргумента и строит на их основе кривую распределения значений в процессе анимации. Потренироваться в создании своих функций и посмотреть как они работают можно на http://cubic-bezier.com/ или https://matthewlein.com/ceaser/.

И, наконец, анимацию можно превратить в набор дискретных значений с помощью функции steps(количество шагов, направление), в качестве аргументов которой задаётся количество её шагов и направление, которое может принимать значения start или end. В следующем примере анимация будет состоять из 7 шагов, последний из которых будет сделан непосредственно перед завершением анимации:

element {
    animation-timing-function: steps(7, end);
}

График

Посмотреть на CodePen: Форма анимации.

Поддержка браузерами

CSS-анимации имеют довольно хорошую поддержку, и со временем она будет становится все лучше. Подробно о поддержке анимаций десктопными и мобильными браузерами можно узнать из таблицы Can I use.

Материалы для дальнейшего изучения

  • Animate.css — самая знаменитая библиотека CSS-анимаций.
  • Effect.css — не менее известная библиотека анимаций.
  • CSS3 Animation Cheat Sheet — отличная подборка примеров.
  • Курс CSS3 анимаций на htmlacademy — лучшее место, чтобы освоить анимации на практике. Платно, но очень дешево.
  • MDN CSS Animation — самый актуальный справочник по анимациям.
  • Обязательно поиграйте с Bounce.js. Крутейшие и супер-плавные эффекты.
  • Motion-ui-design — крутая коллекция ссылок по анимациям от @fliptheweb.

На этом всё! Есть несколько мелочей, которые мы не рассмотрели, подробнее о них можно прочесть в приведённых выше материалах. Однако вы должны знать, что и без них вы только что изучили CSS3-анимации примерно на 97,8%. Поздравляю :)

I have searched through a lot of questions related to my question in stackoverflow but i haven’t found one yet that answers my question with plain JavaScript (not using libraries of any kind).

My problem is that I have an infinite animation with CSS3 i.e.:

.clockwiseAnimation {
    top: 270px;
    left: 200px;
    position: absolute;

    -webkit-animation: clockwise 4s linear infinite; /* Chrome, Safari 5 */
    -moz-animation: clockwise 4s linear infinite; /* Firefox 5-15 */
    -o-animation: clockwise 4s linear infinite; /* Opera 12+ */
    animation: clockwise 4s linear infinite; /* Chrome, Firefox 16+, IE 10+, Safari 5 */
}
@-webkit-keyframes clockwise {
    from { -webkit-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-moz-keyframes clockwise {
    from { -moz-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -moz-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-o-keyframes clockwise {
    from { -o-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -o-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@keyframes clockwise {
    from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}

This animation allows me to spin (clockwise) whatever tag that has the class «clockwiseAnimation».

What I want to do is to change the time of execution (I’ll call it speed) of the animation with javascript like:

HTML:

<span id="someID" class="clockwiseAnimation">sometext</span>

JavaScript:

var style = document.getElementById("someID").style,
speed = 6; 
//obviously the speed is dynamic within my site (through an `<input type="range">`)
//for the purposes of this example I set the speed to a different value(6seconds) than the original value(4seconds).
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";

It works when I pause and then play(by play I mean UNPAUSE not restart) the animation, i.e.:

var style = document.getElementById("someID").style;
some = 6; //it is dynamic (as I pointed out before)

//pause
style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";

//change speed
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";  

//play (== UNPAUSE) //UPDATE: Added the timeout because I can't get it to work any other way.
setTimeout(function(){
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
        },1);

UPDATED:

And it works! BUT, it has a big RANDOM jump in the animation, meaning that when I change the «speed» with the «<input type="range"> slider» the element jumps to a random location (not the beginning nor the end of the animation just a random location).

NOTE: Pause and play works very smooth without changing the «speed» of the animation.

My question(s): Can I change the «speed» of the animation smoothly WITH JavaScript? (WITHOUT the jumping)
If the answer is: «There is not a way to do it smoothly throughout the animation execution», then:
Is there a way to change it in the next iteration of the infinite animation?
If so:
Then how can I tell it to start in the next iteration and how to know which is the next iteration if I set the animation to infinite (animation-iteration-count property of the element that is doing the animation always returns «infinite»).

Here is an example. I hope it helps.

I have searched through a lot of questions related to my question in stackoverflow but i haven’t found one yet that answers my question with plain JavaScript (not using libraries of any kind).

My problem is that I have an infinite animation with CSS3 i.e.:

.clockwiseAnimation {
    top: 270px;
    left: 200px;
    position: absolute;

    -webkit-animation: clockwise 4s linear infinite; /* Chrome, Safari 5 */
    -moz-animation: clockwise 4s linear infinite; /* Firefox 5-15 */
    -o-animation: clockwise 4s linear infinite; /* Opera 12+ */
    animation: clockwise 4s linear infinite; /* Chrome, Firefox 16+, IE 10+, Safari 5 */
}
@-webkit-keyframes clockwise {
    from { -webkit-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -webkit-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-moz-keyframes clockwise {
    from { -moz-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -moz-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@-o-keyframes clockwise {
    from { -o-transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { -o-transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}
@keyframes clockwise {
    from { transform: rotate(0deg) translateX(150px) rotate(0deg); }
    to { transform: rotate(360deg) translateX(150px) rotate(-360deg); }
}

This animation allows me to spin (clockwise) whatever tag that has the class «clockwiseAnimation».

What I want to do is to change the time of execution (I’ll call it speed) of the animation with javascript like:

HTML:

<span id="someID" class="clockwiseAnimation">sometext</span>

JavaScript:

var style = document.getElementById("someID").style,
speed = 6; 
//obviously the speed is dynamic within my site (through an `<input type="range">`)
//for the purposes of this example I set the speed to a different value(6seconds) than the original value(4seconds).
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";

It works when I pause and then play(by play I mean UNPAUSE not restart) the animation, i.e.:

var style = document.getElementById("someID").style;
some = 6; //it is dynamic (as I pointed out before)

//pause
style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "paused";

//change speed
style.webkitAnimationDuration = style.mozAnimationDuration = style.oAnimationDuration = style.animationDuration = speed + "s";  

//play (== UNPAUSE) //UPDATE: Added the timeout because I can't get it to work any other way.
setTimeout(function(){
            style.webkitAnimationPlayState = style.mozAnimationPlayState = style.oAnimationPlayState = style.animationPlayState = "running";
        },1);

UPDATED:

And it works! BUT, it has a big RANDOM jump in the animation, meaning that when I change the «speed» with the «<input type="range"> slider» the element jumps to a random location (not the beginning nor the end of the animation just a random location).

NOTE: Pause and play works very smooth without changing the «speed» of the animation.

My question(s): Can I change the «speed» of the animation smoothly WITH JavaScript? (WITHOUT the jumping)
If the answer is: «There is not a way to do it smoothly throughout the animation execution», then:
Is there a way to change it in the next iteration of the infinite animation?
If so:
Then how can I tell it to start in the next iteration and how to know which is the next iteration if I set the animation to infinite (animation-iteration-count property of the element that is doing the animation always returns «infinite»).

Here is an example. I hope it helps.

Oct 6, 2020

Rachel Andrew

Kayce Basques

On this page

  • Browser compatibility
  • Move an element
  • Resize an element
  • Change an element’s visibility
  • Avoid properties that trigger layout or paint
  • Force layer creation
  • Debug slow or janky animations
    • Check if an animation triggers layout
    • Check if an animation is dropping frames
    • Check if an animation triggers paint
  • Conclusion

This guide teaches you how to create high-performance CSS animations.

See Why are some animations slow? to learn the theory behind these recommendations.

Browser compatibility #

All of the CSS properties that this guide recommends have good cross-browser support.

  • transform
  • opacity
  • will-change

Move an element #

To move an element, use the translate or rotation keyword values of the transform property.

For example to slide an item into view, use translate.

.animate {
animation: slide-in 0.7s both;
}

@keyframes slide-in {
0% {
transform: translateY(-1000px);
}
100% {
transform: translateY(0);
}
}

Items can also be rotated, in the example below 360 degrees.

.animate {
animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}

Resize an element #

To resize an element, use the scale keyword value of the transform property.

.animate {
animation: scale 1.5s both;
}

@keyframes scale {
50% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}

Change an element’s visibility #

To show or hide an element, use opacity.

.animate {
animation: opacity 2.5s both;
}

@keyframes opacity {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}

Avoid properties that trigger layout or paint #

Before using any CSS property for animation (other than transform and opacity), determine the property’s impact on the rendering pipeline. Avoid any property that triggers layout or paint unless absolutely necessary.

Force layer creation #

As explained in Why are some animations slow?, by placing elements on a new layer they can be repainted without also requiring the rest of the layout to be repainted.

Browsers will often make good decisions about which items should be placed on a new layer, but you can manually force layer creation with the will-change property. As the name suggests, this property tells the browser that this element is going to be changed in some way.

In CSS this property can be applied to any selector:

body > .sidebar {
will-change: transform;
}

However, the specification suggests this approach should only be taken for elements that are always about to change. If the above example was a sidebar the user could slide in and out, that might be the case. Some items on your page may not frequently change, and so it would be better to apply will-change using JavaScript at a point where it becomes likely the change will occur. You’ll need to make sure to give the browser enough time to perform the optimizations needed and then remove the property once the changing has stopped.

If you need a way to force layer creation in one of the rare browsers that doesn’t support will-change (most likely Internet Explorer at this point), you can set transform: translateZ(0).

Debug slow or janky animations #

Chrome DevTools and Firefox DevTools have lots of tools to help you figure out why your animations are slow or janky.

Check if an animation triggers layout #

An animation that moves an element using something other than transform, is likely to be slow. In the following example, I have achieved the same visual result animating top and left, and using transform.

Don’t

.box {
position: absolute;
top: 10px;
left: 10px;
animation: move 3s ease infinite;
}

@keyframes move {
50% {
top: calc(90vh - 160px);
left: calc(90vw - 200px);
}
}

Do

.box {
position: absolute;
top: 10px;
left: 10px;
animation: move 3s ease infinite;
}

@keyframes move {
50% {
transform: translate(calc(90vw - 200px), calc(90vh - 160px));
}
}

You can test this in the following two Glitch examples, and explore performance using DevTools.

  • Before.
  • After.

Chrome DevTools #

  1. Open the Performance panel.
  2. Record runtime performance while your animation is happening.
  3. Inspect the Summary tab.

If you see a nonzero value for Rendering in the Summary tab, it may mean that your animation is causing the browser to do layout work.

The Summary panel shows 37ms for rendering and 79ms for painting.

The animation-with-top-left example causes rendering work.
The Summary panel show zero values for rendering and painting.
The animation-with-transform example does not cause rendering work.

Firefox DevTools #

In Firefox DevTools the Waterfall can help you to understand where the browser is spending time.

  1. Open the Performance panel.
  2. In the panel Start Recording Performance while your animation is happening.
  3. Stop the recording and inspect the Waterfall tab.

If you see entries for Recalculate Style then the browser is having to begin at the start of the rendering waterfall.

Check if an animation is dropping frames #

  1. Open the Rendering tab of Chrome DevTools.
  2. Enable the FPS meter checkbox.
  3. Watch the values as your animation runs.

At the top of the FPS meter UI you see the label Frames. Below that you see a value along the lines of 50% 1 (938 m) dropped of 1878. A high-performance animation will have a high percentage, e.g. 99%. A high percentage means that few frames are being dropped and the animation will look smooth.

The fps meter shows 50% of frames were dropped

The animation-with-top-left example causes 50% of frames to be dropped
The fps meter shows only 1% of frames were dropped
The animation-with-transform example causes only 1% of frames to be dropped.

Check if an animation triggers paint #

When it comes to painting, some things are more expensive than others. For example, anything that involves a blur (like a shadow, for example) is going to take longer to paint than drawing a red box. In terms of CSS, however, this isn’t always obvious: background: red; and box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5); don’t necessarily look like they have vastly different performance characteristics, but they do.

Browser DevTools can help you to identify which areas need to be repainted, and performance issues related to painting.

Chrome DevTools #

  1. Open the Rendering tab of Chrome DevTools.
  2. Select Paint Flashing.
  3. Move the pointer around the screen.

A UI element highlighted in green to demonstrate it will be repainted

In this example from Google Maps you can see the elements that will be repainted.

If you see the whole screen flashing, or areas that you don’t think should change highlighted then you can do some investigation.

If you need to dig into whether a particular property is causing performance issues due to painting, the paint profiler in Chrome DevTools can help.

Firefox DevTools #

  1. Open Settings and add a Toolbox button for Toggle paint flashing.
  2. On the page you want to inspect, toggle the button on and move your mouse or scroll to see highlighted areas.

Conclusion #

Where possible restrict animations to opacity and transform in order to keep animations on the compositing stage of the rendering path. Use DevTools to check which stage of the path is being affected by your animations.

Use the paint profiler to see if any paint operations are particularly expensive. If you find anything, see if a different CSS property will give the same look and feel with better performance.

Use the will-change property sparingly, and only if you encounter a performance issue.

Return to all articles

Experimental: Это экспериментальная технология
Так как спецификация этой технологии ещё не стабилизировалась, смотрите таблицу совместимости по поводу использования в различных браузерах. Также заметьте, что синтаксис и поведение экспериментальной технологии может измениться в будущих версиях браузеров, вслед за изменениями спецификации.

CSS-анимации позволяют анимировать переходы от одной конфигурации CSS стилей к другой. CSS-анимации состоят из двух компонентов: стилевое описание анимации и набор ключевых кадров, определяющих начальное, конечное и, возможно, промежуточное состояние анимируемых стилей.

Есть три преимущества CSS-анимации перед традиционными способами:

  1. Простота использования для простых анимаций; вы можете создать анимацию, не зная JavaScript.
  2. Анимации будут хорошо работать даже при умеренных нагрузках системы. Простые анимации на JavaScript, если они плохо написаны, часто выполняются плохо. Движок может использовать frame-skipping и другие техники, чтобы сохранить производительность на таком высоком уровне .
  3. Позволяет браузеру контролировать последовательность анимации, тем самым оптимизируя производительность и эффективность браузера. Например, уменьшая частоту обновления кадров анимации в непросматриваемых в данный момент вкладках.

Конфигурирование анимации

Чтобы создать CSS-анимацию вы должны добавить в стиль элемента, который хотите анимировать, свойство animation или его подсвойства. Это позволит вам настроить ускорение и продолжительность анимации, а также другие детали того, как анимация должна протекать. Это не поможет вам настроить внешний вид анимации, который настраивается с помощью @keyframes (en-US), рассматриваемой далее в Определение последовательности анимации с помощью ключевых кадров.

Свойство animation имеет следующие подсвойства:

animation-name

Определяет имя @keyframes (en-US), настраивающего кадры анимации.

animation-duration

Определяет время, в течение которого должен пройти один цикл анимации.

animation-timing-function

Настраивает ускорение анимации.

animation-delay

Настраивает задержку между временем загрузки элемента и временем начала анимации.

animation-iteration-count

Определяет количество повторений анимации; вы можете использовать значение infinite для бесконечного повторения анимации.

animation-direction

Даёт возможность при каждом повторе анимации идти по альтернативному пути, либо сбросить все значения и повторить анимацию.

animation-fill-mode

Настраивает значения, используемые анимацией, до и после исполнения.

animation-play-state

Позволяет приостановить и возобновить анимацию.

Определение последовательности анимации с помощью ключевых кадров

После того, как вы настроили временные свойства (продолжительность, ускорение) анимации, вы должны определить внешний вид анимации. Это делается с помощью двух и более ключевых кадров после @keyframes (en-US). Каждый кадр описывает, как должен выглядеть анимированный элемент в текущий момент.

В то время, как временные характеристики (продолжительность анимации) указываются в стилях для анимируемого элемента, ключевые кадры используют percentage, чтобы определить стадию протекания анимации. 0% означает начало анимации, а 100% её конец. Так как эти значения очень важны, то для них придумали специальные слова: from и to.

Вы также можете добавить ключевые кадры, характеризующие промежуточное состояние анимации.

Примеры

Примечание: Внимание: Примеры ниже не используют префиксов для CSS стилей . Webkit-браузеры и старые версии других браузеров нуждаются в указании префиксов в CSS стилях. Примеры, на которые вы можете кликнуть в своём браузере, также содержат префиксы -webkit-.

Скольжение текста

Этот простой пример анимирует скольжение текста в элементе <p> от правого края окна браузера.

Обратите внимание на то, что анимация может сделать страницу шире, чем окно браузера. Этого можно избежать, поместив элемент, который будет анимироваться, в контейнер и установив ему свойство overflow: hidden.

p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

В стиле для элемента <p> с помощью свойства animation-duration указано, что исполнение анимации от начала до конца должно занять 3 с , и что имя для @keyframes (en-US), описывающей саму анимацию, определено как «slidein».

В элемент <p> можно добавлять и другие пользовательские стили, чтобы как-то украсить его, однако здесь мы хотели продемонстрировать только эффект анимации.

Ключевые кадры определяются с помощью правила @keyframes (en-US). В данном случае мы имеем только два ключевых кадра. Первый при 0% анимации (from). Здесь мы придаём элементу левый отступ в 100% и ширину в 300% (в три раза больше ширины родительского элемента). Это становится причиной того, что при первом кадре анимации заголовок <p> находится за пределами правого края окна браузера .

Второй ключевой кадр (to) определяет конец анимации, т.е (100%). Левый отступ устанавливается равным 0, а ширина 100%. Все выглядит так, будто заголовок <p> приплывает к левому краю окна браузера.

<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

(Обновите страницу, чтобы увидеть анимацию, или щёлкните по кнопке CodePen, чтобы воспроизвести её в окне CodePen)

Добавление других ключевых кадров

Давайте добавим другие ключевые кадры в предыдущий пример. Скажем, мы хотим чтобы размер шрифта заголовка временно увеличивался по мере продвижения влево, а потом возвращался к первоначальному значению . Это легко реализовать с помощью следующего ключевого кадра:

75% {
  font-size: 300%;
  margin-left: 25%;
  width: 150%;
}
p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }

  75% {
    font-size: 300%;
    margin-left: 25%;
    width: 150%;
  }
}
<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

Это говорит браузеру о том, что при 75% выполнения анимации, шрифт должен быть 300%, а ширина 150%.

(Обновите страницу, чтобы увидеть анимацию, или щёлкните по кнопке CodePen, чтобы воспроизвести её в окне CodePen)

Настройка повторения

Чтобы настроить повторение, нужно добавить свойство animation-iteration-count и задать ему значение, равное нужному количеству повторений анимаций . В данном случае давайте установим значение infinite для бесконечного повторения:

p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

Движение текста вправо и влево

Итак, мы настроили повторение, но получили нечто странное: текст при каждом повторении снова «запрыгивает» за край окна браузера. То, чего мы хотим, так это чтобы текст двигался влево и вправо. Этого легко достичь с помощью установки свойству animation-direction значения alternate:

p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}
<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

Использование шорткодов

Шорткод animation полезен для экономии места в коде. Например, правило, которое мы используем в этой статье:

p {
  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

можно заменить на:

p {
  animation: 3s infinite alternate slidein;
}

Примечание: Внимание: подробнее об этом на странице раздела animation

Установка нескольких значений свойствам анимации

CSS-свойство анимации может иметь несколько значений, разделённых запятыми. Это используется, чтобы указать несколько значений анимации в одном правиле и установить разную продолжительность, число повторений и т.д., для различных анимаций. Рассмотрим несколько примеров, чтобы увидеть разницу.

В первом примере у свойства имени анимации установлены три значения, у свойств продолжительности и количества повторений — по одному. В этом случае у всех трёх анимаций одинаковая продолжительность и число повторений:

animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 3s;
animation-iteration-count: 1;

Во втором примере установлены три значения для каждого из свойств. В этом случае каждая анимация выполняется с соответствующими по порядку значениями в каждом свойстве, так, например, fadeInOut имеет продолжительность 2.5 с и количество повторений 2, и т.д.

animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s, 1s;
animation-iteration-count: 2, 1, 5;

В третьем примере определены три значения имени анимации, но два значения продолжительности и количества повторений. В случае, когда количества значений недостаточно для каждой анимации, значения берутся циклически от начала до конца. Например, у fadeInOut длительность будет 2.5s, а moveLeft300px — 5s. Значения продолжительности закончились, теперь они берутся сначала — bounce получит продолжительность 2.5s. Значение количества повторений (а также другие указанные свойства) будет определено таким же образом.

animation-name: fadeInOut, moveLeft300px, bounce;
animation-duration: 2.5s, 5s;
animation-iteration-count: 2, 1;

Использование событий анимации

Вы можете получить дополнительный контроль над анимацией, а также полезную информацию о ней, с помощью событий анимации. Эти события, представленные объектом AnimationEvent (en-US), можно использовать, чтобы определить, когда начинается и заканчивается анимация или начинается новая итерация. Каждое событие содержит момент времени, когда оно произошло, а также имя анимации, которая вызвала событие.

Мы будем модифицировать текст, чтобы выводить некоторую информацию о каждом событии анимации. Так мы сможем увидеть, как она работает.

Добавление CSS

Начнём с добавления CSS. Анимация будет длиться 3 секунды, будет называться «slidein», будет повторяться 3 раза, а также значение animation-direction установлено alternate. В ключевых кадрах @keyframes (en-US) установлены такие значения ширины и левого отступа, что элемент будет скользить по экрану.

.slidein {
  -moz-animation-duration: 3s;
  -webkit-animation-duration: 3s;
  animation-duration: 3s;
  -moz-animation-name: slidein;
  -webkit-animation-name: slidein;
  animation-name: slidein;
  -moz-animation-iteration-count: 3;
  -webkit-animation-iteration-count: 3;
  animation-iteration-count: 3;
  -moz-animation-direction: alternate;
  -webkit-animation-direction: alternate;
  animation-direction: alternate;
}

@-moz-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

@-webkit-keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%
  }

  to {
   margin-left: 0%;
   width: 100%;
 }
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%
  }

  to {
   margin-left: 0%;
   width: 100%;
 }
}

Добавление обработчика события анимации

Будем использовать JavaScript для отслеживания всех трёх возможных событий анимации. Следующий код конфигурирует обработчик; мы вызываем его при первой загрузке документа.

var e = document.getElementById("watchme");
e.addEventListener("animationstart", listener, false);
e.addEventListener("animationend", listener, false);
e.addEventListener("animationiteration", listener, false);

e.className = "slidein";

Это довольно стандартный код; вы можете получить дополнительную информацию в документации element.addEventListener(). Последнее, что делает этот код — это установка класса «slidein» для анимируемого элемента; мы делаем это, чтобы запустить анимацию.

Почему? Потому что в нашем случае событие animationstart происходит как только анимация стартует, и это происходит раньше, чем исполняется наш сценарий. Так мы сможем контролировать начало анимации самостоятельно посредством вставки класса «slidein» для анимируемого элемента.

Регистрация событий

События будут передаваться функции listener(), показанной ниже.

function listener(e) {
  var l = document.createElement("li");
  switch(e.type) {
    case "animationstart":
      l.innerHTML = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      l.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      l.innerHTML = "New loop started at time " + e.elapsedTime;
      break;
  }
  document.getElementById("output").appendChild(l);
}

Этот код также очень прост. Этот код следит за event.type, чтобы определить тип события, и добавляет элемент <ul>, чтобы залогировать произошедшее событие.

Вывод, когда анимация закончится, будет выглядеть примерно следующим образом:

  • Started: elapsed time is 0
  • New loop started at time 3.01200008392334
  • New loop started at time 6.00600004196167
  • Ended: elapsed time is 9.234000205993652

Обратите внимание, что время, указанное в выводе, и время, которое мы указали в стилях, не совпадают. Также обратите внимание, что после окончания итерации не посылается событие animationiteration ; вместо него посылается событие animationend.

HTML

Ради полноты картины приведём код разметки HTML. В разметке имеется тег ul, в который и выводится вся информация:

<body>
  <h1 id="watchme">Watch me move</h1>
  <p>This example shows how to use CSS animations to make <code>p</code> elements
  move across the page.</p>
  <p>In addition, we output some text each time an animation event fires, so you can see them in action.</p>
  <ul id="output">
  </ul>
</body>

Смотрите также

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить скорость wifi на телефоне
  • Как изменить скорость wifi на ноутбуке
  • Как изменить скорость wifi адаптера
  • Как изменить скорость ssd диска
  • Как изменить скорость sata

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии