英文:
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..
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
<!-- language: lang-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>
<!-- 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>
创建:
仅为 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="[percentage] 100"
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
<svg-percentage percentage="10"></svg-percentage>
<svg-percentage percentage="42"></svg-percentage>
<svg-percentage percentage="77"></svg-percentage>
creates:
Added an onclick
for Stack Overflow Snippet demo only
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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; // create a unique 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>`;
}
})
<!-- language: lang-html -->
<style>
svg { max-height: 170px }
</style>
<svg-percentage percentage="10"></svg-percentage>
<svg-percentage percentage="42"></svg-percentage>
<svg-percentage percentage="77"></svg-percentage>
<!-- 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 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.25 233.26">
<defs>
<linearGradient id="progress" x1="-1" >
<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 fill="url(#progress)" class="cls-1" d="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"/>
<path stroke="black" fill="none" id="pth" d="M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0" />
</g>
</g>
</svg>
<!-- 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 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.25 233.26">
<defs>
<linearGradient id="progress" x1="-1" >
<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" d="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"/>
<path stroke="url(#progress)" fill="none" stroke-width="40" clip-path="url(#cp)" id="pth" d="M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0"/>
</g>
</g>
</svg>
<!-- 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 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.25 233.26">
<defs>
<linearGradient id="progress" x1="-1" >
<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">
<clipPath id="cp">
<path class="cls-1" d="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"/>
</clipPath>
<path stroke="url(#progress)" fill="none" stroke-width="40" clip-path="url(#cp)" id="pth" d="M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0" />
</g>
</g>
</svg>
<!-- end snippet -->
Finaly you can set the stroke-dasharray of the path to whatever you need. Please observe that pathLength="100"
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
function setProgress(amt)
{
amt = (amt < 0) ? 0 : (amt > 1) ? 1 : amt;
let s= 100*amt;
document.getElementById("pth").setAttribute("stroke-dasharray", `${s},${100 - s}`);
}
setProgress(0.60);
<!-- language: lang-css -->
svg{width:90vh;border:solid}
<!-- language: lang-html -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 254.25 233.26">
<defs>
<linearGradient id="progress" x1="-1" >
<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">
<clipPath id="cp">
<path class="cls-1" d="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"/>
</clipPath>
<path stroke="url(#progress)" fill="none" stroke-width="40" clip-path="url(#cp)" id="pth" d="M10,52L10,92.14C10,273 240,273 235.32,92.14L235.32,0" pathLength="100" />
</g>
</g>
</svg>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论