10

Как добиться подобного эффекта заполнения линии, как рисунке ниже

введите сюда описание изображения

Можно предположить, что здесь использованы два атрибута линии:

  • stroke-linecap="round" чтобы закруглить концы черточек.
  • stroke-width (ширина линии) должна быть равна длине черты в stroke-dasharray, чтобы получить круги.

Выполняем эти условия: stroke-width:36.2; stroke-linecap:round; stroke-dasharray:36.2,36.2"

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="600" viewBox="0 0 400 400" >
     <rect width="100%" height="100%" fill="#C45585" />
 <path  id="check"
     style="stroke:white; fill:none;stroke-width:36.2; stroke-linecap:round; stroke-dasharray:36.2,36.2"
     d="m350 200c0 27.2-7.3 52.8-19.9 74.8C304.2 319.7 255.6 350 200 350 144.7 350 96.3 320 70.3 275.5 57.4 253.3 50 227.5 50 200 50 117.2 117.2 50 200 50c82.8 0 150 67.2 150 150z"/>
</svg>

И получаем вместо кружков, что-то сосисочно-колбасное

введите сюда описание изображения

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

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
  • Похоже на полость рта. Или моя больная фантазия – Randall Mar 24 '22 at 14:34
  • @Избытоксусликов Ну если сможешь засунуть голову в чужую полость рта и посмотришь сверху на нижнюю челюсть, то наверное будет похоже:)) Привет дорогой. Что-то давно ты не задавал вопросов по SVG/ Раньше у тебя хорошо получалось – Alexandr_TT Mar 24 '22 at 14:59
  • 1
    @Избытоксусликов код немного изменил для твоей версии :)) – Alexandr_TT Mar 24 '22 at 15:04
  • 1
    Привет-привет :) Так я уже не задаю вопросы с 17-го года. Смотрю на твои вопросы обычно. Все также очень интересно. :) – Randall Mar 24 '22 at 22:04

2 Answers2

10

Рассмотрим подробней атрибут линии stroke-linecap="round"

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

введите сюда описание изображения

То есть решение уже становится практически ясным.

Рассмотрим на нашем примере с окружностью

введите сюда описание изображения

При длине черты stroke-dasharray="36.2" и stroke-linecap="round" к концам черты 36px с двух сторон присоединяются две полуокружности с диаметром равным ширине линии stroke-width="36.2"

Поэтому, чтобы получить полную окружность, нужно убрать прямой участок, то есть сделать черту в stroke-dasharray="0,36.2", где 0 - длина черты, 36.2 - длина пробела

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="600" viewBox="0 0 400 400" >
     <rect width="100%" height="100%" fill="#2772C7" />
 <path  id="check"
     style="stroke:white; fill:none;stroke-width:36.2; stroke-linecap:round; stroke-dasharray:0,36.2"
     d="m350 200c0 27.2-7.3 52.8-19.9 74.8C304.2 319.7 255.6 350 200 350 144.7 350 96.3 320 70.3 275.5 57.4 253.3 50 227.5 50 200 50 117.2 117.2 50 200 50c82.8 0 150 67.2 150 150z"/>
</svg>    

#1. Заполнение линии одной, двумя, N окружностями

Ниже будут практические примеры использования этого эффекта с нулевой длиной черточки в stroke-dasharray и шириной линии stroke-width равной длине пробела

Чтобы показать, что эта техника универсальна, возьму вместо кругового path, как в примере выше, окружность - circle

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

Для вывода одной синей окружности на большой серой окружности, нужно брать полную длину линии большой окружности perimeter = 2 * Math.PI * R = 942 , где

PI – число ПИ
R – радиус окружности, на которой будут размещены маленькие окружности

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400">
 &lt;!-- Большая окружность --&gt;

<circle cx="200" cy="200" r="150" fill="none" stroke="grey" stroke-width="2" />
<!-- Один синий кружок --> <circle cx="200" cy="200" r="150" fill="none" stroke="dodgerblue" stroke-dasharray="0, 942" stroke-width="35" stroke-linecap="round"/> </svg>

введите сюда описание изображения

#2. Заполнение линии шестью окружностями

Код точно такой же, как и в примере с одной окружностью, но нужно поделить длину большой окружности на шесть равных частей

perimeter = 2*Math.PI*R / 6 = 157
stroke-dasharray=”0, 157″

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" viewBox="0 0 400 400">
 &lt;!-- Большая окружность --&gt;

<circle cx="200" cy="200" r="150" fill="none" stroke="grey" stroke-width="2" />
<!-- Шесть синих кружков --> <circle cx="200" cy="200" r="150" fill="none" stroke="dodgerblue" stroke-dasharray="0, 157" stroke-width="35" stroke-linecap="round"/>

введите сюда описание изображения

#3. Анимация спирали со линией, состоящих из кружков

Идея состоит в том, чтобы линию спирали с кружками, изначально закрывает маска, которая будет постепенно открывать линию с кружками. Для реализации анимации линии маски, используется прием изменения атрибутов “stroke-dashoffset` от максимального значения – “6265px” до нуля, реализуя тем самым постепенный рост видимой линии от нуля до максимума. Подробнее здесь и здесь

 #path1 {
 fill:none;
 stroke:white;
 stroke-width:25;
 stroke-dasharray:6265;
 stroke-dashoffset:6265;
 }
 #path2 {
 fill:none;
 stroke:white;
 stroke-width:25;
 stroke-linecap:round;
 stroke-dasharray:0,25;
 }
<svg id="svg1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="600" height="800" viewBox="0 150 744 1052">
   <defs> 
     <mask id="msk">   
              <!-- Маска, изначально закрывающая линию с кружками -->
     <path id="path1"  d="m351 487c0 8-11 4-14-1-6-11 4-24 15-27 19-5 37 11 40 30 4 27-18 50-44 53-35 4-64-25-66-59-3-42 32-77 73-79 50-3 90 39 92 88 2 57-46 104-102 105-65 2-117-53-119-117-1-72 60-131 131-132 80-1 144 67 145 146 1 87-74 158-160 158-95 0-171-81-171-175 0-102 88-185 190-184 110 1 198 95 197 204C557 615 456 709 340 708 215 706 115 598 117 475 119 342 233 236 364 238 504 240 616 361 614 500 611 648 484 766 337 763 182 760 58 626 61 472 65 309 206 179 367 183c170 4 306 151 302 320-4 178-158 319-335 315" >
      <!-- анимация линии маски открывающая линию с кружками -->
      <animate id="an"
        attributeName="stroke-dashoffset"
        values="6265;0;0;6265"
        begin="svg1.click"
        dur="18s"
        fill="freeze"
        repeatCount="2"
        restart="whenNotActive" /> 
     </path>
     </mask>
  </defs>     
             <!-- Фон   -->
   <rect width="100%" height="100%" style="fill: dodgerblue" />
           <!-- линия с кружками -->

<path id="path2" mask="url(#msk)" d="m351 487c0 8-11 4-14-1-6-11 4-24 15-27 19-5 37 11 40 30 4 27-18 50-44 53-35 4-64-25-66-59-3-42 32-77 73-79 50-3 90 39 92 88 2 57-46 104-102 105-65 2-117-53-119-117-1-72 60-131 131-132 80-1 144 67 145 146 1 87-74 158-160 158-95 0-171-81-171-175 0-102 88-185 190-184 110 1 198 95 197 204C557 615 456 709 340 708 215 706 115 598 117 475 119 342 233 236 364 238 504 240 616 361 614 500 611 648 484 766 337 763 182 760 58 626 61 472 65 309 206 179 367 183c170 4 306 151 302 320-4 178-158 319-335 315"/> <text x="12" y="225" font-size="32px" fill="white" >Click me </text> </svg>

введите сюда описание изображения

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384
6

Другие примеры анимации

Концепция прелоадеров.

Тут можно играть с парными параметрами атрибута stroke-dasharray до бесконечности.

 <animate attributeName="stroke-dasharray" begin="0s" dur="10s"
       values="0,942;
             0,36;
             0,36;
             0,942;
             0,942"
               fill="freeze"
               repeatCount="indefinite"
               keyTimes="
               0;0.4;0.55;0.99;1"/>

#1. Заполнение фигуры от одного кружка до полного заполнения периметра

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="600" viewBox="0 0 400 400" >
     <rect width="100%" height="100%" fill="#2772C7" />
 <path  id="check"
     style="stroke:white; fill:none;stroke-width:36.2; stroke-linecap:round; stroke-dasharray:0,36.2"
     d="m350 200c0 27.2-7.3 52.8-19.9 74.8C304.2 319.7 255.6 350 200 350 144.7 350 96.3 320 70.3 275.5 57.4 253.3 50 227.5 50 200 50 117.2 117.2 50 200 50c82.8 0 150 67.2 150 150z">
     <animate attributeName="stroke-dasharray" begin="0s" dur="10s"
       values="0,942;
             0,36;
             0,36;
             0,942;
             0,942"
               fill="freeze"
               repeatCount="indefinite"
               keyTimes="
               0;0.4;0.55;0.99;1"/>
  </path>    
</svg>

#2. Заполнение периметра фигуры от одного кружка до нескольких с изменением длины сегментов

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="600" viewBox="0 0 400 400" >
     <rect width="100%" height="100%" fill="#2772C7" />
 <path  id="check"
     style="stroke:white; fill:none;stroke-width:36.2; stroke-linecap:round; stroke-dasharray:0,36.2"
     d="m350 200c0 27.2-7.3 52.8-19.9 74.8C304.2 319.7 255.6 350 200 350 144.7 350 96.3 320 70.3 275.5 57.4 253.3 50 227.5 50 200 50 117.2 117.2 50 200 50c82.8 0 150 67.2 150 150z">
     <animate attributeName="stroke-dasharray" begin="0s" dur="8s"
       values="0, 942;
               80,785;
               100,628;
               120,471;
               100,57;
               0,36;
               0,36;
               120,471;
               100,628;
               80,785;
               0,942;
               0,942"
               fill="freeze"
               repeatCount="indefinite"/>
  </path>    
</svg>    

3#. Анимация изменения формы рамки

Морфинг формы рамки из окружности в треугольник и затем в прямоугольник, основан на анимации атрибута: “d” path

введите сюда описание изображения введите сюда описание изображения введите сюда описание изображения

Пути всех фигур рисуются в векторном редакторе.
Чтобы анимация была гладкой, без рывков, необходимо выполнить два условия при создании path:

  • Количество узловых точек должно быть одинаковым во всех фигурах
  • Тип узловых точек с одинаковым расположением от начала, должен быть одинаковым во всех фигурах

Анимация начнется после клика по фигуре

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" viewBox="0 0 400 400" >
     <rect width="100%" height="100%" fill="#2772C7" />
 <path  
     style="stroke:white; fill:none;stroke-width:18; stroke-linecap:round; stroke-dasharray:0,15"
     d="m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z">
            <!-- Анимация морфинга круга в треугольник и прямоугольник -->
      <animate
        attributeName="d"
        begin="svg1.click"
        dur="3s"
        fill="freeze"
        repeatCount="3"
        restart="whenNotActive"
        values="
            m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;
        m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;

        m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;

        m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;

        m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;

        m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;

        m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150z"    
         /&gt;

</path> </svg>

Alexandr_TT
  • 110,146
  • 23
  • 114
  • 384