开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天
效果图
画圆弧:
使用clip-path五点画圆弧:
- 第一个点: 圆点
- 第二个点:圆弧开始起点
- 第三和第四个点:把起点和重点的弧线分成均等三段的两个点
- 第五个点:终点
圆外的四个点距离圆心是2r。为什么是2r呢?
因为当圆弧是360度(也就是一个圆时),点与点两两连线,线刚刚好与圆相切,
灰色圆弧背景
写一个灰色圆环作为背景即可
圆环:圆角边框+mask(遮盖) 实现
注意点:
1.角度的方向:
2.Math.sin js涉及角度的Math函数里面的参数都是弧度值(就是2Math.PI=360,用的是前者)
使用组件主要需要六个参数:
startAngle={324} //弧线起始角度
angle={252} //弧线横跨角度
innerRadius={40} //内圆半径
outerRadius={60} //外圆半径
color={['#1ADBFF', '#45FF9D', '#F2BB00', '#FF6726']} //弧型渐变颜色数组
percent={arcPercent} //弧线站总弧线的百分比
圆弧组件:yuanhu/index.jsx
import React, { Component } from 'react';
import "./index.css"
import {creatPolygon} from "./polygon"
class Yuanhu extends Component {
addColor=()=>{
const {color,angle}=this.props
const {length}=color
const fillNum=length/(angle/360);
let fillColor=color;
for(let i =0;i<(fillNum-length);i++){
fillColor.push("red")
}
return fillColor
}
render() {
const {
startAngle,
angle,
innerRadius,
outerRadius,
color,
percent
}=this.props
const width=outerRadius*2
console.log(color);
// startAngle=startAngle-90
const params=creatPolygon(startAngle,angle,width,percent);
console.log(params);
return (
<div>
<div
className="test"
style={{
width:`${width}px`,
height:`${width}px`,
borderRadius:`50%`,
transform: `rotate(${startAngle -90}deg)`,
background:`conic-gradient(${this.addColor()})`,
WebkitMask:`radial-gradient(transparent ${innerRadius}px, #000 ${innerRadius}px)`,
mask: `radial-gradient(transparent ${innerRadius}, #000 ${innerRadius})`,
clipPath:`polygon(${params})`,
}}
></div>
</div>
);
}
}
export default Yuanhu;
yuanhu/polygon.js--生成clip-path需要的参数
export function creatPolygon(startAngle,angle,width,percent){
const r=width/2;
startAngle=(startAngle/180)*Math.PI
const ang=(((angle/180)*Math.PI)/3)*percent; //均等分角度
console.log("ang:",ang);
const x=width/2; //圆心x坐标
const y=width/2; //圆心y坐标
const as1=2*r*Math.sin(startAngle)
const ac1=2*r*Math.cos(startAngle)
const as2=2*r*Math.sin(startAngle+ang);
const ac2=2*r*Math.cos(startAngle+ang)
const as3=2*r*Math.sin(startAngle+2*ang);
const ac3=2*r*Math.cos(startAngle+2*ang)
const as4=2*r*Math.sin(startAngle+3*ang)
const ac4=2*r*Math.cos(startAngle+3*ang)
let p1=[x,y];
let p2=[x+as1,y-ac1]
let p3=[x+as2,y-ac2]
let p4=[x+as3,y-ac3]
let p5=[x+as4,y-ac4]
console.log("p2:",p2);
return [p1, p2, p3, p4, p5]
.map((arr) => {
return arr
.map((pos) => {
return `${pos}px`;
})
.join(' ');
})
.join();
}
圆弧组件的使用:yuanhu-item/index.jsx
import React, { Component } from 'react';
import Yuanhu from '../yuanhu';
import "./index.css"
class YuanhuItem extends Component {
render() {
return (
<div className='yuanhu-box'>
<div className='yuanhu-bg'></div>
<Yuanhu
startAngle={-30}
angle={268}
innerRadius={40}
outerRadius={60}
color={['#1ADBFF', '#45FF9D', '#F2BB00', '#FF6726']}
percent={0.5}
/>
</div>
);
}
}
export default YuanhuItem;
圆弧使用组件的样式
yuanhu-item/index.css
.yuanhu-box{
width: 120px;
height: 80px;
position: absolute;
overflow: hidden;
}
.yuanhu-bg{
width: 120px;
height: 120px;
border-radius: 50%;
background-color: #ccc;
mask: radial-gradient(transparent 40px,#000 40px);
position: absolute;
}
app.js
import React, { Component,Fragment } from 'react'
import YuanhuItem from './components/10-yuanhu/yuanhu-item'
export default class App extends Component {
render() {
return (
<Fragment>
<h1>app组件</h1>
<YuanhuItem/>
</Fragment>
)
}
}