react 画一个渐变圆弧(渐变,圆弧)

664 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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>
		)
	}
}