SVG 路径未按预期设置动画的问题

我正在使用关于内嵌 SVG 的 this 视频教程作为参考。我试图复制使 SVG 线看起来从中间点画出来的效果。视频中的方法和我的方法之间的唯一区别是,在视频中,SVG 行具有预定义的长度,而我的则是可变长度。

该方法背后的想法非常简单。您可以创建任意大小的 SVG 线,然后将其 stroke-dasharray 属性设置为 '0,length/2',并将它的 stroke-dashoffset 属性设置为 '-length/2',这样该线就不会在首先,它的“起点”设置在它的中间点。然后,当相关输入字段被聚焦时,您将 dasharray 属性更改为 'length,0' 并将 dashoffset 属性更改为 0。这使得虚线等于线的长度。这应该使线条看起来是从中间点画出来的,如果你从一开始就知道线条的长度,这确实会发生。但是,当我尝试使用没有预定长度的线来实现这种方法时,情况并非如此。我的线条似乎几乎从线条的开头而不是从中间点开始绘制。我很困惑为什么会发生这种情况。我正在使用 JavaScript 来计算线的长度。下面是我的代码片段。

function animateLine() {

  const input = document.querySelector('.input');
  const line = document.querySelector('.focus');
  
  const length = line.getTotalLength();
  
  line.style.strokeDasharray = `0,${length/2}`;
  line.style.strokeDashoffset = `-${length/2}`;
  
  input.addEventListener('focus',function() {
    line.style.strokeDasharray = `${length},0`;
    line.style.strokeDashoffset = `0`;
  });
};


animateLine();
/* Input module */

.input {
  background: none;
  border: none;
  width: 100 %;
  padding: 0.5em;
  padding-left: 0;
  color: white;
  font-family: inherit;
  font-size: 0.85em;
}

.input:focus {
  outline: none;
}

.line {
  width: 100%;
  height: 2px;
  padding: 0;
  stroke: grey;
}

.focus {
  stroke: black;
  transition: all 5s;
  stroke-dasharray: 0,10000;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <input class="input" type="text" name="review[body]" placeholder="Leave a review..." required>
  <svg xmlns="http://www.w3.org/2000/svg" class="line" viewBox="0 0 40 2" preserveAspectRatio="none">
                        <path d="M0 1 L40 1"></path>
                        <path d="M0 1 L40 1" class="focus"></path>
</svg>
</body>

</html>

我尝试使用不同的百分比,并仅使用值“20”作为我的半长,因为我的视口长度为“40”,但这些都不起作用。有谁知道这里可能有什么问题?

zhangxiaoqi525 回答:SVG 路径未按预期设置动画的问题

我想出了问题。这是一个令人尴尬的错误,但无论如何我都会把它留在这里,以防万一有人也遇到这个问题。

我使用“transition: all 5s”来更好地查看中间点的位置,当我为我的 SVG 行设置动画时。问题是在开始时,我将 stroke-dasharray 设置为“0,10000”以使线条不可见,我没有设置 stroke-dashoffset 属性,因为我认为我需要首先弄清楚中间点是什么。然后我将这 2 个属性设置为它们应该使用 JavaScript 的内容。这触发了转换到启动,耗时 5 秒。所以当我专注于相关的输入元素时,我并没有像我想要的那样从中间点开始动画;当我加载到页面时,我没有等待 5 秒,这没有给初始动画足够的时间来完成到达线的中点。

这一切都是因为我的误会。我的理解是 SVG 线的长度与包含它的 div 的大小成正比(因为我将“线”类的宽度设置为 100%)。但是,SVG 大小实际上是使用视口单位计算的,而不是像素或其他绝对单位。知道这一点后,我意识到我可以使用更简单的方法实现我所期待的效果,而无需涉及 JavaScript。我们可以简单地忽略 SVG 的实际显示大小,而只关注我们最初设置的视口单位。默认情况下,浏览器实际上会使这个视口单位与 SVG 可用的任何空间成比例。因此,我们可以简单地使用 20 个视口单位的宽度作为 SVG 线的中点,而不是计算 SVG 路径的长度,因为我们知道这些视口单位将与 SVG 可用的空间成正比.我想强调的是,这适用于任何线长,只要您使用的视口为 40。

/* Input module */

.input {
  background: none;
  border: none;
  width: 100%;
  padding: 0.5em;
  padding-left: 0;
  color: black;
  font-family: inherit;
  font-size: 0.85em;
}

.input:focus {
  outline: none;
}


/* SVGs */

.line {
  width: 100%;
  height: 2px;
  padding: 0;
  stroke: grey;
}

.focus {
  stroke: black;
  transition: all 2s;
  stroke-dasharray: 0,20;
  stroke-dashoffset: -20;
}

.input:focus~.line .focus {
  stroke-dasharray: 40;
  stroke-dashoffset: 0;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <input class="input" type="text" name="review[body]" placeholder="Leave a review..." required>
  <svg xmlns="http://www.w3.org/2000/svg" class="line" viewBox="0 0 40 2" preserveAspectRatio="none">
                        <path d="M0 1 L40 1"></path>
                        <path d="M0 1 L40 1" class="focus">
                        </path>
                    </svg>
</body>

</html>

差不多就是这样。我的基本错误。

本文链接:https://www.f2er.com/510918.html

大家都在问