Создание анимированной пунктирной линии SVG с прозрачным фоном

Я играл с этим часами и пытался придумать решение.

В этом... https://jsfiddle.net/WebFlair/nc0zyjdq/78/

<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

<path class="dashed" fill="none" stroke="white"  stroke-width="7" stroke-linejoin="round" stroke-miterlimit="16" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
<style>
.bg {background:#eee;}
.dashed{
  stroke-dasharray: 14;
}
.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
</style>

Вы увидите серый фон и анимированную бело-розовую пунктирную линию.

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

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


person user2227359    schedule 28.12.2020    source источник


Ответы (2)


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

Идея такова: использовать три слоя

  1. Первый нижний слой будет иметь белый путь
  2. Средний слой будет иметь точно такую ​​же розовую дорожку.
  3. На верхнем слое будет маскирующий контур, постепенно раскрывающий розовый контур.

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

А так как длина маскирующего пути изменяется от нуля до максимального значения (stroke-dashoffset уменьшается от максимального 917 до нуля), становится виден рост розового пути

@keyframes dash {
  from {
    stroke-dashoffset: 917;
  }
  to {
    stroke-dashoffset: 0;
  }

Уточнение: максимальная длина пути – 917px

1. Первый нижний слой будет иметь белый контур

.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
}
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
    
    
</svg>
</div>
<script>
  console.log(dashed.getTotalLength());
</script>

2. Средний слой будет иметь точно такую ​​же розовую дорожку

 <style>
.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">


   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

</svg>
</div>

3. На верхнем слое будет маскирующий путь, который постепенно покажет розовый путь

.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 

#maskLine {
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-dasharray: 917;
  stroke-dashoffset: 917;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 917;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<defs>
  <mask id="msk">  
       <!-- A mask layer that reveals a dashed pink line -->
    <path id="maskLine"  d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
  </mask>
</defs>

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
    
</svg>
</div>

ОБНОВЛЕНИЕ

Заполнение, очистка пути при повторных нажатиях на кнопку Play

var dash = true;

function play() {
  var path = document.getElementById('maskLine');
  path.style.strokeDashoffset = (dash) ? '0' : '917.00';
  dash = !dash;
} 
.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 

#maskLine {
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-dasharray: 917;
  stroke-dashoffset: 917;
  transition: stroke-dashoffset 5s linear;
}
<button onclick="play();">Play</button>
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<defs>
  <mask id="msk">  
       <!-- A mask layer that reveals a dashed pink line -->
    <path id="maskLine"  d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591">
     </path>
        
     </path>    
  </mask>
</defs>

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

</svg>
</div>

person Alexandr_TT    schedule 28.12.2020

Вы можете сделать это с помощью маски:

.bg {
  background: #eee;
}

.dashed {
  stroke-dasharray: 14;
}

.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<div class="bg">
  <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000" preserveAspectRatio="xMidYMid meet">
  <defs>
    <path id="dashed" class="dashed" fill="none" stroke="white" stroke-width="7" stroke-linejoin="round" stroke-dasharray="14" stroke-miterlimit="16" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
    <mask id="mask">
      <use xlink:href="#dashed"/>
    </mask>
  </defs>
  <path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" mask="url(#mask)" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
  </svg>
</div>

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

person Robby Cornelissen    schedule 28.12.2020