使用特定点的百分比值填充箭头SVG图标。

huangapple go评论56阅读模式
英文:

Fill arrow SVG icon using percentage value from specific point

问题

以下是您要翻译的内容:

我有这个SVG图标,我想根据百分比值填充它的颜色,这是一个图表,所以它应该从左上角开始,沿着线条一直向右填充。

演示

<!-- 开始代码片段: 不隐藏 js 控制台输出: 是 不使用 Babel: 是 -->

<!-- JavaScript 代码 -->
function setProgress(amt)
{
  amt = (amt < 0) ? 0 : (amt > 1) ? 1 : amt;
  document.getElementById("stop1").setAttribute("offset", amt);
  document.getElementById("stop2").setAttribute("offset", amt);
}

setProgress(0.60);

<!-- HTML 代码 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.25 233.26">
<defs>
 <linearGradient id="progress" x1="1" y1="0" x2="0" y2="0">
      <stop id="stop1" offset="0" stop-color="#bb8e89"/>
      <stop id="stop2" offset="0" stop-color="#f4b6b0"/>
    </linearGradient>
</defs>
<g id="Capa_2" data-name="Capa 2">
<g id="Capa_1-2" data-name="Capa 1">
<path class="cls-1" fill="url(#progress)" d="M254.25,17.72,235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z"/>
</g>
</g>
</svg>

<!-- 结束代码片段 -->
英文:

I have this svg icon that I want to fill with color according to the percentage value, it's a chart, so it should start from the top left and fill all the way to the right following the line..

Demo

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function setProgress(amt)
{
  amt = (amt &lt; 0) ? 0 : (amt &gt; 1) ? 1 : amt;
  document.getElementById(&quot;stop1&quot;).setAttribute(&quot;offset&quot;, amt);
  document.getElementById(&quot;stop2&quot;).setAttribute(&quot;offset&quot;, amt);
}


setProgress(0.60);

<!-- language: lang-html -->

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 254.25 233.26&quot;&gt;
&lt;defs&gt;
 &lt;linearGradient id=&quot;progress&quot; x1=&quot;1&quot; y1=&quot;0&quot; x2=&quot;0&quot; y2=&quot;0&quot;&gt;
      &lt;stop id=&quot;stop1&quot; offset=&quot;0&quot; stop-color=&quot;#bb8e89&quot;/&gt;
      &lt;stop id=&quot;stop2&quot; offset=&quot;0&quot; stop-color=&quot;#f4b6b0&quot;/&gt;
    &lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;g id=&quot;Capa_2&quot; data-name=&quot;Capa 2&quot;&gt;
&lt;g id=&quot;Capa_1-2&quot; data-name=&quot;Capa 1&quot;&gt;
&lt;path class=&quot;cls-1&quot; fill=&quot;url(#progress)&quot; d=&quot;M254.25,17.72,235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z&quot;/&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

答案1

得分: 1

Exaneta 在使用路径 "stroke" 而不是 "fill" 时是正确的。

使用 "stroke",您可以使用 "stroke-dashArray="[百分比] 100""。

唯一棘手的部分是您的箭头,要动态定位它,您需要使用 "animateMotion"。

使用原生的 JSWC JavaScript Web 组件,因为这是它们的用途。

通过 "observed" 属性 "percentage" 使其具有响应性。

<svg-percentage percentage="10"></svg-percentage>
<svg-percentage percentage="42"></svg-percentage>
<svg-percentage percentage="77"></svg-percentage>

创建:

使用特定点的百分比值填充箭头SVG图标。

仅为 Stack Overflow Snippet 演示添加了 "onclick"。

customElements.define("svg-percentage", class extends HTMLElement {
  static get observedAttributes() {
    return ["percentage"];
  }
  connectedCallback() {
    this.attributeChangedCallback();
    this.onclick = () => this.setAttribute("percentage", ~~(Math.random()*100));
  }
  attributeChangedCallback() {
    let p = ~~(this.getAttribute("percentage") || 42);
    let d = "m10 52 0 40c0 181 230 181 225 0l0-92";
    let id = "p" + Math.random() * 1e18; // 创建唯一的 id
    this.innerHTML = `
<svg viewBox="-10 -25 260 280" stroke-width="15">
   <path id="${id}" d="${d}" fill="none" stroke="lightgrey"/>
   <path d="${d}" fill="none" stroke="lightgreen" 
         pathLength="100" stroke-dasharray="${p} 100"/>
   <path d="m0 -15 30 15-30 15z" fill="green">         
     <animateMotion dur="0.001s" rotate="auto" fill="freeze" 
                    keyPoints="0;${p/100}" keyTimes="0;1" calcMode="linear">
        <mpath href="#${id}"/>
      </animateMotion>
    </path>
    <text x="50%" y="50%" font-size="3em" text-anchor="middle">${p}%</text>
</svg>`;
  }
})
<style>
  svg { max-height: 170px }
</style>

<svg-percentage percentage="10"></svg-percentage>
<svg-percentage percentage="42"></svg-percentage>
<svg-percentage percentage="77"></svg-percentage>
英文:

I am not 100% sure what you are after.

Exaneta is correct when he shows to use path stroke and not fill

With stroke you can use stroke-dashArray=&quot;[percentage] 100&quot;

Only tricky part then is your arrow-head, to position it dynamically you need animateMotion

Using a native JSWC JavaScript Web Component because this is what they are meant to do

Making it reactive with observed attribute percentage

&lt;svg-percentage percentage=&quot;10&quot;&gt;&lt;/svg-percentage&gt;
&lt;svg-percentage percentage=&quot;42&quot;&gt;&lt;/svg-percentage&gt;
&lt;svg-percentage percentage=&quot;77&quot;&gt;&lt;/svg-percentage&gt;

creates:

使用特定点的百分比值填充箭头SVG图标。

Added an onclick for Stack Overflow Snippet demo only

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

customElements.define(&quot;svg-percentage&quot;, class extends HTMLElement {
  static get observedAttributes() {
    return [&quot;percentage&quot;];
  }
  connectedCallback() {
    this.attributeChangedCallback();
    this.onclick = () =&gt; this.setAttribute(&quot;percentage&quot;, ~~(Math.random()*100));
  }
  attributeChangedCallback() {
    let p = ~~(this.getAttribute(&quot;percentage&quot;) || 42);
    let d = &quot;m10 52 0 40c0 181 230 181 225 0l0-92&quot;;
    let id = &quot;p&quot; + Math.random() * 1e18; // create a unique id
    this.innerHTML = `
&lt;svg viewBox=&quot;-10 -25 260 280&quot; stroke-width=&quot;15&quot;&gt;
   &lt;path id=&quot;${id}&quot; d=&quot;${d}&quot; fill=&quot;none&quot; stroke=&quot;lightgrey&quot;/&gt;
   &lt;path d=&quot;${d}&quot; fill=&quot;none&quot; stroke=&quot;lightgreen&quot; 
         pathLength=&quot;100&quot; stroke-dasharray=&quot;${p} 100&quot;/&gt;
   &lt;path d=&quot;m0 -15 30 15-30 15z&quot; fill=&quot;green&quot;&gt;         
     &lt;animateMotion dur=&quot;0.001s&quot; rotate=&quot;auto&quot; fill=&quot;freeze&quot; 
                    keyPoints=&quot;0;${p/100}&quot; keyTimes=&quot;0;1&quot; calcMode=&quot;linear&quot;&gt;
        &lt;mpath href=&quot;#${id}&quot;/&gt;
      &lt;/animateMotion&gt;
    &lt;/path&gt;
    &lt;text x=&quot;50%&quot; y=&quot;50%&quot; font-size=&quot;3em&quot; text-anchor=&quot;middle&quot;&gt;${p}%&lt;/text&gt;
&lt;/svg&gt;`;
  }
})

<!-- language: lang-html -->

&lt;style&gt;
  svg { max-height: 170px }
&lt;/style&gt;

&lt;svg-percentage percentage=&quot;10&quot;&gt;&lt;/svg-percentage&gt;
&lt;svg-percentage percentage=&quot;42&quot;&gt;&lt;/svg-percentage&gt;
&lt;svg-percentage percentage=&quot;77&quot;&gt;&lt;/svg-percentage&gt;

<!-- end snippet -->

答案2

得分: 0

以下是翻译好的部分:

首先,您需要绘制一个与您的形状相匹配的路径。我的路径可能不完美,但仍然有效。

接下来,将描边的宽度设置得很大,例如40,并将描边颜色设置为“url(#progress)”。

现在,您可以使用clipPath来剪裁宽描边,使其符合您的形状。

最后,您可以将路径的描边虚线数组(stroke-dasharray)设置为所需的值。请注意,pathLength="100"

希望这些翻译对您有所帮助。

英文:

First you need to draw a path that is following your shape. Mine is not perfect but still works.

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-css -->

svg{width:90vh; border:solid;}

<!-- language: lang-html -->

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 254.25 233.26&quot;&gt;
&lt;defs&gt;
 &lt;linearGradient id=&quot;progress&quot; x1=&quot;-1&quot; &gt;
      &lt;stop id=&quot;stop1&quot; offset=&quot;0&quot; stop-color=&quot;#bb8e89&quot;/&gt;
      &lt;stop id=&quot;stop2&quot; offset=&quot;0&quot; stop-color=&quot;#f4b6b0&quot;/&gt;
    &lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;g id=&quot;Capa_2&quot; data-name=&quot;Capa 2&quot;&gt;
&lt;g id=&quot;Capa_1-2&quot; data-name=&quot;Capa 1&quot;&gt;

&lt;path fill=&quot;url(#progress)&quot; class=&quot;cls-1&quot; d=&quot;M254.25,17.72 L235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z&quot;/&gt;

  &lt;path stroke=&quot;black&quot;  fill=&quot;none&quot; id=&quot;pth&quot; d=&quot;M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

Next you set the width of the stroke to something big like 40 and you make the stroke="url(#progress)"

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-css -->

svg{border:solid; width:90vh}

<!-- language: lang-html -->

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 254.25 233.26&quot;&gt;
&lt;defs&gt;
 &lt;linearGradient id=&quot;progress&quot; x1=&quot;-1&quot; &gt;
      &lt;stop id=&quot;stop1&quot; offset=&quot;0&quot; stop-color=&quot;#bb8e89&quot;/&gt;
      &lt;stop id=&quot;stop2&quot; offset=&quot;0&quot; stop-color=&quot;#f4b6b0&quot;/&gt;
    &lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;g id=&quot;Capa_2&quot; data-name=&quot;Capa 2&quot;&gt;
&lt;g id=&quot;Capa_1-2&quot; data-name=&quot;Capa 1&quot;&gt;

&lt;path class=&quot;cls-1&quot; d=&quot;M254.25,17.72 L235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z&quot;/&gt;

  &lt;path stroke=&quot;url(#progress)&quot;  fill=&quot;none&quot; stroke-width=&quot;40&quot; clip-path=&quot;url(#cp)&quot; id=&quot;pth&quot; d=&quot;M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0&quot;/&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

Now you can use clipPath to clip the wide stroke with your shape:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-css -->

svg{border:solid; width:90vh}

<!-- language: lang-html -->

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 254.25 233.26&quot;&gt;
&lt;defs&gt;
 &lt;linearGradient id=&quot;progress&quot; x1=&quot;-1&quot; &gt;
      &lt;stop id=&quot;stop1&quot; offset=&quot;0&quot; stop-color=&quot;#bb8e89&quot;/&gt;
      &lt;stop id=&quot;stop2&quot; offset=&quot;0&quot; stop-color=&quot;#f4b6b0&quot;/&gt;
    &lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;g id=&quot;Capa_2&quot; data-name=&quot;Capa 2&quot;&gt;
&lt;g id=&quot;Capa_1-2&quot; data-name=&quot;Capa 1&quot;&gt;
  &lt;clipPath id=&quot;cp&quot;&gt;
&lt;path class=&quot;cls-1&quot; d=&quot;M254.25,17.72 L235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z&quot;/&gt;
  &lt;/clipPath&gt; 
  &lt;path stroke=&quot;url(#progress)&quot;  fill=&quot;none&quot; stroke-width=&quot;40&quot; clip-path=&quot;url(#cp)&quot; id=&quot;pth&quot; d=&quot;M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

Finaly you can set the stroke-dasharray of the path to whatever you need. Please observe that pathLength=&quot;100&quot;

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function setProgress(amt)
{
  amt = (amt &lt; 0) ? 0 : (amt &gt; 1) ? 1 : amt;
 let s= 100*amt;
  document.getElementById(&quot;pth&quot;).setAttribute(&quot;stroke-dasharray&quot;, `${s},${100 - s}`);
}


setProgress(0.60);

<!-- language: lang-css -->

svg{width:90vh;border:solid}

<!-- language: lang-html -->

&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 254.25 233.26&quot;&gt;
&lt;defs&gt;
 &lt;linearGradient id=&quot;progress&quot; x1=&quot;-1&quot; &gt;
      &lt;stop id=&quot;stop1&quot; offset=&quot;0&quot; stop-color=&quot;#bb8e89&quot;/&gt;
      &lt;stop id=&quot;stop2&quot; offset=&quot;0&quot; stop-color=&quot;#f4b6b0&quot;/&gt;
    &lt;/linearGradient&gt;
&lt;/defs&gt;
&lt;g id=&quot;Capa_2&quot; data-name=&quot;Capa 2&quot;&gt;
&lt;g id=&quot;Capa_1-2&quot; data-name=&quot;Capa 1&quot;&gt;
  &lt;clipPath id=&quot;cp&quot;&gt;
&lt;path class=&quot;cls-1&quot; d=&quot;M254.25,17.72 L235.32,0,216.38,17.72H227V92.93c0,66.6-25.41,124.48-104.17,124.48S18.63,159.53,18.63,92.93V52.35H0V92.14c0,76.11,32.18,141.12,122.79,141.12,89.77,0,122-65,122-141.12V17.72Z&quot;/&gt;
  &lt;/clipPath&gt; 
  &lt;path stroke=&quot;url(#progress)&quot;  fill=&quot;none&quot; stroke-width=&quot;40&quot; clip-path=&quot;url(#cp)&quot; id=&quot;pth&quot; d=&quot;M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0&quot; pathLength=&quot;100&quot; /&gt;
&lt;/g&gt;
&lt;/g&gt;
&lt;/svg&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月25日 10:55:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定