본문 바로가기

Front-End/HTML_CSS

[Typescript, CSS] Circular Progress Bar 만들기

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

 

Building Two Different Types of Progress Bars

Learn how to create a couple of progress bars with React & Typescript.

buildingthingswithjavascript.com