import colors from "@/styles/color";
import React, { ReactElement } from "react";
import styled from "styled-components";
type Props = {
progress: number;
label?: string;
width?: number;
imageUrl: string;
};
export default function CircularProgressBar({
progress,
label = "Progress Bar",
width = 100,
imageUrl,
}: Props): ReactElement {
const strokeWidth = 3;
const radius = 100 / 2 - strokeWidth * 2;
const circumference = radius * 2 * Math.PI;
const offset = circumference - (progress / 100) * circumference;
console.log(radius);
return (
<svg
aria-label={label}
aria-valuemax={100}
aria-valuemin={0}
aria-valuenow={progress}
height={width}
role="progressbar"
width={width}
viewBox="0 0 100 100"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<clipPath id="circleView">
<circle cx="50" cy="50" r={radius} />
</clipPath>
</defs>
<image
clip-path="url(#circleView)" // 클립 패스를 이미지에 적용합니다.
href={imageUrl} // 이미지 URL을 href 속성으로 설정합니다.
height="100"
width="100"
x="0"
y="0"
/>
<Circle cx="50" cy="50" r={radius} strokeWidth={strokeWidth} />
<FilledCircle
cx="50"
cy="50"
data-testid="progress-bar-bar"
r={radius}
strokeDasharray={`${circumference} ${circumference}`}
strokeDashoffset={offset}
strokeWidth={strokeWidth}
/>
</svg>
);
}
const Circle = styled.circle`
fill: transparent;
stroke: #d9d9d9;
stroke-linecap: round;
`;
const FilledCircle = styled(Circle)`
stroke: ${colors.primary};
transform: rotate(-90deg);
transform-origin: 50% 50%;
transition: stroke-dashoffset 0.5s ease-out;
`;
사용은 다음과 같이 해주면 된다.
<CircularProgressBar
progress={70}
width={100}
imageUrl="image_url"
/>
그러면 이렇게 예뿌게 짠! 하고 나온다.
저 왼쪽에 파란색 직각삼각형은 모른 척 해주세용 🥲
이게 뭐라고.. 구현하는 데 진짜 오래 걸렸다.
ㅜㅜ
[참고]
https://buildingthingswithjavascript.com/articles/building-two-different-types-of-progress-bars
'Front-End > HTML_CSS' 카테고리의 다른 글
[CSS] CSS-Flex Link Archive (0) | 2023.11.06 |
---|---|
[CSS] tsx 내의 string에서 줄바꿈이 안되는 문제 해결 (0) | 2023.09.22 |
[CSS] position: fixed일 때 상하스크롤이 안되는 문제 해결 (0) | 2023.06.12 |
[HTML/CSS] 220318 학습일기 (0) | 2023.03.19 |
[HTML/CSS] 220317 학습일기 (0) | 2023.03.18 |