Skip to content

육각형 이미지

jsx
<svg
    xmlns="http://www.w3.org/2000/svg"
    width="2.25rem"
    height="2.25rem"
    viewBox="0 0 35 35"
    aria-labelledby="title"
>
    <defs>
        <clipPath id="image">
            <use xlinkHref="#clipPath"/>
        </clipPath>
    </defs>
    <title id="title">My nft</title>
    <path
        id="clipPath"
        style={{
            fill: "none",
            stroke: "#000",
            strokeWidth: 2,
        }}
        d="M15.5 0.65470053837926a4 4 0 0 1 4 0l11.58845726812 6.6905989232415a4 4 0 0 1 2 3.4641016151378l0 13.381197846483a4 4 0 0 1 -2 3.4641016151378l-11.58845726812 6.6905989232415a4 4 0 0 1 -4 0l-11.58845726812 -6.6905989232415a4 4 0 0 1 -2 -3.4641016151378l0 -13.381197846483a4 4 0 0 1 2 -3.4641016151378"
    />
    <image
        clipPath="url(#image)"
        height="100%"
        width="100%"
        xlinkHref={imageUrl}
        preserveAspectRatio="xMidYMin slice"
    ></image>
</svg>

SVG 아이콘

custom.d.ts

svg 확장자 파일 인식하도록함.

ts
declare module "*.svg" {
  import React = require("react");
  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

loader.ts

svg 아이콘을 Map에 등록함

ts
type IconType = 'My Icon' | 'My Icon2'

export const loader: Map<IconType, () => Promise<typeof import("*.svg")>> =
  new Map()
    .set("My Icon", () => import("./assets/My Icon.svg"))

Icon.tsx

loader를 사용해서 아이콘을 동적 로딩함

tsx
export const Icon = ({ className, iconType }: Props) => {
  const [IconComponent, setIconComponent] = useState<React.FC<
    React.SVGProps<SVGSVGElement>
  > | null>(null);

  useEffect(() => {
    const iconLoader = loader.get(iconType);
    if (iconLoader) {
      iconLoader().then((result) => {
        setIconComponent(() => result.ReactComponent);
      });
    }
  }, [iconType]);

  return IconComponent ? (
    <IconComponent className={className} />
  ) : (
    IconComponent
  );
};

circle-css.html

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .progress {
      width: 150px;
      height: 150px;
      /* 프로그래스가 12시 방향으로 시작하기 위함 */
      transform: rotate(-90deg)
    }
    .progress .gray-circle,
    .progress .point-circle {
      cx: 75px; /* width의 절반 */
      cy: 75px; /* height의 절반 */
      fill: none;
    }
    .progress .gray-circle {
      stroke: #ddd;
      stroke-width: 2;
    }
    .progress .point-circle {
      stroke: #50d07b;
      stroke-width: 4;
      /* javascript로 동적으로 가능하지만, 반지름이 고정임으로 고정값으로 넣을 수 있음 */
      /* 2 * Math.PI * radius */
      /* calc(2 * 3.141592653589793 * 71) */
      stroke-dasharray: 446;
      /* calc(446 * (100 - 70) / 100) */
      stroke-dashoffset: 133.8
    }
  </style>
</head>
<body>
<svg
  class="progress"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
>
<!--  radius = width / 2 - stroke-width -->
  <circle
    class="gray-circle"
    r="73"
  ></circle>
<!--  radius = width / 2 - stroke-width -->
  <circle
    class="point-circle"
    r="71"
  ></circle>
</svg>
</body>
</html>

circle-css-with-text.html

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .progress-wrapper {
      position: relative;
    }
    .progress-text {
      position: absolute;
      left: 0;
      top: 0;
      width: 150px;
      text-align: center;
      line-height: 150px;
      font-size: 30px;
      color: #3198F5;
    }
    .progress {
      width: 150px;
      height: 150px;
      /* 프로그래스가 12시 방향으로 시작하기 위함 */
      transform: rotate(-90deg)
    }
    .progress .gray-circle,
    .progress .point-circle {
      cx: 75px; /* width의 절반 */
      cy: 75px; /* height의 절반 */
      fill: none;
    }
    .progress .gray-circle {
      stroke: #ddd;
      stroke-width: 2;
    }
    .progress .point-circle {
      stroke: #3198F5;
      stroke-width: 4;
    }
  </style>
</head>
<body>
<div class="progress-wrapper">
  <svg
    class="progress"
    version="1.1"
    xmlns="http://www.w3.org/2000/svg"
  >
  <!--  radius = width / 2 - stroke-width -->
    <circle
      class="gray-circle"
      r="73"
    ></circle>
  <!--  radius = width / 2 - stroke-width -->
    <circle
      class="point-circle"
      r="71"
    ></circle>
  </svg>
  <span class="progress-text">70%</span>
</div>
<script>

  // 원의 둘레값
  const getCircumference = (radius) => 2 * Math.PI * radius

  const getStrokeDashoffset = (percentage, circumference) => {
    const offset = (100 - percentage) / 100
    return circumference * offset
  }

  window.onload = () => {
    const pointCircle = document.querySelector('.point-circle')

    // 반지름
    const radius = pointCircle.getAttribute('r')
    // 원의 둘레
    const circumference = getCircumference(radius)

    const percentage = 70

    pointCircle.setAttribute('stroke-dashoffset', getStrokeDashoffset(percentage, circumference))
    pointCircle.setAttribute('stroke-dasharray', circumference)
  }
</script>
</body>
</html>

circle-js.html

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .progress {
      width: 150px;
      height: 150px;
      /* 프로그래스가 12시 방향으로 시작하기 위함 */
      transform: rotate(-90deg)
    }
    .progress .gray-circle,
    .progress .point-circle {
      cx: 75px; /* width의 절반 */
      cy: 75px; /* height의 절반 */
      fill: none;
    }
    .progress .gray-circle {
      stroke: #ddd;
      stroke-width: 2;
    }
    .progress .point-circle {
      stroke: #50d07b;
      stroke-width: 4;
    }
  </style>
</head>
<body>
<svg
  class="progress"
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
>
<!--  radius = width / 2 - stroke-width -->
  <circle
    class="gray-circle"
    r="73"
  ></circle>
<!--  radius = width / 2 - stroke-width -->
  <circle
    class="point-circle"
    r="71"
  ></circle>
</svg>
<script>

  // 원의 둘레값
  const getCircumference = (radius) => 2 * Math.PI * radius

  const getStrokeDashoffset = (percentage, circumference) => {
    const offset = (100 - percentage) / 100
    return circumference * offset
  }

  window.onload = () => {
    const pointCircle = document.querySelector('.point-circle')

    // 반지름
    const radius = pointCircle.getAttribute('r')
    // 원의 둘레
    const circumference = getCircumference(radius)

    const percentage = 70

    pointCircle.setAttribute('stroke-dashoffset', getStrokeDashoffset(percentage, circumference))
    pointCircle.setAttribute('stroke-dasharray', circumference)
  }
</script>
</body>
</html>

svg-parser.js

js
const parseSVG = (template) => {
  var tmp = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  tmp.innerHTML = template
  return tmp.children[0]
}