使滚动增长 <path> 到虚线

Posted

技术标签:

【中文标题】使滚动增长 <path> 到虚线【英文标题】:Make the on scroll growing <path> to dashed line 【发布时间】:2018-01-14 08:40:29 【问题描述】:

这是我目前在 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 的路径正在增长。但是,有没有办法达到我正在寻找的东西?如果没有,那么请建议另一种方式。我不是在寻找“在您要绘制的线条上放置一条虚线并为其提供背景颜色”。

【问题讨论】:

我不相信有别的办法,除了你说你不想要的codepen.io/Evgeny/pen/IEGoq @KScandrett 在我的在线检查中也是我得出的结论。但我想知道是否有人尝试过新方法并到达某个地方。让我们看看有没有人有新的想法..! 【参考方案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>

【讨论】:

Nyz 这是一个很好的解决方法。但我想知道是否有任何直接的方法可以做到这一点。! 变通方法是针对错误的 hacky 解决方案。这不是那个。您复制路径。让它变白,稍微厚一点。将其包裹在&lt;mask&gt; 标签中,然后将您的原始路径指向它。这一点都不复杂。你不会找到更简单的解决方案。

以上是关于使滚动增长 <path> 到虚线的主要内容,如果未能解决你的问题,请参考以下文章

如何在相应的滚动上获得虚线(带有向下箭头图标)SVG动画?

如何使虚线图居中?

flex 图表网格线虚线

下滑虚线组件封装

如何在 Android 中使用虚线/虚线分隔线创建 ListView?

调整大小时,使用虚线边框使窗口透明