【问题标题】:how to make svg curve at one end如何在一端制作svg曲线
【发布时间】:2021-06-28 06:12:14
【问题描述】:
我使用 svg 作为圆形进度条,我想制作一端曲线而不是两端。这怎么可能 ?
如何在 svg 中实现一条末端曲线?
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
@keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>
【问题讨论】:
标签:
javascript
css
web
svg
【解决方案1】:
最简单的方法是掩盖蓝色圆圈的起点。
为此,您将需要一个<mask>,如下所示:
<mask id="m">
<rect width="100" height="100" fill="white"/>
<rect x="85" y="40" width="10" height="10" />
</mask>
请注意第一个矩形是白色的,它覆盖了整个图表。 (白色像素下的所有内容都将可见)。较小的矩形是黑色的,覆盖了蓝色圆圈的起点。黑色像素下的所有内容都将不可见。
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
@keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<mask id="m">
<rect width="100" height="100" fill="white"/>
<rect x="85" y="40" width="10" height="10" />
</mask>
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" mask="url(#m)" />
</svg>
【解决方案2】:
试试这个代码:
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
border-top-right-radius: 20px;
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
@keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>
【解决方案3】:
我想出了一个比enxaneta 建议的替代解决方案。使用蒙版的问题是,当您的值超过 96% 左右时,圆圈没有完全填满,蒙版会显露出来。
相反,您可以在另一条平头的进度线之上设置圆形进度线。将圆形的进度线旋转大约 5 度,露出平坦的一端。
下面是在 React Native 中使用 react-native-svg 的方法:
const radius = 60;
let myPercentage = 40;
const circleCircumference = 2 * Math.PI * radius;
const valueOffset = circleCircumference -
(circleCircumference * myPercentage * 0.98) / 100;
<Svg height={radius * 2 + 30} width={radius * 2 + 30}>
<G rotation={-90} originX={radius + 15} originY={radius + 15}>
// Background gray circle
<Circle
cx="50%"
cy="50%"
r={radius}
stroke="rgb(60, 60, 60)"
fill="transparent"
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeLinecap="butt"
/>
// Background progress circle with flat ends
<Circle
cx="50%"
cy="50%"
r={radius}
stroke={"rgb(0, 51, 204)"}
fill="transparent"
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeDashoffset={valueOffset}
strokeLinecap="butt"
/>
// Progress circle with round ends rotated by 5 degrees
<Circle
cx="50%"
cy="50%"
r={radius}
stroke={rgb(0, 51, 204)}
fill="transparent"
rotation={5}
originX={radius + 15}
originY={radius + 15}
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeDashoffset={valueOffset}
strokeLinecap="round"
/>
</G>
</Svg>