【需求效果图:如上图所示】
需求:动态获取不同的分数,圆环展示对应的百分比分数值:
- 正确率 70%以下提示文案:还需要继续加油哦~
- 正确率 70% - 90%以下提示文案:不错,再加把劲~
- 正确率 90%及以上提示文案:真棒!
数据描述:不同的测试分数显示不同的分数百分比
百分比分数字段:score
因为分数是动态获取的,所以 在React中,肯定是需要通过state来更改分数的百分比的.
我先解释一下代码实现的原理,看懂原理后,实现起来就很轻松了。
【以下有图有真相,图片更方便你理解原理】
![这里写图片描述](https://img-blog.csdn.net/2018041300262065?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMDcyNTkz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
外层的实心圆其实就是一个border为5px(线条粗一点的)实线而已。通过transform: rotate()
和transition: transform 1s;
来控制旋转角度和1s的进度条动画波动。
大圆的进度条:
可以划分为 左右两部分:
左半部分又分为左上部分和左下部分构成。
右半部分又分为右上部分和右下部分构成。
![这里写图片描述](https://img-blog.csdn.net/2018041308555935?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMDcyNTkz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
配合上面的动图和我画的那张图,结合上面的解释,应该就可以把页面开发好了,如果你开发圆形动图遇到和我上面效果图实现的不一样,可以参考我下面的代码,我贴出来了。【注:如果你不会React的项目,请把里面涉及到React的代码去掉,用假数据写在标签里就可以了】
html 样式:
<div className="interview_score">
<div className="circleProgress_wrapper">
<span className="correct_rate">正确率</span>
<span className="correct_score">
<span className="">{this.state.score}</span>
<span>%</span>
</span>
<div className="wrapper left">
<div className="circleProgress leftcircle" style={scoreProgress_left}></div>
</div>
<div className="wrapper right">
<div className="circleProgress rightcircle" style={scoreProgress_right}></div>
</div>
</div>
<div className="flag_scores">
{userScore}
<img src={flag} alt=""/> //flag是分数判断之后文字描述的那个红色的背景图片
</div>
</div>
css样式:
.interview_score {
padding-top: 40px;
.circleProgress_wrapper {
width: 180px;
height: 180px;
position: relative;
border: 1px solid #0d546c;
margin: 0 auto;
border-radius: 50%;
.correct_rate {
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
font-size: 18px;
color: #0d546c;
}
.correct_score {
position: absolute;
top: 60px;
left: 50%;
transform: translateX(-50%);
font-size: 50px;
color: #0d546c;
span:last-of-type {
margin-left: 3px;
font-size: 25px;
}
}
}
.wrapper {
width: 90px;
height: 180px;
position: absolute;
top: 0;
overflow: hidden;
}
.right {
right: 0;
}
.left {
left: 0;
}
.circleProgress {
width: 170px;
height: 170px;
box-sizing: content-box;
border: 5px solid transparent;
border-radius: 50%;
position: absolute;
top: 0;
transform: rotate(-135deg);
}
.rightcircle {
transition: transform 1s;
transition-delay: 1s;
border-top: 5px solid #0d546c;
border-right: 5px solid #0d546c;
right: 0;
}
.leftcircle {
transition: transform 1s;
border-bottom: 5px solid #0d546c;
border-left: 5px solid #0d546c;
left: 0;
}
.flag_scores {
text-align: center;
top: -20px;
position: relative;
span {
position: absolute;
width: 140px;
height: 30px;
line-height: 30px;
text-align: center;
left: 50%;
top: 50%;
margin-left: -67px;
margin-top: -17px;
color: #fff;
}
img {
width: 210px;
display: block;
margin: 0 auto;
}
}
}
js 逻辑:
上面的html和css代码可以实现一个circle圆形滑动的效果了,下面就是根据不同的分数实现不同的百分比显示不同的circle圆形加载了。
// 构造函数里初始数据设置score为0分:
this.state = {
score: 0
}
// 页面初始化加载的时候,去获取你当前的score是多少,就显示多少:
componDidMount() {
this.setState = ({
score: this.props.score
})
}
// 这里显示不同的score,红色背景flag里面显示不同的文字。
let userScore, scoreProgress_left, scoreProgress_right
if (this.state.score < 70) {
userScore = (
<span> 还需要继续加油哦~</span>
)
} else if (this.state.score >= 70 && this.state.score <= 90) {
userScore = (
<span> 不错,再加把劲~</span>
)
} else {
userScore = (
<span> 真棒!</span>
)
}
`将长方形内部的半圆向右(顺时针)旋转45度,就可以得到进度覆盖整个背景的图像。
将半圆向左(逆时针)旋转135度就能得到只有进度条背景的图像。
为什么又要向左旋转,而不是一直向右旋转,
当然是因为要实现的效果是:进度是从顶部开始,顺时走完的`
if (this.state.score >= 0 && this.state.score <= 50) {
const rotate = -135 + 18 / 5 * this.state.score
scoreProgress_left = {
transform: `rotate(${rotate}deg)`
}
scoreProgress_right = {
transform: `rotate(-135deg)`
}
} else {
const rotate = -135 + 18 / 5 * (this.state.score - 50)
scoreProgress_left = {
transform: `rotate(45deg)`
}
scoreProgress_right = {
transform: `rotate(${rotate}deg)`
}
}
基本上上面的逻辑和操作就可以实现circle圆环进度条加载的效果了 ~