Сделайте ‹путь› при прокрутке растущим до пунктирной линии

Это то, что я сделал до сих пор с помощью друзей из самого stackoverfow.

Он отлично работает, но я хочу сделать анимацию, которая для меня немного сложна.

// Get the id of the <path> element and the length of <path>
var myline = document.getElementById("myline");
var length = myline.getTotalLength();
circle = document.getElementById("circle");
// The start position of the drawing
myline.style.strokeDasharray = length;

// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
myline.style.strokeDashoffset = length;

// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);

function myFunction() {
  // What % down is it?
  var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
  // Length to offset the dashes
  var draw = length * scrollpercent;

  // Reverse the drawing (when scrolling upwards)
  myline.style.strokeDashoffset = length - draw;

  //get point at length
  endPoint = myline.getPointAtLength(draw);
  circle.setAttribute("cx", endPoint.x);
  circle.setAttribute("cy", endPoint.y);

}
body {
  height: 2000px;
  background: #f1f1f1;
}

#circle {
  fill: red;
}

#mySVG {
  position: fixed;
  top: 15%;
  width: 100vw;
  height: 100vh;
  margin-left: -50px;
}

.st0 {
  fill: none;
  stroke-dashoffset: 3px;
  stroke: red;
  stroke-width: 5;
  stroke-miterlimit: 10;
  stroke-dasharray: 20;
}
<h2>Scroll down this window to draw my path.</h2>
<p>Scroll back up to reverse the drawing.</p>

<svg id="mySVG" viewBox="0 0 60 55" preserveAspectRatio="xMidYMin slice" style="width: 6%; padding-bottom: 42%; height: 1px; overflow: visible">
  <circle id="circle" cx="10" cy="10" r="10"/>
  <path id="myline" class="st0" stroke-dasharray="10,9" d="M 20 0 v 20 a 30 30 0 0 0 30 30 h 600 a 40 40 0 0 1 0 80 h -140 a 30 30 0 0 0 0 60 h 200 a 40 40 0 0 1 0 80 h -100 a 30 30 0 0 0 -30 30 v 20" /> Sorry, your browser does not support inline SVG.
</svg>

Мой вопрос: Можем ли мы сделать линию пунктирной?

Я знаю, что путь растет, используя strokeDasharray. Но все же, есть ли способ достичь того, что я ищу? Если нет, то предложите другой способ. Я не ищу "поместить пунктирную линию поверх линии, которую вы хотите нарисовать, и придать ей цвет вашего фона".


person Jithin Raj P R    schedule 07.08.2017    source источник
comment
Я не верю, что есть другой способ, кроме того, что вы говорите, что не хотите codepen.io/ Евгений/pen/IEGoq   -  person K Scandrett    schedule 07.08.2017
comment
@KScandrett в моей онлайн-проверке я тоже пришел к такому выводу. Но мне было интересно, экспериментировал ли кто-нибудь с новыми методами и достиг чего-то. Посмотрим, есть ли у кого новые идеи..!   -  person Jithin Raj P R    schedule 07.08.2017


Ответы (1)


Есть способ сделать это. Вы можете использовать пунктирную линию в качестве маски для анимированной линии.

// Get the id of the <path> element and the length of <path>
var myline = document.getElementById("myline");
var length = myline.getTotalLength();
circle = document.getElementById("circle");
// The start position of the drawing
myline.style.strokeDasharray = length;

// Hide the triangle by offsetting dash. Remove this line to show the triangle before scroll draw
myline.style.strokeDashoffset = length;

// Find scroll percentage on scroll (using cross-browser properties), and offset dash same amount as percentage scrolled
window.addEventListener("scroll", myFunction);

function myFunction() {
  // What % down is it?
  var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
  // Length to offset the dashes
  var draw = length * scrollpercent;

  // Reverse the drawing (when scrolling upwards)
  myline.style.strokeDashoffset = length - draw;

  //get point at length
  endPoint = myline.getPointAtLength(draw);
  circle.setAttribute("cx", endPoint.x);
  circle.setAttribute("cy", endPoint.y);

}
body {
  height: 2000px;
  background: #f1f1f1;
}

#circle {
  fill: red;
}

#mySVG {
  position: fixed;
  top: 15%;
  width: 100vw;
  height: 100vh;
  margin-left: -50px;
}

.st0 {
  fill: none;
  stroke-dashoffset: 3px;
  stroke: red;
  stroke-width: 5;
  stroke-miterlimit: 10;
  stroke-dasharray: 20;
}

.mask-style {
  stroke: white;
  stroke-width: 7;
}
<h2>Scroll down this window to draw my path.</h2>
<p>Scroll back up to reverse the drawing.</p>

<svg id="mySVG" viewBox="0 0 60 55" preserveAspectRatio="xMidYMin slice" style="width: 6%; padding-bottom: 42%; height: 1px; overflow: visible">
  <defs>
    <mask id="dash-mask">
      <path class="st0 mask-style" stroke-dasharray="10,9" d="M 20 0 v 20 a 30 30 0 0 0 30 30 h 600 a 40 40 0 0 1 0 80 h -140 a 30 30 0 0 0 0 60 h 200 a 40 40 0 0 1 0 80 h -100 a 30 30 0 0 0 -30 30 v 20" />
    </mask>
  </defs>
  <circle id="circle" cx="10" cy="10" r="10"/>
  <path id="myline" class="st0" stroke-dasharray="10,9" d="M 20 0 v 20 a 30 30 0 0 0 30 30 h 600 a 40 40 0 0 1 0 80 h -140 a 30 30 0 0 0 0 60 h 200 a 40 40 0 0 1 0 80 h -100 a 30 30 0 0 0 -30 30 v 20" mask="url(#dash-mask)"/>
  Sorry, your browser does not support inline SVG.
</svg>

person Paul LeBeau    schedule 07.08.2017
comment
Низ, это хорошая работа. Но мне интересно, есть ли какой-нибудь прямой способ сделать это.! - person Jithin Raj P R; 07.08.2017
comment
Обходной путь — это хакерское решение ошибки. Это не то. Вы дублируете путь. Сделайте его белым и немного толще. Оберните его тегами <mask>, а затем укажите исходный путь. Это совсем не сложно. Более простого решения вы не найдете. - person Paul LeBeau; 07.08.2017