今天遇到一个问题,就是页面上有许多环形图,而且功能只需要展示比例而已,这个时候如果引用一些图表框架的话,那可能会让页面加载速度变慢,毕竟这些图表框架都不小。
所以我就想用几个DIV,再加一些CSS3的属性,希望能够解决这个问题,并且能够适配所有的PC或移动的浏览器。搜索了一些资料,有说使用css3 clip的属性,但是Opera和UC For Android是不支持这个属性的。
然后。。。突发灵感,想到了一个很变态的方法。废话不多说,先贴代码。
React 组件代码
class Circle extends PureComponent {
constructor(props) {
super(props);
this.state = {
index: 0
};
}
componentDidMount() {
let rootHeight = this.root.clientHeight / 2 + 'px';
this.rule.style.borderRightWidth = rootHeight;
this.cover.style.borderRightWidth = rootHeight;
this.draw(360);
}
/**
* 画环形图
* @param {Number} 角度的值
*/
draw(deg) {
if (deg < 0) {
deg = 0;
}
if (deg > 360) {
deg = 360;
}
if (deg < 180) {
this.cover.className = this.cover.className.replace(/add/, 'cover');
this.rotate(deg);
} else {
this.cover.className = this.cover.className.replace(/cover/, 'add');
this.rotate(deg - 180);
}
}
/**
* 旋转
* @param {Number} 旋转的角度
*/
rotate(deg) {
let ele = this.cover;
let degStr = `rotate(${deg}deg)`;
ele.style.webkitTransform = degStr;
ele.style.MozTransform = degStr;
ele.style.msTransform = degStr;
ele.style.OTransform = degStr;
ele.style.transform = degStr;
}
render() {
let { className } = this.props;
return (
<div
ref={ root => (this.root = root) }
className={ 'circle ' + (className || '') }
>
<div ref={ rule => (this.rule = rule) } className="rule" />
<div ref={ cover => (this.cover = cover) } className="rule cover" />
<div className="outter">
<div className="inner">{this.props.children}</div>
</div>
</div>
);
}
CSS代码
.circle {
margin: 120px 60px;
border-radius: 50%;
height: 120px;
width: 120px;
position: relative;
background-color: #fff;
overflow: hidden;
.rule {
position: absolute;
height: 100%;
width: 100%;
border-radius: 50%;
border-bottom: 0px;
border-left: 0px;
border-top: 0;
border-right: 30px solid red;
&.cover {
border-right-color: #fff;
}
&.add {
border-right-color: red;
}
}
.outter {
position: absolute;
left: 2px;
right: 2px;
top: 2px;
bottom: 2px;
border-radius: 50%;
background-color: #000;
text-align: center;
}
}
实现的中心思想是利用border属性,设置其上下做都为0,然后设置右宽度为容器高度的一般,再设置为环形指示的颜色,然后再加一个相同的设置的同级div,但设置其颜色为白色,通过旋转白色的div来控制显示的数值,当角度超过180时,则将该白色的div设置背景色为环形指示的颜色,再旋转角度-180.
比较另类的解决思路,最后得到以下的效果。
关键字:DIV画曲线,DIV画扇形,环形图,饼图