【问题标题】:Filling Non-linear Svg Path Stroke填充非线性 Svg 路径描边
【发布时间】:2022-02-15 08:11:46
【问题描述】:

我试图通过用线性渐变填充笔划来做速度计。当停止偏移为 0% 时,白线出现在路径的开头。我怎样才能摆脱它?此外,我不确定用线性渐变填充笔画是填充 svg 路径的最佳选择。你有更好的想法吗?

<svg width="196" height="65" viewBox="0 0 196 65" fill="none" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="fillSpeedometer" x1="0" y1="0.5" x2="1" y2="0.5">
      <stop offset="0%" stop-opacity="1" stop-color="white" />
      <stop offset="0%" stop-opacity="1" stop-color="white" />
      <stop offset="0%" stop-opacity="1" stop-color="grey" />
      <stop offset="100%" stop-opacity="1" stop-color="grey" />
    </linearGradient>
  </defs>
  <path d="M2 63C3.65579 42.6667 19.0187 2 67.2238 2C115.429 2 171.827 2 194 2" stroke="url(#fillSpeedometer)" stroke-width="3" stroke-linecap="round" />
</svg>

【问题讨论】:

    标签: css svg


    【解决方案1】:

    一种常见的方法是通过设置/更改stroke-dasharray 属性来呈现您的当前值/速度。

    假设您的“限速”是 300 公里/小时。

    pathLength 属性应用于您的路径。 这样您就可以轻松地显示当前速度,例如 50 km/h,如下所示:

    stroke-dasharray="150 300"
    

    第二个破折号数组值将是总速度(或最大范围值)。
    这将确保虚线笔划有足够大的间隙(因此您不会看到重复的虚线图案)。

    示例:使用 stroke-daharray

    let svgGauges = document.querySelectorAll(".gaugeProgress");
    let progress = document.querySelector("#progress");
    
    progress.addEventListener("change", function(e) {
      let percent = e.target.value;
      if (svgGauges.length) {
        svgGauges.forEach(function(gauge, i) {
          let currentGauge = svgGauges[i];
          let dashGap = gauge.getAttribute("stroke-dasharray").split(" ")[1];
          gauge.setAttribute("stroke-dasharray", percent + " " + dashGap);
        });
      }
    });
    #progress,
    .speedometer {
      display: inline-block;
      width: 50%
    }
    
    .gaugeProgress {
      transition: 0.3s stroke-dasharray;
    }
    <h3>Speed (km/h)</h3>
    <p><input id="progress" type="range" min="0" max="300" step="10" value="150" />
    </p>
    <svg class="speedometer" viewBox="0 0 196 65" fill="none" xmlns="http://www.w3.org/2000/svg">
      <!-- remove stroke-linecap if stroke dash is 0 -->
        <style>
          [stroke-dasharray^="0 "] {
            stroke-linecap: unset;
          }
        </style>
      <defs>
        <linearGradient id="fillSpeedometer">
          <stop offset="0%" stop-opacity="1" stop-color="orange" />
          <stop offset="100%" stop-opacity="1" stop-color="red" />
        </linearGradient>
      </defs>
      <path id="gauge" pathLength="300" d="M2 63C3.65579 42.6667 19.0187 2 67.2238 2C115.429 2 171.827 2 194 2" stroke-width="3" />
      <use class="gaugeBG" href="#gauge" stroke="#ccc" stroke-linecap="round" />
      <use class="gaugeProgress" href="#gauge" stroke="url(#fillSpeedometer)" stroke-dasharray="50 300" stroke-linecap="round" />
    </svg>

    如果您使用圆角线帽,则需要一个额外的 css 规则来防止可见笔划 value=0。由于 stroke-linecap="round" (或 rect) 会扩展您的笔划破折号,您需要像这样禁用这个 stroke-linecap 值:

      [stroke-dasharray^="0 "] {
        stroke-linecap: unset;
      }  
    

    这个概念与用于许多仪表/饼图/甜甜圈图设计的基本相同......以及svg line animations.
    另见gauge related questions on SO.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2022-01-19
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 2020-03-14
      相关资源
      最近更新 更多