육각형 이미지
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]
}