Как украсить сайт на 23 февраля: анимированный танк на SVG (SMIL)

Скоро 23 февраля, поэтому я хочу показать как сделать тематическую анимацию к этому празднику: танк, который ездит внизу сайта и выбрасывает флаг. Интересно это решение тем, что мы практически не будем использовать CSS (только для позиционирования) и вся реализация будет на чистом HTML. Разберемся как собрать руками танк на SVG, а затем анимировать его на SVG-анимации SMIL.

Реализуем сам танк на SVG

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

<style>
  .tank {
    position: absolute;
    bottom: 0;
    z-index: 10;
  }
</style>
<svg height="65" width="100%" class="tank">
     …
</svg>

Высота моего танка получилась 65 пикселей, ездить танк должен по всему экрану, поэтому ширина 100%.Далее используем тег <g>, чтобы сгруппировать все теги танка вместе для дальнейшей совместной анимации.

Рисуем гусеницы

Начнем рисование танка с гусениц. Определим контур:

    <path d="M13 45 
             Q 5 55, 25 65,
             H 90, 
             Q 115 55, 100 45
             " stroke="black" stroke-width="2" fill="#83835c" />

В результате мы должны получить следующее:

Я уже разбирала то, как контур через тег <path> в статье про анимированную гирлянду, но здесь я использовала другие методы. Для начала, мы, как обычно, задаем положение кисти через “M13 45” – это точка от которой мы строим гусеницы. Затем используется кривая Безье с одной контрольной точкой для построения левой части гусениц “Q 5 55, 25 65”. Чтобы полностью понимать, что мы делаем, давайте разберем, как строится эта кривая Безье.

На рисунке показано, как строится кривая по трем точкам. Точка mx, my – это та точка, где сейчас находится кисть, мы это определили задава “M13 45”. Дальше идет команда, определяющая, что мы начинаем рисовать кривую Безье “Q”. После этого мы указываем контрольную точку x1, y1, задающую искривление кривой, и в конце точку x, y, в которой заканчивается кривая.После этого нам нужно продолжить линия прямо горизонтально, для этого есть короткая команда “H 90”, которая говорит, что мы продолжаем от той точки, где сейчас находится кисть в горизонталь на 90 пикселей. По сути мы просто меняем координату x. Далее мы снова используем кривую Безье, чтобы завершить рисование гусениц.Когда само основание готово, нам нужно добавить кружочки, имитирующие гусеницы. Как рисовать кружки я тоже разбирала в статье анимированная гирлянда на чистом HTML и CSS. Для этого мы просто создаем набор circle и располагаем их в нужных местах, чтобы получились гусеницы. Я выбрала вот такие позиции:

…
    <circle cx="20" cy="52" r="5" />
    <circle cx="35" cy="55" r="5" />
    <circle cx="50" cy="55" r="5" />
    <circle cx="65" cy="55" r="5" />
    <circle cx="80" cy="55" r="5" />
    <circle cx="95" cy="53" r="5" />
…

Теперь мы получаем вот такой результат готовых гусениц:

Рисуем корпус танка

Над гусеницами нам нужно построить корпус танка, для этого я использую несколько тегов <polygon>. Для начала рассмотрим как этот тег использовать.

В атрибуте points указываются все координаты точек, которые описывают нужный полигон. Для построения корпуса танка нам нужно построить две трапеции, дуло в виде прямоугольника и небольшую полоску сверху в виде люка. Я подобрала нужные координаты и получился такой результат:

На этом сам танк готов. Теперь давайте сделаем анимацию движения. Я хочу чтобы танк выезжал из левой части экрана и уезжал за правую.

Анимация движения танка

Для анимации движения танка мы будет использовать тег animateMotion. Но для начала нам нужно поставить id=”tank” тегу g, в который обернуты теги танка. Код анимации с комментариями:

<animateMotion 
     xlink:href="#tank"   <!-- связываем анимацию с тегом танка  --> 
     dur="6s"                 <!-- указываем длительность анимации в 6 секунд  -->
     repeatCount="indefinite"   <!-- бесконечный повтор анимации-->
     path="M-117, 0 H1500"     <!-- рисуем траекторию по которой будет двигаться танк -->
     />

В атрибуте path вы можете указать любую траекторию, которую сможете нарисовать. Я выбрала траекторию, которая начинается за границей экрана и продолжается на 1500 пикселей вправо. После этого танк начинает двигаться.

Анимация флажка

Я хочу, чтобы танк просто выезжал из левого края, а затем выстреливал флажок из дула. Флажок я решила сделать с георгиевской ленточкой, а нарисовать его с помощью простых линий. Для анимации просто меняем координаты линии. Для каждой координаты x1, y1, x2 и y2 создаем свою анимацию. Для анимации используем тег animate, его просто размещаем внутри линии и она автоматически прикрепляется к ней. Я покажу на примере черенка флажка, как это делается, а сам флажок делается из трех черных и двух оранжевых линий по такому же принципу. Все что нужно это подобрать нужные координаты.

<line x1="68" y1="25" x2="110" y2="19" stroke="black" stroke-width="3">       
      <animate 
               attributeName="x1" 
               from="68" 
               to="108" 
               values="68; 108; 108" 
               keyTimes="0; 0.5; 1" 
               dur="6s" 
               repeatCount="indefinite"  />
      <animate 
               attributeName="y1" 
               from="25" 
               to="19" 
               values="25; 19; 19" 
               dur="6s"  
               keyTimes="0; 0.5; 1" 
               repeatCount="indefinite"  />
      <animate 
               attributeName="x2" 
               from="110" to="160" 
               values="110; 160; 160" 
               keyTimes="0; 0.5; 1" 
               dur="6s" 
               repeatCount="indefinite"  />
     <animate 
               attributeName="y2" 
               from="19" 
               to="8" 
               values="19; 8; 8" 
               keyTimes="0; 0.5; 1" 
               dur="6s" 
               repeatCount="indefinite"  />
    </line>

Разберем основные моменты:

attributeName – указывает какой атрибут мы анимируем
from и to – показывают с какого значение на какое должно изменится значение этого атрибута
values – показывает все значения, которые должна пройти анимация
keyTimes – показывает какое значение в какой момент времени в процентах должно быть применено. То есть, мы хотим чтоб флажок выбросился и после этого завис до конца анимации в этом положении, а затем пропал в тот момент, когда танк уйдет за экран. Мы указываем, что в 0% времени анимации значение атрибута x1 должно быть 68, а к 50% времени оно должно измениться на 108, затем до 100% времени анимации оно должно оставаться 108.
dur – длительность анимации, совпадает в длительностью анимации танка
repeatCount – повторение анимации

На таком же принципе делаем сам флажок и решение готов. Конечный код вы можете посмотреть и скопировать ниже.

Добавить комментарий