75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
import React from 'react';
|
|
import styled from 'styled-components';
|
|
|
|
// 원형 프로그레스 컴포넌트
|
|
const CircularProgress = ({
|
|
progress,
|
|
size = 40,
|
|
strokeWidth,
|
|
backgroundColor = '#E0E0E0',
|
|
progressColor = '#4A90E2',
|
|
textColor = '#4A90E2',
|
|
showText = true,
|
|
textSize,
|
|
className
|
|
}) => {
|
|
// 기본값 계산
|
|
const actualStrokeWidth = strokeWidth || size * 0.1; // 프로그레스 바 두께
|
|
const radius = (size - actualStrokeWidth) / 2; // 원의 반지름
|
|
const circumference = 2 * Math.PI * radius; // 원의 둘레
|
|
const strokeDashoffset = circumference - (progress / 100) * circumference; // 진행률에 따른 offset 계산
|
|
const actualTextSize = textSize || Math.max(10, size * 0.3); // 텍스트 크기
|
|
|
|
return (
|
|
<ProgressContainer size={size} className={className}>
|
|
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
|
|
{/* 배경 원 */}
|
|
<circle
|
|
cx={size / 2}
|
|
cy={size / 2}
|
|
r={radius}
|
|
fill="none"
|
|
stroke={backgroundColor}
|
|
strokeWidth={actualStrokeWidth}
|
|
/>
|
|
{/* 진행률 표시 원 */}
|
|
<circle
|
|
cx={size / 2}
|
|
cy={size / 2}
|
|
r={radius}
|
|
fill="none"
|
|
stroke={progressColor}
|
|
strokeWidth={actualStrokeWidth}
|
|
strokeDasharray={circumference}
|
|
strokeDashoffset={strokeDashoffset}
|
|
strokeLinecap="round"
|
|
transform={`rotate(-90 ${size / 2} ${size / 2})`}
|
|
/>
|
|
</svg>
|
|
{showText && (
|
|
<ProgressText color={textColor} fontSize={actualTextSize}>
|
|
{`${Math.round(progress)}%`}
|
|
</ProgressText>
|
|
)}
|
|
</ProgressContainer>
|
|
);
|
|
};
|
|
|
|
export default CircularProgress;
|
|
|
|
// 스타일 컴포넌트
|
|
const ProgressContainer = styled.div`
|
|
position: relative;
|
|
width: ${props => props.size}px;
|
|
height: ${props => props.size}px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
`;
|
|
|
|
const ProgressText = styled.div`
|
|
position: absolute;
|
|
font-size: ${props => props.fontSize}px;
|
|
font-weight: bold;
|
|
color: ${props => props.color};
|
|
`; |