javascript - 带百分比的虚线圆形条
问题描述
我正在尝试用虚线制作一个圆形进度条。我以编程方式创建stroke-dasharray
并stroke-dashoffset
绘制一个带有百分比的圆圈。
而不是实心圆,我需要绘制如下所示的虚线圆:
我无法将实心圆圈更改为虚线圆圈。我是否遗漏了什么或者我需要改变我的逻辑来绘制虚线圆圈?
https://jsfiddle.net/6mu97jyL/
class CircularProgressBar extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
// Size of the enclosing square
const sqSize = this.props.sqSize;
// SVG centers the stroke width on the radius, subtract out so circle fits in square
const radius = (this.props.sqSize - this.props.strokeWidth) / 2;
// Enclose cicle in a circumscribing square
const viewBox = `0 0 ${sqSize} ${sqSize}`;
// Arc length at 100% coverage is the circle circumference
const dashArray = radius * Math.PI * 2;
// Scale 100% coverage overlay with the actual percent
const dashOffset = dashArray - dashArray * this.props.percentage / 100;
return (
<svg
width={this.props.sqSize}
height={this.props.sqSize}
viewBox={viewBox}>
<circle
className="circle-background"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`} />
<circle
className="circle-progress"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
transform={`rotate(-90 ${this.props.sqSize / 2} ${this.props.sqSize / 2})`}
style={{
strokeDasharray: dashArray,
strokeDashoffset: dashOffset
}} />
</svg>
);
}
}
CircularProgressBar.defaultProps = {
sqSize: 200,
percentage: 25,
strokeWidth: 10
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
percentage: 25
};
this.handleChangeEvent = this.handleChangeEvent.bind(this);
}
handleChangeEvent(event) {
this.setState({
percentage: event.target.value
});
}
render() {
return (
<div>
<CircularProgressBar
strokeWidth="10"
sqSize="200"
percentage={this.state.percentage}/>
<div>
<input
id="progressInput"
type="range"
min="0"
max="100"
step="1"
value={this.state.percentage}
onChange={this.handleChangeEvent}/>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
#app {
margin-top: 40px;
margin-left: 50px;
}
#progressInput {
margin: 20px auto;
width: 30%;
}
.circle-background,
.circle-progress {
fill: none;
}
.circle-background {
stroke: #ddd;
}
.circle-progress {
stroke: #F99123;
stroke-linecap: round;
stroke-linejoin: round;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<div class="container">
<div class="text-center" id="app">
</div>
</div>
解决方案
不确定这是否在您正在寻找的范围内。(下面的完整片段/演示)
我不是这个主题的专家,所以可能有另一种选择(比如两个不同样式的半圆) - 但这里基本上要做的是在实心圆的顶部放置另一个圆,并确保它具有相同的笔画颜色作为页面。然后,这将掩盖后面圆圈的间隙(基本上隐藏圆圈的一部分)。
<circle
className="circle-dashes"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
style={{
strokeDasharray: "5 10" // Adjust the spacing here
}} />
CSS:
.circle-dashes {
stroke: #FFF;
fill: none;
}
并删除
stroke-linecap: round;
stroke-linejoin: round;
一些小的调整以满足您的需要,希望您得到它!
如果您使用另一种背景颜色查看应用程序,更改可能会更明显。
class CircularProgressBar extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
// Size of the enclosing square
const sqSize = this.props.sqSize;
// SVG centers the stroke width on the radius, subtract out so circle fits in square
const radius = (this.props.sqSize - this.props.strokeWidth) / 2;
// Enclose cicle in a circumscribing square
const viewBox = `0 0 ${sqSize} ${sqSize}`;
// Arc length at 100% coverage is the circle circumference
const dashArray = radius * Math.PI * 2;
// Scale 100% coverage overlay with the actual percent
const dashOffset = dashArray - dashArray * this.props.percentage / 100;
return (
<svg
width={this.props.sqSize}
height={this.props.sqSize}
viewBox={viewBox}>
<circle
className="circle-background"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`} />
<circle
className="circle-progress"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
// Start progress marker at 12 O'Clock
transform={`rotate(-90 ${this.props.sqSize / 2} ${this.props.sqSize / 2})`}
style={{
strokeDasharray: dashArray,
strokeDashoffset: dashOffset
}} />
<circle
className="circle-dashes"
cx={this.props.sqSize / 2}
cy={this.props.sqSize / 2}
r={radius}
strokeWidth={`${this.props.strokeWidth}px`}
style={{
strokeDasharray: "5 10"
}} />
</svg>
);
}
}
CircularProgressBar.defaultProps = {
sqSize: 200,
percentage: 25,
strokeWidth: 10
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
percentage: 25
};
this.handleChangeEvent = this.handleChangeEvent.bind(this);
}
handleChangeEvent(event) {
this.setState({
percentage: event.target.value
});
}
render() {
return (
<div>
<CircularProgressBar
strokeWidth="10"
sqSize="200"
percentage={this.state.percentage}/>
<div>
<input
id="progressInput"
type="range"
min="0"
max="100"
step="1"
value={this.state.percentage}
onChange={this.handleChangeEvent}/>
</div>
</div>
);
}
}
ReactDOM.render(
<App/>,
document.getElementById('app')
);
#app {
margin-top: 40px;
margin-left: 50px;
}
#progressInput {
margin: 20px auto;
width: 30%;
}
.circle-background,
.circle-progress {
fill: none;
}
.circle-background {
stroke: #ddd;
}
.circle-dashes {
stroke: #fff;
fill: none;
}
.circle-progress {
stroke: #F99123;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div class="container">
<div class="text-center" id="app">
</div>
</div>
推荐阅读
- typescript - 正确使用 PartiQL 和 AWS 开发工具包?
- devops - Bamboo - 如何在同一构建作业中合并代码后构建最新版本
- amazon-web-services - 克隆环境时如何更改平台分支?
- python - 禁用 Python 跨行自动连接字符串
- sql - 带有字符串连接的 SQL 很慢
- reactjs - MUI DataGrid 显示 Airtable 数据
- mysql - PowerShell MySQL 插入外来字符失败
- python - RGBA 参数无效:数组
- sql - postgreSQL 可以检索的最大记录数是多少?
- reactjs - TypeError: theme.~~ 不是带有样式组件的函数