Плавные строки SVG

SVG

Без лишних слов, давайте начнем с визуализаций:

Разве это не круто?Этот эффект достигается с помощью SVG+CSS.Теперь давайте разберем реализацию этой анимации.


Предварительные знания

Несколько вариантов использования тегов SVG, которые необходимо освоить

  • <path>

    инструкция параметр иллюстрировать
    M x y Переместите кисть в точку (x, y)
    L x y Кисть рисует отрезок от текущей точки до точки (x,y)
    H x Кисть рисует горизонтальный отрезок от текущей точки до точки (x,y0)
    V y Кисть рисует вертикальный отрезок от текущей точки до точки (x0,y)
    A rx ry x-axis-rotation large-arc-flag sweep-flag x y Кисть рисует дугу из текущей точки в точку (x,y)
    C x1 y1, x2 y2, x y Кисть рисует кубическую кривую Безье от текущей точки до точки (x,y)
    S x2 y2, x y Специальная версия кубической кривой Безье (без первой контрольной точки)
    Q x1 y1, x y нарисовать квадратичную кривую Безье в точку (x, y)
    T x y Специальная версия квадратичной кривой Безье (контрольные точки опущены)
    Z нет параметров Нарисовать замкнутую фигуру.Если для атрибута d не указана команда Z, вместо замкнутой фигуры рисуется отрезок.

    Всего существует 9 инструкций для пути, но мы используем только две из них для реализации нашей анимации: A и Z, поэтому здесь мы сосредоточимся на инструкции A!

    Команда рисования дуги: A rx ry x-axis-rotation большой-дуговой-флаг флаг развертки x y

    По заданным двум точкам (одной начальной и одной конечной) и радиусу можно провести 4 дуги. Эти четыре дуги можно разделить двумя способами:

    1. по углу
      • более 180°
      • менее 180°
    2. Сгруппировано по направлению кисти
      • По часовой стрелке
      • против часовой стрелки

  • rx,ry - длина большой и малой полуосей дуги

  • x-axis-rotation — это угол поворота дуги, который представляет собой угол между большой полуосью этой дуги и горизонтальным направлением. Положительное число представляет угол поворота по часовой стрелке.

  • Флаг большой дуги равен 1 для дуг с большим углом и 0 для дуг с малым углом.

  • Флаг развертки 1 означает, что дуга идет по часовой стрелке вокруг центра от начальной точки до конечной точки, а 0 означает против часовой стрелки.

  • X, Y - координаты терминалов дуги.

  • <defs>

    SVG позволяет нам определять графические элементы, которые нам нужно повторно использовать позже. Рекомендуется определить все ссылочные элементы, которые необходимо повторно использовать вdefsвнутри элемента. Это повышает удобочитаемость и доступность содержимого SVG. существуетdefsГрафические элементы, определенные в elements, не визуализируются напрямую. Вы можете использовать в любом месте вашего окна просмотра``element отображает эти элементы. ——MDN

    Назначение этого тега — просто определить шаблон чертежа, который мы можем использовать непосредственно в другом месте.

    Здесь мы можем определить наш элемент градиента: linearGradient.

  • <linearGradient>

    Элемент linearGradient используется для определения линейного градиента, который используется для заливки или обводки графических элементов. ——MDN

    Цветовая шкала на градиенте, определяемом стоп-элементом.

    Например:

    <stop offset="5%" stop-color="#F60" />
    

    Эта строка кода означает: цвет #F60 со смещением 5% от начальной точки.

    Когда мы обращаемся к нашему собственному градиенту, чтобы установить цвет заливки или цвет кисти, нам нужно использовать url() только для привязки идентификатора градиента, как показано ниже:

    stroke="url(#linear)"
    

    Здесь мы устанавливаем цвет кисти на градиент, идентификатор которого является линейным.

Также есть два свойства:

  • stroke-dasharray

    Для создания пунктирных линий:

    stroke-dasharray = '10'
    stroke-dasharray = '10, 10'
    stroke-dasharray = '10, 10, 5, 5'
    

Нарисовать пунктирную линию: Когда параметр: Указывает длину пунктирной линии и интервал между каждой пунктирной линией.

Когда есть два или более параметра: один для длины и один для интервала

  • stroke-dashoffset

    Свойство stroke-dashoffset задает расстояние от шаблона штриха до начала контура.

    Если используется процентное значение, то это значение представляет процент текущего окна просмотра.

    Значение может принимать отрицательное значение. ——MDN

    Проще говоря, stroke-dashoffset задает смещение начальной точки кисти, а положительное значение смещает ее влево.

Реализация

рисовать пути SVG

Путем трассировки точек автор трассирует загруженное из интернета изображение яблока в SVG, что может быть неточно, но этого должно быть достаточно. Вот картинка того, что я нарисовал:

<path
  stroke-linecap="round"
  fill="none"
  stroke-width="10"
  stroke="url(#linear)"
  d="
M 197,148
A 87,87,0,0,0,79,214
A 282,282,0,0,0,148,438
A 54,54,0,0,0,212,448
A 87,87,0,0,1,288,448
A 54,54,0,0,0,352,438
A 282,282,0,0,0,407,350
A 87,87,0,0,1,413,189
A 87,87,0,0,0,303,148
A 141,141,0,0,1,197,148
Z
"
/>
<path
  stroke-linecap="round"
  fill="none"
  stroke="url(#linear)"
  stroke-width="10"
  d="
M 237,141
A 87,87,0,0,0,314,64
A 87,87,0,0,0,237,141
Z
"
/>

И я установил цвет кисти на идентификатор градиента, который собираюсь написать.

Определение цветов градиента

<defs>
  <linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="rgb(98, 180, 76)" />
    <stop offset="20%" stop-color="rgb(242, 179, 61)" />
    <stop offset="40%" stop-color="rgb(238, 125, 55)" />
    <stop offset="60%" stop-color="rgb(205, 58, 71)" />
    <stop offset="80%" stop-color="rgb(142, 61, 140)" />
    <stop offset="100%" stop-color="rgb(39, 155, 213)" />
  </linearGradient>
</defs>

Для отображения в цвете я настроил шесть узлов градиентного цвета.

Стоит отметить, что даже если на кисть наложен цвет градиента, его заливка заполняется в соответствии с цветовой заливкой лица. Возьмем этот пример, я определяю linearGradientx1="0%" y1="0%" x2="100%" y2="100%", так что цвет от верхнего левого угла до нижнего правого угла страницы отображается как градиент, а не градиент от начальной точки до конечной точки пути, поэтому цвет, который мы определяем для градиента в 0 % и 100% не обязательно должны совпадать. (На самом деле мы также не можем определить градиент от начальной точки до конечной точки пути)

JavaScript получает длину пути

let pathLength = document.querySelectorAll('path');
pathLength.forEach((item, index) => {
  let itemLength = Math.ceil(item.getTotalLength());
  console.log(itemLength);
});

Здесь мы используем JavaScript API: getTotalLength(), который используется для получения длины пути, что нам удобно для установки смещения.

оживлять

path {
  animation: dash 5s linear forwards;
}
path:nth-child(2) {
  stroke-dasharray: 1162;
  stroke-dashoffset: -1162;
}
path:nth-child(3){
  stroke-dasharray: 236;
  stroke-dashoffset: -236;
}
@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}

Наша анимация — это процесс с нуля, поэтому мы устанавливаем как длину тире, так и интервал* между каждым тире в соответствии с длиной пути.

В этом случае мы должны показать полный логотип Apple.

Когда мы устанавливаем stroke-dashoffset на длину пути, то мы полностью скрываем пунктирную часть картинки перед начальной точкой кисти. Вся картинка будет пустой!

В это время мы добавляем анимацию к двум путям и позволяем им изменять смещение штриха-тире на 0 с постоянной скоростью в течение 5 секунд, после чего нам представляется процесс динамического рисования логотипа, как показано в предыдущей анимации.

Другие реализации, такие как анимация

Сначала о рендерах:

Код реализации выглядит следующим образом:

<svg
xmlns="http://www.w3.org/2000/svg"
width="200px"
height="164.50px"
class="icon"
version="1.1"
viewBox="0 0 1245 1024"
id="logo-pic"
>
<defs>
  <linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#05a" />
    <stop offset="100%" stop-color="#0a5" />
  </linearGradient>
</defs>
<path
  fill="url(#linear)"
  d="M870.953514 333.768649c-209.781622 0-374.867027 145.020541-374.867028 322.836756s165.223784 322.836757 374.867028 322.836757a548.116757 548.116757 0 0 0 132.289729-22.417297L1124.185946 1024l-33.210811-110.702703C1179.537297 845.768649 1245.405405 756.92973 1245.405405 656.605405c0-177.816216-176.294054-322.836757-374.451891-322.836756z m-121.496217 267.208648A47.463784 47.463784 0 0 1 705.72973 556.419459 47.740541 47.740541 0 0 1 749.457297 512c33.349189 0 55.351351 22.278919 55.351352 44.557838s-22.002162 44.419459-55.351352 44.419459z m242.438919 0a47.325405 47.325405 0 0 1-43.727567-44.557838A47.602162 47.602162 0 0 1 991.896216 512c33.072432 0 55.351351 22.278919 55.351352 44.557838s-22.278919 44.419459-55.351352 44.419459z"
/>
<path
  fill="url(#linear)"
  d="M440.735135 0C198.434595 0 0 166.054054 0 378.326486c0 122.188108 66.006486 222.512432 176.432432 300.41946l-44.142702 133.811892 154.153513-77.907027c55.351351 10.931892 99.355676 22.278919 154.430271 22.278919 13.837838 0 27.675676 0 41.513513-1.798919a334.045405 334.045405 0 0 1-13.837838-93.267027c0-193.72973 166.054054-352.034595 374.728649-352.034595a378.88 378.88 0 0 1 42.482162 2.629189C847.429189 133.12 657.574054 0 440.735135 0zM294.192432 296.683243a53.137297 53.137297 0 1 1 52.722163-53.137297 52.860541 52.860541 0 0 1-52.722163 53.137297z m314.395676 0a53.137297 53.137297 0 1 1 52.722162-53.137297A52.860541 52.860541 0 0 1 608.864865 296.683243z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="2rem"
id="logo-name"
>
<text
  text-anchor="middle"
  x="50%"
  y="50%"
  class="logo logo-name-text-1"
>
  WeChat
</text>
<text
  text-anchor="middle"
  x="50%"
  y="50%"
  class="logo logo-name-text-2"
>
  WeChat
</text>
<text
  text-anchor="middle"
  x="50%"
  y="50%"
  class="logo logo-name-text-3"
>
  WeChat
</text>
</svg>

Стоит отметить, что текст в SVG также можно раскрасить, разделив границы и отступы. Итак, здесь мы устанавливаем границу текста в цвет градиента, определенный в начале, а для заливки — нет.

#logo-pic {
  width: 75px;
  height: 75px;
}
.logo {
  font-size: 1.25rem;
  font-weight: bold;
  fill: none;
  stroke-width: 1px;
  stroke-dasharray: 30% 70%;
  animation: stroke 4.5s infinite linear;
}
.logo-name-text-1 {
  stroke: rgb(0, 169, 86);
}
.logo-name-text-2 {
  stroke: rgb(0, 127, 129);
  animation-delay: -1.5s;
}
.logo-name-text-3 {
  stroke: rgb(0, 86, 168);
  animation-delay: -3s;
}
@keyframes stroke {
  to {
    stroke-dashoffset: -100%;
  }
}

Автор специально создал хранилище на github для записи навыков, трудностей и ошибок при обучении разработке с полным стеком.Вы можете щелкнуть ссылку ниже, чтобы просмотреть. Если вы думаете, что это не плохо, пожалуйста, дайте ему маленькую звезду! 👍


2019/04/02

AJie