分段的 SVG 轮廓圆
Segemented SVG Outlined Circle
在此先感谢您的帮助!
我正在尝试构建一个 SVG 圆圈,它没有填充只有一个轮廓并且被分成 3 个部分。
我设法找到了一个主题,向我展示了如何将一个圆分成 4 个部分(参见代码片段),但我对 SVG 还很陌生,所以我真的不知道发生了什么,也不知道如何得到这个到 3 个部分,只有轮廓。
我附上了显示圈子结果的屏幕截图。我不想要段的任何可见标志,但我希望能够单独使用每个段。 (基本上,当您向下滚动页面时,我将创建一个圆圈自行完成的页面。)
<svg width="200" height="200" viewBox="0 0 200 200">
<g transform="translate(100,100)" stroke="#000" stroke-width="2">
<path d="M0 0-70 70A99 99 0 0 1-70-70Z" fill="none"/>
<path d="M0 0-70-70A99 99 0 0 1 70-70Z" fill="none"/>
<path d="M0 0 70-70A99 99 0 0 1 70 70Z" fill="none"/>
<path d="M0 0 70 70A99 99 0 0 1-70 70Z" fill="none"/>
</g>
</svg>
您需要计算每条弧线的起点和终点。因为你想要 3 个弧,所以使用的角度是圆的 1/3,即 2*Math.PI/3.
请阅读代码中的注释。
//the circle's radius
let r = 70;
//points used for the start and end of every arc
let points =[];
//the paths
let ps = document.querySelectorAll("path");
//calculating the points used for the start and end of every arc
for(let angle = -Math.PI/2; angle < 2*Math.PI; angle += 2*Math.PI/3 ){
let point = {}
point.x = r * Math.cos(angle);
point.y = r * Math.sin(angle);
points.push(point)
}
//defining the valueof the d attribute of every path as an arc with the given radius, starting at the previous point and ending at the actual point
for(let i = 0,l=points.length; i<l-1; i++){
let point = points[i+1];
let prev = points[i]
let d = `M${prev.x},${prev.y} A${r},${r},0,0,1,${point.x},${point.y}`
//setting the d attribute
ps[i].setAttribute("d",d);
}
svg{border:solid}
<svg viewBox="-100 -100 200 200" width="300" fill="none" stroke-width="20">
<path stroke="gold"/>
<path stroke="skyBlue"/>
<path stroke="tomato"/>
</svg>
让本机 Web 组件 <svg-segments>
代替所有数学运算。
created SVG <path>
中的重要部分是 pathLength
和 stroke-dasharray
值
您指定的 All 是一个 字符串 颜色定义绘制的颜色段的数量和颜色。
none 颜色将创建一个空段:
<svg-segments parts="red,,blue"></svg-segments>
在下面的 SO 片段中;单击圆圈以添加更多细分
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:10px;background:grey">
<svg-segments parts="red,green,blue"></svg-segments>
<svg-segments parts="red,,blue"></svg-segments>
<svg-segments parts=",,red"></svg-segments>
<svg-segments parts="red,green,blue,purple" width="5"></svg-segments>
<svg-segments parts="red,,,green,,blue,,red,red" width="50"></svg-segments>
</div>
<script>
customElements.define("svg-segments", class extends HTMLElement {
static get observedAttributes() {
return ["parts", "size"]; // svg is redrawn at *every* attribute update!
}
attributeChangedCallback() {
this.parts = this.getAttribute("parts").split(",");
let vb = 200; // viewPort size; might need to tweak this
let width = this.getAttribute("width") || 25; // stroke-width
let a = vb / 2 - width/2; // calculate circle arcs
let b = vb - width;
this.innerHTML = `<svg viewBox='0 0 ${vb} ${vb}'>` +
this.parts.map((col, idx) => {
if (col)
return `<path d='M${width/2},${vb/2}a${a},${a} 0 1,0 ${b},0a${a},${a} 0 1,0 -${b},0'
fill='none' stroke-width='${width}' pathLength='${this.parts.length}'
stroke='${col}' stroke-dashoffset='${idx}'
stroke-dasharray='1 ${this.parts.length-1}'/>`;
else return ``;
}) + `</svg>`;
}
connectedCallback() {// for Whosebug Snippet demo purpose only
this.onclick = (evt) => {
let moreparts = this.parts.join(",") + ",red";
this.setAttribute("parts", moreparts);
}
}
})
</script>
SVG 在计算时有一些怪癖 path-arcs,当您看到伪像(红色)时,您可能需要将视口尺寸调整到更高的尺寸:
或re-factor使用<circle>
在此先感谢您的帮助!
我正在尝试构建一个 SVG 圆圈,它没有填充只有一个轮廓并且被分成 3 个部分。
我设法找到了一个主题,向我展示了如何将一个圆分成 4 个部分(参见代码片段),但我对 SVG 还很陌生,所以我真的不知道发生了什么,也不知道如何得到这个到 3 个部分,只有轮廓。
我附上了显示圈子结果的屏幕截图。我不想要段的任何可见标志,但我希望能够单独使用每个段。 (基本上,当您向下滚动页面时,我将创建一个圆圈自行完成的页面。)
<svg width="200" height="200" viewBox="0 0 200 200">
<g transform="translate(100,100)" stroke="#000" stroke-width="2">
<path d="M0 0-70 70A99 99 0 0 1-70-70Z" fill="none"/>
<path d="M0 0-70-70A99 99 0 0 1 70-70Z" fill="none"/>
<path d="M0 0 70-70A99 99 0 0 1 70 70Z" fill="none"/>
<path d="M0 0 70 70A99 99 0 0 1-70 70Z" fill="none"/>
</g>
</svg>
您需要计算每条弧线的起点和终点。因为你想要 3 个弧,所以使用的角度是圆的 1/3,即 2*Math.PI/3.
请阅读代码中的注释。
//the circle's radius
let r = 70;
//points used for the start and end of every arc
let points =[];
//the paths
let ps = document.querySelectorAll("path");
//calculating the points used for the start and end of every arc
for(let angle = -Math.PI/2; angle < 2*Math.PI; angle += 2*Math.PI/3 ){
let point = {}
point.x = r * Math.cos(angle);
point.y = r * Math.sin(angle);
points.push(point)
}
//defining the valueof the d attribute of every path as an arc with the given radius, starting at the previous point and ending at the actual point
for(let i = 0,l=points.length; i<l-1; i++){
let point = points[i+1];
let prev = points[i]
let d = `M${prev.x},${prev.y} A${r},${r},0,0,1,${point.x},${point.y}`
//setting the d attribute
ps[i].setAttribute("d",d);
}
svg{border:solid}
<svg viewBox="-100 -100 200 200" width="300" fill="none" stroke-width="20">
<path stroke="gold"/>
<path stroke="skyBlue"/>
<path stroke="tomato"/>
</svg>
让本机 Web 组件 <svg-segments>
代替所有数学运算。
created SVG <path>
中的重要部分是 pathLength
和 stroke-dasharray
值
All 是一个 字符串 颜色定义绘制的颜色段的数量和颜色。
none 颜色将创建一个空段:
<svg-segments parts="red,,blue"></svg-segments>
在下面的 SO 片段中;单击圆圈以添加更多细分
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:10px;background:grey">
<svg-segments parts="red,green,blue"></svg-segments>
<svg-segments parts="red,,blue"></svg-segments>
<svg-segments parts=",,red"></svg-segments>
<svg-segments parts="red,green,blue,purple" width="5"></svg-segments>
<svg-segments parts="red,,,green,,blue,,red,red" width="50"></svg-segments>
</div>
<script>
customElements.define("svg-segments", class extends HTMLElement {
static get observedAttributes() {
return ["parts", "size"]; // svg is redrawn at *every* attribute update!
}
attributeChangedCallback() {
this.parts = this.getAttribute("parts").split(",");
let vb = 200; // viewPort size; might need to tweak this
let width = this.getAttribute("width") || 25; // stroke-width
let a = vb / 2 - width/2; // calculate circle arcs
let b = vb - width;
this.innerHTML = `<svg viewBox='0 0 ${vb} ${vb}'>` +
this.parts.map((col, idx) => {
if (col)
return `<path d='M${width/2},${vb/2}a${a},${a} 0 1,0 ${b},0a${a},${a} 0 1,0 -${b},0'
fill='none' stroke-width='${width}' pathLength='${this.parts.length}'
stroke='${col}' stroke-dashoffset='${idx}'
stroke-dasharray='1 ${this.parts.length-1}'/>`;
else return ``;
}) + `</svg>`;
}
connectedCallback() {// for Whosebug Snippet demo purpose only
this.onclick = (evt) => {
let moreparts = this.parts.join(",") + ",red";
this.setAttribute("parts", moreparts);
}
}
})
</script>
SVG 在计算时有一些怪癖 path-arcs,当您看到伪像(红色)时,您可能需要将视口尺寸调整到更高的尺寸:
或re-factor使用<circle>