Руководство по анимации SVG (SMIL)
Графика SVG может быть анимирована с помощью элементов анимации. Эти элементы были первоначально определены в спецификации анимации SMIL ; к ним относятся:
- <animate> - позволяет задать анимацию для скалярных атрибутов и свойств на определенный промежуток времени;
- <set> - является удобным сокращением для анимации, с помощью которого можно присваивать значения анимации нечисловым атрибутам и свойствам, таким как свойства видимости;
- <animateMotion> - передвигает элемент вдоль траектории движения;
- <animateColor> - изменяет значение цвета конкретных атрибутов или свойств за определенный промежуток времени. Обратите внимание, что использование элемента <animateColor> является устаревшей практикой по сравнению с использованием элемента анимации для определения свойств, которые могут принять значения цвета. Даже при том, что он по-прежнему присутствует в спецификации SVG 1.1 , в этой же спецификации было четко задекларировано, что он устарел; из спецификации SVG-2 он был полностью удален.
В дополнение к элементам анимации, определенным в спецификации SMIL, SVG включает в себя расширения, совместимые со спецификацией SMIL -анимации; эти расширения включают атрибуты, которые расширяют функциональные возможности элемента <animateMotion> и дополнительных элементов анимации.
Расширения SVG включают:
- <animateTransform> - позволяет задавать анимацию одному из атрибутов преобразований SVG за определенный промежуток времени, например для атрибута transform ;
- path (атрибут) - позволяет любой функции синтаксиса данных пути SVG быть указанной в атрибуте пути к элементу animateMotion ( SMIL-анимация позволяет использовать в атрибуте пути только подчиненный набор синтаксиса данных пути SVG ).
Мы поговорим об animateMotion в следующем разделе:
- <mpath> - используется в сочетании с элементом animateMotion для ссылки на траекторию движения, которая должна использоваться, как и траектория движения. Элемент mpath включается внутри элемента animateMotion , перед закрывающим тегом;
- keypoints ( атрибут ) - используется в качестве атрибута для animateMotion , чтобы обеспечить точный контроль скорости перемещения анимированного элемента вдоль траектории;
- rotate ( атрибут ) - используется в качестве атрибута для animateMotion , чтобы контролировать поворачивается ли объект автоматически таким образом, чтобы его точки х-оси поворачивались в том же ( или обратном ) направлении, что и направление касательного вектора пути движения. Этот атрибут является ключом к созданию движения вдоль пути, которое будет работать так, как вам нужно. Подробнее об этом в разделе animateMotion .
SVG анимация может быть похожа на анимацию и переходы CSS в силу своей природы. Создаются кифреймы, все движется, изменяются цвета и т.д. Тем не менее, она может сделать кое-что, чего CSS -анимация не может. Об этом я расскажу в этом руководстве.
Для чего используется SVG-анимация?
Для SVG можно задать стили и анимацию с помощью CSS ( слайдов ). В принципе, любая анимация преобразования или перехода, которая может быть применена к элементу HTML , также может применяться к элементу SVG . Но существуют некоторые свойства SVG , которые не могут быть анимированы через CSS , однако это можно сделать непосредственно через SVG .
Траектория SVG , например, определяется набором данных ( атрибут d="" ), которые определяют форму этой траектории. Эти данные могут быть изменены и анимированы через SMIL , но не через CSS .
Все потому, что SVG элементы описаны с помощью набора атрибутов, известных как атрибуты представления SVG . Некоторые из этих атрибутов могут быть установлены, измены и анимированы с использованием CSS , а другие нет.
Таким образом, многие эффекты анимации на текущий момент просто не могут быть реализованы с помощью CSS . Этот пробел может быть восполнен либо с помощью JavaScript , либо с помощью декларативной SVG анимации, полученной из SMIL .
Если вы предпочитаете использовать JavaScript , я рекомендую вам snap.svg Дмитрия Барановского, который называют " jQuery для SVG ".
Или, если вы предпочитаете более изысканный подход к анимации, вы можете использовать элементы SVG , которые мы рассмотрим в этом руководстве!
Еще одно преимущество SMIL над JS -анимацией заключается в том, что JS не работает, когда SVG встроен в качестве img или используется в качестве background-image в CSS . SMIL -анимация работает в обоих случаях ( или ожидается, что вскоре будет поддерживаться браузерами ).
На мой взгляд, это существенное преимущество. Вы можете найти для себя и другие причины остановить свой выбор именно на SMIL . Эта статья представляет собой руководство, которое поможет вам начать работу со SMIL уже сегодня.
Поддержка браузеров и альтернативные вариантыSMIL довольно широко поддерживается браузерами. Он работает во всех браузерах за исключением Internet Explorer и Opera Mini . Чтобы получить исчерпывающую информацию относительно поддержки браузерами, вы можете ознакомиться с таблицей совместимости или "Могу ли использовать" .
Если вам нужно обеспечить запасной вариант для SMIL анимации, вы можете проверить наличие поддержки браузера с помощью Modernizr . Если SMIL не поддерживается, вы можете обеспечить своего рода альтернативный вариант ( JavaScript анимация, альтернативный подход и т.д .).
Указание цели анимации с помощью xlink:hrefНезависимо от того, какой из четырех элементов анимации вы выберете, вы должны указать целевую анимацию, определяемую этим элементом.
Чтобы указать цель, вы можете использовать атрибут xlink:href . Атрибут принимает URI -ссылку на элемент, который является объектом данной анимации, и который, следовательно, будет изменяться в течение определенного времени. Целевой элемент должен быть частью текущего фрагмента SVG документа:
Если до этого вы имели дело с элементами анимации SVG , они, вероятно, встречались вам как вложенные элементы внутри другого элемента, который они должны анимировать. Это предусматривается спецификацией.
Если использование атрибута xlink:href не предусмотрено, то целевым элементом будет родительский элемент первого следующего вверх уровня от текущего элемента анимации:
Таким образом, если вы захотите " инкапсулировать " анимацию в элемент, к которому она применяется, вы можете сделать именно это. А если вы хотите, чтобы элементы анимации хранились в другом месте документа, вы можете сделать это, при этом указав цель для каждого элемента анимации с помощью xlink:href - оба способа работают одинаково корректно.
Указание целевого свойства анимации с помощью attributeName и attributeTypeВсе элементы анимации также взаимодействуют еще с одним атрибутом: attributeName. attributeName используется для указания имени атрибута, который вы анимируете.
Например, если вы хотите задать анимацию для позиции центра <circle> по оси х, вы делаете это, указав cx в качестве значения атрибута attributeName .
attributeName принимает только одно значение, но не список значений, так как вы можете анимировать только один атрибут за один раз. Если вы хотите задать анимацию более чем для одного атрибута, необходимо определить более одного эффекта анимации для этого элемента.
Это то, что мне не совсем нравится, и, я думаю, что в этом CSS как раз имеет преимущество над SMIL . Но опять же, из-за значений, возможных для других атрибутов анимации ( об этом чуть далее ), имеет смысл определять только одно имя атрибута за раз, в противном случае, если определить еще несколько значений атрибутов, работать с ними станет слишком сложно.
При указании имени атрибута, вы можете добавить префикс XMLNS ( сокращение от пространство имен XML ) для обозначения пространства имен атрибута.
Пространство имен также можно задать с помощью атрибута attributeType . Например, некоторые атрибуты принадлежат пространству имен CSS (что означает, что атрибут может быть также найден как свойство CSS ), другие - только пространству имен XML .
Здесь приведена таблица, где перечислены эти атрибуты. В данной таблице описаны не все атрибуты SVG , только те из них, которые могут быть установлены с помощью CSS . Некоторые уже сегодня доступны в качестве свойств CSS .
Если значение для attributeType четко не установлено или установлено auto, браузер должен сначала произвести поиск по списку свойств CSS , и если ничего не найдено - поиск в пространстве имен XML элемента по умолчанию.
Например, следующий фрагмент задает анимацию для непрозрачности прямоугольника SVG . Поскольку атрибут opacity также доступен как свойство CSS , для attributeType установлено пространство имен CSS :
Мы рассмотрим другие атрибуты анимации в следующих примерах. Все атрибуты анимации являются общими для всех элементов анимации, если обратное не указано отдельно.
Давайте начнем с перемещения круга из одного места в другое. Мы собираемся сделать это, изменив значение его атрибута cx ( который определяет положение его центра по оси х ).
Для этого мы используем элемент <animate>. Данный элемент используется для анимирования одного атрибута один раз. Атрибуты, которые принимают числовые значения и значения цветов, как правило, анимируются с помощью <animate>. Список атрибутов, которые могут быть анимированы, вы можете найти в этой таблице .
Для того чтобы произвести изменение значения от одной величины к другой в течение определенного периода времени, используются атрибуты from, to и dur . В дополнение к ним вы также можете указать, когда анимация должна запускаться - для этого используется атрибут begin :
В приведенном выше примере мы определили круг, а затем вызывали анимацию для этого круга. Центр круга перемещается из исходного положения с координатами 50 единиц в точку с координатами 450 единиц по оси х.
Для атрибута begin мы устанавливаем значение click . Это означает, что круг будет начинать перемещаться после нажатия курсора мыши. Вы можете установить для этого атрибута определенное время. Например, begin="0s" будет запускать анимацию сразу после загрузки страницы.
Вы можете задержать старт анимации, установив положительное значение времени, например, begin="2s" будет запускать анимацию через две секунды после нагрузки страницы.
Еще более интересно, что вы можете определить для атрибута begin такое значение, как click + 1s , которое будет запускать анимацию через одну секунду после клика мышью!
К тому же, вы можете использовать другие значения, которые позволяют синхронизировать анимацию без точного расчета продолжительности и задержки других анимаций. Подробнее об этом позже.
Атрибут dur аналогичен атрибуту CSS animation-duration .
Атрибуты from и to аналогичны кифреймам from и to блока анимации @keyframe CSS :
Атрибут fill ( который, к сожалению, назван так же, как другой атрибут fill, определяющий цвет заливки элемента ) похож на свойство animation-fill-mode , которое определяет, должен ли элемент возвращаться к исходному состоянию после завершения анимации.
Его значения в SVG аналогичны тем, которые используются в CSS , за исключением использования различных имен:
- freeze: Значение, которое указывает заморозить состояние эффекта на том, которое было при последнем значении продолжительности анимации. Эффект анимации " замораживается " до тех пор, пока документ не будет закрыт ( или пока анимация не будет перезапущена );
- remove: Эффект анимации удаляется ( больше не применяется ), по завершению действия анимации, заданного продолжительностью. После завершения анимации она больше не применяется к целевому элементу ( если только анимация не будет перезапущена ).
Попробуйте изменить значения в этой демо-версии, чтобы увидеть, как это повлияет на анимацию: HTML:
Атрибут by используется, чтобы указать относительное смещение для анимации. Как следует из названия, вы можете использовать его, чтобы указать значение, которое будет задавать изменение анимации.
Данный эффект заметен, в основном только когда вы изменяете продолжительность анимации от одного цикла к другому, подобно тому, как работает функция CSS steps().
В SVG эквивалентом функции CSS steps() является calcMode="discrete" . Мы доберемся до атрибута calcMode="discrete" чуть позже.
Перезапуск анимации с помощью restartВам может понадобиться заблокировать перезапуск анимации, пока она активна. Для этого в SVG предусмотрен атрибут restart.
Вы можете установить для него одно из трех возможных значений:
- always: Анимация может быть перезапущена в любой момент. Это значение по умолчанию;
- whenNotActive: анимация может быть перезапущена, только когда она неактивна ( то есть по завершении периода продолжительности анимации ). Попытки перезапустить анимацию во время действия анимации игнорируются;
- never: Элемент не может быть перезапущен, пока не перезагружен его родительский контейнер. ( В случае с SVG, так как родительским контейнером является SVG -фрагмент документа, то анимация не может быть перезапущена, пока не перезагружен документ ).
Предположим, мы хотим задать анимацию для положения и цвета круга, таким образом, чтобы изменение цвета происходило в конце анимации перемещения. Мы можем сделать это, установив значение begin для анимации изменения цвета равным длительности анимации перемещения; так мы, как правило, делаем в CSS .
Однако SMIL имеет отличную функцию обработки событий. Я уже упоминала, что атрибут begin принимает такие значения, как click + 5s . Это значение называется " значением события ", и в данном случае оно состоит из события, за которым следует " значение часов ".
Самая интересная здесь вторая часть - " значение часов ". Почему оно не называется просто " значение времени "? Ответ заключается в том, что вы можете использовать это значение буквально, как часы : вы можете установить " 10min " или " 01:33 ", что будет эквивалентно " 1 минуте и 33 секундам ", или даже " 02:30:03 " ( 2 часа, 30 минут и 3 секунды ). На момент написания этой статьи, значения часов не полностью реализованы в большинстве браузеров.
Так что, если бы в предыдущей демонстрации мы использовали click + 01:30 , то в случае реализованной поддержки браузером, анимация бы запустилась через 1 минуту и 30 секунд после клика мыши.
Еще один вид значения, которое может принимать этот атрибут - это ID другой анимации, за которым следует обозначение события. Если у вас есть два ( или более ) эффекта анимации ( независимо то того, применяются ли они к одному элементу или нет! ), и вы хотите синхронизировать их таким образом, чтобы один из них начинался в зависимости от стадии исполнения другого, вы можете сделать это, даже не зная продолжительность другой анимации.
Например, в следующем примере, синий прямоугольник начинает движение через 1 секунду после начала анимации круга. Это делается путем предоставления каждому элементу анимации ID , а затем использования этого ID с событием begin , как это показано в следующем коде:
begin="circ-anim.begin + 1s" указывает браузеру начать анимацию прямоугольника через 1 секунду после начала анимации круга.
Вы можете увидеть все это в этой демонстрации:
РезультатВы также можете запустить анимацию прямоугольника по завершении анимации круга, используя событие end :
Вы можете даже запустить ее до завершения анимации круга:
Повторяющаяся анимация с помощью repeatCountЕсли вы хотите запустить анимацию более чем один раз, вы можете сделать это с помощью атрибута repeatCount . Вы можете указать, сколько раз вы хотите ее повторить или использовать ключевое слово indefinite , чтобы повторять анимацию бесконечно.
Таким образом, если мы хотим повторить анимации круга два раза, код должен выглядеть следующим образом:
Вы можете увидеть это в демонстрации. Я установила количество повторений для круга - 2 и для квадрата indefinite . HTML:
Обратите внимание, что анимация рестартует с первоначального значения from , а не со значения, которого она достигла по завершении цикла. К сожалению, SMIL не позволяет нам задать путь туда и обратно между начальным и конечным значениями, как мы можем сделать это с помощью CSS анимации.
В CSS свойство animation-direction определяет, должна ли анимация проигрываться в обратном направлении или каждый цикл стартует с нулевой точки.
Значение animation-direction: alternate означает, что четные циклы анимации проигрываются в обычном направлении, а нечетные воспроизводятся в обратном направлении. Это означает, что первый цикл будет проигрываться от начала до конца, а второй - с конца обратно к началу, третий цикл снова будет проигрываться от начала к концу и так далее.
Чтобы сделать это в SMIL , вам придется использовать JavaScript , чтобы изменять значения атрибутов from и to . Джон МакПартленд из Big Bite Creative некоторое время назад опубликовал статью , в которой описал, как он сделал это для анимации иконок меню, над которой он работал.
Вот отличная, простая анимация, повторяющаяся бесконечное количество раз, с использованием задержки, созданная Майлзом Иламом :
Ограничение времени повторения анимации с помощью repeatDurБесконечное выполнение анимации может раздражать или портить дизайн страницы, если это продолжается в течение длительного времени.
Поэтому вам может оказаться весьма кстати иметь возможность ограничить повторение анимации определенным периодом времени, и остановить повторение анимации через некоторое время после загрузки документа - это называется время презентации.
Время презентации указывает положение на шкале времени данного фрагмента документа, связанной с моментом начала всего документа. Оно задается с помощью атрибута repeatDur .
Его синтаксис похож на значение часов, но вместо того, чтобы отсчитывается от других событий анимации или событий взаимодействия, в данном случае время отсчитывается от начала ( загрузки ) документа.
Например, следующий фрагмент остановит повторение анимации через 1 минуту и 30 секунд после начала ( загрузки ) документа:
А это демо, иллюстрирующее данный атрибут: HTML:
Синхронизация анимации в зависимости количества повторенийТеперь давайте вернемся обратно к синхронизации между двумя анимациями. В самом деле, в SMIL можно синхронизировать анимации таким образом, чтобы одна анимация запускалась в зависимости от того, сколько раз была повторена другая.
Например, вы можете начать анимацию после n-го повторения другой, плюс или минус определенное количество времени, которое вы также можете задать.
В следующем примере анимация прямоугольника запускается на втором повторении анимации круга:
Синхронизация в зависимости от количества повторений в настоящее время реализована не во всех браузерах, поэтому, для этого раздела, к сожалению, демо-версия не приводится.
Управление значениями кифреймов анимации: keyTimes и valuesВ CSS мы можем указать значения, которые должно принимать анимируемое свойство в определенном кифрейме во время проигрывания анимации.
Например, если вы задаете анимацию для смещения элемента слева, вместо указания изменения смещения непосредственно от 0 до 300, вы можете анимировать его так, что смещение принимает определенные значения в определенном фрейме следующим образом:
0%, 20%, 80% и 100% - это фреймы анимации, а значения в блоке каждого фрейма являются значениями для каждого из них. Описанный выше эффект является одним из элементов анимации подпрыгивающего мячика.
В SMIL вы можете управлять значениями для кифреймов аналогичным образом, но сам синтаксис совершенно другой.
Чтобы указать кифреймы, используется атрибут keyTimes . И, чтобы указать значение свойства анимации для каждого фрейма, используются атрибуты values . Соглашение об именах в SMIL довольно удобное.
Если вернуться к нашему перемещающемуся кругу и использовать значения, аналогичные описанным выше кифреймам CSS , то код будет выглядеть следующим образом:
Что мы сделали?Первое, что нужно отметить - время и промежуточные значения кифреймов задаются в виде списков. Атрибут keyTimes - разделенный точками с запятой список значений времени, используемый для управления этапами анимации. Каждое время в списке соответствует значению в списке атрибутов values , и определяет, когда это значение используется в функции анимации.
Каждое значение времени в списке keyTimes задается как десятичное число от 0 до 1 ( включительно ), представляющее собой пропорциональный сдвиг по времени в проигрывании элемента анимации. Таким образом, keyTimes работает так же, как его аналоги в CSS , за исключением того, что мы определяем его в виде десятичной дроби, а не в процентах.
Ниже приведена демонстрация для данного кода. Нажмите на круг, чтобы запустить анимацию. HTML:
Следует отметить, что, если используется список значений, то анимация будет применяться в соответствии с указанными в нем значениями. В этом случае все атрибуты from, to и by будут игнорироваться.
Управление темпом анимации с помощью пользовательских корректив: calcMode и keySplinesСейчас я снова прибегну к сравнению CSS и SMIL , потому что синтаксис и концепцию SMIL вам будет гораздо проще понять, если вы уже знакомы с анимацией CSS .
В CSS вы можете изменить равномерное проигрывание анимации по умолчанию и указать пользовательскую функцию корректировки, которая будет управлять анимацией с помощью свойства animation-timing-function.
Функция тайминга может определяться одним из нескольких предопределенных ключевых слов или функций cubic b;zier . Последняя может быть создана при помощи инструментов, наподобие этого, разработанного Леей Веру .
В SMIL темп анимации задается с помощью атрибута calcMode . По умолчанию его значение для всех элементов анимации - linear , кроме animateMotion ( мы вернемся к нему позже ). Кроме значения linear , вы можете установить также значения: discrete, paced или spline .
- discrete указывает, что функция анимации переходит от одного значения к другому без интерполяции. Это похоже на функцию CSS steps() ;
- paced похоже на значение linear , кроме того, что при этом игнорируются любые промежуточные значения, и изменение времени выполнения анимации определяется в keyTimes ;
- spline производит интерполяцию от одного значения в списке значений к другому в соответствии с функцией времени, определяемой кубическим сплайном Безьера. Точки сплайна определяются в атрибуте keyTimes , а точки перехода для каждого интервала определяются в атрибуте keySplines .
Вы, наверное, заметили, что я упомянула новый атрибут: keySplines . Что же делает атрибут keySplines ?
Опять же это аналогично CSS .
В CSS вы можете указать темп анимации внутри каждого кифрейма, вместо указания одного темпа анимации для всей анимации. Это дает вам больше контроля над тем, как протекает каждый кифрейм анимации. Примером использования этой функции является создание эффекта прыгающего мячика. Кифреймы для него могут выглядеть следующим образом:
Вместо функции корректировки мы можем использовать соответствующие функции cubic-bezier :
- ease-in = cubic-bezier(0.47, 0, 0.745, 0.715);
- ease-out = cubic-bezier(0.39, 0.575, 0.565, 1)
Давайте начнем с определения ключевых интервалов времени и списка значений для нашего оранжевого круга, чтобы создать тот же эффект подпрыгивающего мячика:
Анимация будет запускаться после нажатия мышью на элемент, и замораживаться, как только он достигнет конечного значения. Далее, для того, чтобы задать темп каждого ключевого кадра, мы добавим атрибут keySplines .
Атрибут keySplines принимает набор контрольных точек b;zier , связанных со списком keyTimes , определяющим кубическую функцию Безье, которая управляет интервалами с разным темпом. Значение атрибута представляет собой разделенный точками с запятой список описаний контрольных точек.
Каждое описание контрольной точки представляет собой набор из четырех значений: x1 y1 x2 y2, описывающий координаты контрольных точек b;zier для одного сегмента времени. Их значение должно находиться в диапазоне от 0 до 1, и для calcMode должно быть установлено значение spline , иначе атрибут игнорируется.
Вместо использования в качестве значений функции cubic-bezier, keySplines принимает координаты двух контрольных точек, которые используются для построения кривой. Данные контрольные точки вы можете видеть на приведенном ниже скриншоте, взятом из инструмента Леи.
На скриншоте также показаны координаты каждой точки, каждое значение координат имеет тот же цвет, что и точка, которую они описывают. Что касается атрибута keySplines , то именно эти значения мы будем использовать, чтобы определить темп для каждого кифрейма анимации.
В SMIL эти значения можно разделять либо запятыми с дополнительным пробелом, либо просто пробелами. Значения keyTimes , которые определяют соответствующий сегмент, являются " опорными точками " b;zier , а значения keySplines являются контрольными точками. Таким образом, контрольных точек должно быть задано на одну меньше, чем keyTimes :
Если мы вернемся к примеру подпрыгивающего мячика, координаты контрольной точки для функций ease-in и ease-out показаны на следующих изображениях:
Таким образом, переведя все это в элемент анимации SVG , мы получим следующий код:
Ниже приводится демо-версия, но убедитесь, что вы запустили ее в Firefox , а не в Chrome , потому что в его последней версии найден а ошибка, из-за которой демо-версия не будет работать корректно:
Если вы хотите указать только общую функцию корректировки скорости для всей анимации, без промежуточных значений, вы все равно должны указать кифреймы, используя атрибут keyTimes , однако вам будет достаточно задать только начальный и конечный кифреймы, а именно 0; 1 - без промежуточных values .
Добавляемые и накапливающие анимации: additive и accumulateИногда нам нужно определить анимацию, которая начинается там, где закончилась предыдущая анимация; или анимацию, которая использует накопительную сумму предыдущих анимаций в качестве значения для начала воспроизведения. Для этого в SVG существуют два атрибута, называющиеся соответствующим образом: additive и accumulate .
Предположим, у вас есть элемент, ширину которого вы хотите " нарастить ", или линия, для которой вы хотите увеличить длину. Или, предположим, у вас есть элемент, который вы хотите перемещать шаг за шагом, через определенные интервалы. Эта функция особенно полезна для повторяющейся анимации.
Как и для любой другой анимации, вам нужно указать значения from и to . В то же время, когда вы устанавливаете для атрибута additive значение sum, каждое из этих значений будет связано с первоначальным значением анимируемого атрибута.
Итак, вернемся к нашему кругу. Для него начальное положение cx равно 50 . Если вы устанавливаете значения from="0" to="100" , то ноль фактически означает начальное значение 50, а 100 - начальное значение 50+100. То есть на практике получается, что вы устанавливаете "from="50" to="150" .
Сделав это, мы получим следующий результат:
Это все, что делает атрибут additive . Он просто определяет, будут ли значения from и to связаны с текущим значением атрибута или нет. Атрибут принимает одно из двух значений: sum и replace .
Последнее значение присваивается по умолчанию, и это, как правило, означает, что заданные значения from и to заменяют текущие / исходные значения, что в конечном итоге может привести к резкой смене позиции анимируемого элемента в начале анимации.
( Попробуйте в приведенном выше примере заменить sum на replace , и вы увидите, что получится ).
Однако, что если мы хотим, чтобы значения добавлялись таким образом, чтобы второй цикл анимации начинался там, где закончился первый? В этом нам поможет атрибут accumulate .
Атрибут accumulate контролирует, учитывается ли предыдущее конечное значение атрибута. По умолчанию его значение none , это означает, что, когда анимация повторяется, то это происходит с самого начала, не учитывая окончания предыдущей итерации.
Однако вы можете установить его на sum . Это будет означать, что каждый новый цикл анимации связан с тем, где завершился предыдущий цикл.
Таким образом, если мы вернемся к предыдущей анимации и укажем accumulate="sum" , мы получим следующий результат: HTML:
Имейте в виду, что атрибут accumulate игнорируется, если значение целевого атрибута не поддерживает добавление, или если элемент анимации не повторяется. Он также будет игнорироваться, если функция анимации задается только с одним атрибутом to .
Указание окончания анимации с помощью endКроме определения того, когда анимация должна начинаться, можно также указать, когда она должна заканчиваться через атрибут end . Например, вы можете установить, чтобы анимация повторялась бесконечно, а затем остановить ее, когда начинается анимация другого элемента.
Атрибут end принимает значения, аналогичные тем, которые имеет атрибут begin . Вы можете указывать абсолютные или относительные значения времени / интервалы, значения повторений, значения событий и т.д.
Например, в следующей демонстрации оранжевый кружок медленно перемещается в течение 30 секунд на другую сторону холста. Зеленый круг также анимирован, но анимация запускается только тогда, когда вы нажмете на него.
Анимация оранжевого круга закончится, когда начнется анимация зеленого круга - таким образом, когда вы нажмете на зеленый круг, оранжевый круг остановится.
Конечно, такую же синхронизацию анимации можно осуществить для двух анимаций, применяемых к одному элементу. Например, предположим, что мы устанавливаем анимацию цвета круга, при которой цвет бесконечно меняется от одного значения к другому.
А потом анимацию, задающую перемещение круга при нажатии на него курсором мыши. Сейчас мы установим, чтобы изменение цвета прекращалось после того, как мы кликаем мышью на элемент, и он начинает двигаться. HTML:
Определение интервалов анимации с использованием нескольких значений begin и end
В самом деле, оба атрибута и begin , и end принимают разделенный запятыми список значений. Каждое значение в атрибуте begin будет иметь соответствующее значение в атрибуте end , что образует активные и не активные интервалы анимации.
Это можно представить, как движущийся автомобиль, у которого колеса то активны, то не активны какое-то время, в зависимости от того, движется ли автомобиль или стоит на месте.
Вы даже можете создать анимацию движущегося автомобиля, применив соответствующие эффекты: один для перемещения автомобиля или движения его вдоль пути, который использует добавляемую и накапливаемую анимацию; второй - для вращения колес в интервалах, которые будут синхронизированы с перемещением.
Примером установки нескольких значений времени начала и конца анимации ( т.е. интервалов ) является следующая демонстрация, где прямоугольник поворачивается, исходя из определенных интервалов, переходя от активного состояния в не активное. ( Перезапустите демонстрацию, если вы пропустили анимацию ). HTML:
Следует отметить, что в приведенном выше примере я использовала элемент <animateTransform>, чтобы задать вращение прямоугольника. Мы поговорим об этом элементе более подробно в следующем разделе.
Также отмечу, что, даже если вы установите для repeatCount значение indefinite , оно будет перекрыто значениями end , и анимация не будет повторяться бесконечно.
Ограничение продолжительности действия элемента с помощью min и maxТак же, как вы можете ограничить количество или время повторений анимации, вы можете ограничить и продолжительность действия анимации.
Атрибуты min и max указывают минимальное и максимальное значение продолжительности анимации соответственно. Они дают нам возможность регулировать нижний и верхний предел продолжительности действия элемента. Оба атрибута принимают значения часов.
min указывает величину минимального значения продолжительности действия анимации, замеряемую по времени действия элемента. Значение этого атрибута должно быть больше или равно 0 ( значение по умолчанию, при котором продолжительность действия вообще не ограничивается ).
В max значение часов указывает величину максимального значения продолжительности действия, измеряемую по времени действия элемента. Его значение также должно быть больше 0. Значение по умолчанию для max - indefinite . Оно не ограничивает продолжительность действия вообще.
Если указаны оба атрибута, то значение max должно быть больше или равно значению min . Если это требование не выполняется, то оба атрибута игнорируются.
Но что же определяет продолжительность действия элемента? Мы упомянули ранее, что существует продолжительность повторений анимации, это кроме " простой продолжительности ", которая является продолжительностью анимации без повторения ( указывается с помощью dur ).
Так как все это работает вместе? Что является более приоритетным? И как насчет атрибута end , он переназначает значения или просто заканчивает анимацию?
Все это работает следующим образом. Браузер сначала вычисляет продолжительность действия на основе значений dur, repeatCount, repeatDur и end . После этого запускается вычисление продолжительности согласно указаниям значений min и max .
Если результат первого этапа вычислений находится в пределах интервала, вычисляемого во время второго этапа, то продолжительность, рассчитанная первой, остается в силе и не изменяется. В противном случае возможны два сценария:
- Если вычисленная первой продолжительность больше, чем значение max, продолжительность действия элемента определяется равной значению max ;
- Если вычисленная первой продолжительность меньше, чем значение min , продолжительность действия элемента будет равна значению min и поведение элемента заключается в следующем;
- Если продолжительность повторений ( или простая продолжительность, если элемент не повторяется ) элемента больше, чем min , то элемент проигрывается стандартное время ( включающее min ) продолжительности действия;
- В противном случае элемент проигрывается стандартное время продолжительности повторений ( или простой продолжительности, если элемент не повторяется ), а затем замораживается и не выводится вовсе, в зависимости от значения атрибута fill .
Это подводит нас к вопросу о том, как браузер фактически вычисляет продолжительность действия. Для краткости я не буду вдаваться в подробности.
Но спецификация содержит очень подробную таблицу, в которой приведены различные комбинации атрибутов dur , repeatCount, repeatDur и end и то, как будет определяться продолжительность действия анимации, исходя из каждой комбинации.
Вы можете ознакомиться с этой таблицей и получить дополнительную информацию из этого раздела спецификации .
Наконец, если для элемента определен запуск до начала родительского элемента ( например, просто с помощью отрицательного значения смещения ), минимальная продолжительность будет определяться рассчитанным на первом этапе значением, и не будет входить в интервал действия родительского элемента.
Это означает, что значение min не будет иметь заметного влияния на протекание анимации элемента.
Пример <animate>: трансформация контуровОдним из атрибутов, которые могут быть анимированными через SMIL ( но для которых нельзя задать анимацию через CSS ), является атрибут из <path> SVG - d ( сокращенно от "data" - данные ).
Атрибут d содержит данные, которые определяют контуры формы или фигуры, которую вы создаете. Эти данные контура состоят из набора команд и координат, которые указывают браузеру, где и как рисовать точки, дуги и линии, которые составляют окончательный контур.
Анимируя этот атрибут, мы можем трансформировать контуры SVG и создавать эффекты метаморфоз фигур .
Но, для того, чтобы иметь возможность трансформироваться фигуры, начальная, конечная и все промежуточные фигуры должны иметь одинаковое количество вершин / точек, и они должны появляться в том же порядке. Если количество вершин разных фигур не совпадает, анимация не будет работать.
Причиной этого является то, что трансформация фигур производится на самом деле через перемещение вершин и интерполяцию их позиций. Так что если одна вершина отсутствует или не соответствует общему порядку вывода, контур не может быть интерполирован.
Чтобы анимировать контур SVG , нам нужно указать для атрибута attributeName значение d , а затем установить значения from и to , которые определяют начальную и конечную фигуры. Вы также можете использовать атрибут values , чтобы определить любые промежуточные значения, которые должен принимать контур при трансформации.
Для краткости, я не буду вдаваться в подробности относительно того, как это сделать. Вместо этого, вы можете прочитать эту прекрасную статью Ноа Блона , в которой он объясняет, как он создал трансформирующуюся фигуру, использую <animate>. Вот демонстрация созданной Ноа анимации: HTML: