728x90

[Project][SVG] Text를 그려보자!


SVG 에는 text 태그를 이용해 원하는 text를 표현할 수 있습니다.

x,y 속성을 통해서 위치를 정하고, textAnchor 나 alignmentBaseline 등으로 text를 좌표기준 정렬 시킬수 있습니다.

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text

전체 코드


// src\project\s\svg\components\text.js

// modules
import React, { useRef, forwardRef, useEffect, useState } from "react";

const Text = forwardRef(({ x, y, children, config = {} }, ref) => {
  const textRef = ref || useRef();
  const [options, setOptions] = useState({
    textAnchor: "middle",
    alignmentBaseline: "middle",
  });
  useEffect(() => {
    setOptions((p) => ({ ...p, ...config }));
  }, [config]);
  return (
    <text x={x} y={y} {...options} ref={textRef}>
      {children}
    </text>
  );
});

export default Text;

Arc를 그릴때와 마찬가지로 forwardRef 를 통해 부모 컴포넌트에서 tex 컴포넌트를 접근할 수 있도록합니다.

Arc 그리지 → https://twentytwentyone.tistory.com/122

이번에는 props로 넘어온 options을 text에 spread operator로 넘겨주어 따로 props 값을 지정해주는 수고를 덜었습니다.

데모는 아래의 링크에서 확인할 수 있습니다.

http://localhost:8080/work/s/svg

728x90

'project > svg' 카테고리의 다른 글

[Project][SVG] Arc 를 그려보자!  (0) 2022.07.06
728x90

[Project][SVG] Arc 를 그려보자!


SVG 로 Arc를 그리기 위해서는 path를 사용해야합니다.

path의 d 속성에는 여러개의 명령어가 있는데, 그중 M 과 A 를 이용해 그려보는 react 용 Arc Component를 만들어 봅니다.

https://developer.mozilla.org/ko/docs/Web/SVG/Tutorial/Paths

 

A 명령어


원호를 그릴수 있는 명령어인 A는

A rx ry x축-회전각 큰-호-플래그 쓸기-방향-플래그 x y 로 이루어져있습니다.

rx 는 x축 반지름

ry 는 y축 반지름 입니다.

큰-호-플래그 는 180도를 기준으로 중심각을 결정합니다.

 

M 명령어


M 명령어는 Move To 호를 그릴 시작 좌표를 지정해줍니다.

 

Arc Components


Arc component는 A명령어의 파라미터를 채우기위해 2가지의 유틸성 함수를 사용하고,

parameter로

className = "", id = "", cx, cy, r, startDeg, endDeg, fill = "none", stroke = "#446688", strokeWidth = "2",

를 받습니다.

중심 좌표 cx,cy와 반지름 r, 시작각도 startDeg,끝 각도 endDeg, 원호를 꾸며줄 속성들입니다.

 

get Points


먼저 시작 좌표와 끝좌표를 구해야합니다.

구하기 위해서는 각도를 호도로 변환하여 한 좌표와 반지름을 알고있으므로 cos,sin을 이용해 다른 2좌표를 구합니다.

 

const getPoint=(cx, cy, r, deg)=> {   const rad = ((deg - 90) * Math.PI) / 180.0;    return {     x: cx + r * Math.cos(rad),     y: cy + r * Math.sin(rad),   }; }

 

get Attribute d


이렇게 구한 좌표를 가지고, path 태그의 d속성에 넣어줄 명령어 문자열을 만들어 주어야합니다.

const getAttrD=(cx, cy, r, startDeg, endDeg)=> {   const startPos = getPoint(cx, cy, r, startDeg);   const endPos = getPoint(cx, cy, r, endDeg);   const largeArcFlag = endDeg - startDeg > 180 ? 1 : 0;   return `M${startPos.x},${startPos.y}A${r},${r},0,${largeArcFlag},1,${endPos.x},${endPos.y}`; }

getPoint를 이용해 구한 start Point 와 endPoint를 각각 M과 A에 넣어주고, 나서

largetArcFlag를 구해줍니다.

시작각도와 끝각도의 차이가 180도가 넘어가면 1을 아니면 0을 지정해줍니다.

 

전체 코드


 

// src\project\s\svg\components\arc.js
// modules
import React, { useRef, useEffect, useState, forwardRef } from "react";

const Arc = forwardRef(
  (
    {
      className = "",
      id = "",
      cx,
      cy,
      r,
      startDeg,
      endDeg,
      fill = "none",
      stroke = "#446688",
      strokeWidth = "2",
    },
    ref
  ) => {
    const pathRef = ref || useRef();
    const [d, setD] = useState("");
    useEffect(() => {
      setD(getAttrD(cx, cy, r, startDeg, endDeg));
    }, [cx, cy, r, startDeg, endDeg]);
    return (
      <path
        className={className}
        id={id}
        ref={pathRef}
        d={d}
        fill={fill}
        stroke={stroke}
        strokeWidth={strokeWidth}
      ></path>
    );
  }
);

export default Arc;

const getPoint = (cx, cy, r, deg) => {
  const rad = ((deg - 90) * Math.PI) / 180.0;

  return {
    x: cx + r * Math.cos(rad),
    y: cy + r * Math.sin(rad),
  };
};

const getAttrD = (cx, cy, r, startDeg, endDeg) => {
  const startPos = getPoint(cx, cy, r, startDeg);
  const endPos = getPoint(cx, cy, r, endDeg);
  const largeArcFlag = endDeg - startDeg > 180 ? 1 : 0;
  return `M${startPos.x},${startPos.y}A${r},${r},0,${largeArcFlag},1,${endPos.x},${endPos.y}`;
};

 

추가적으로 forwardRef 를 통해 부모 컴포넌트에서 arc 컴포넌트를 접근할 수 있도록합니다.

 

데모는 아래의 링크에서 확인할 수 있습니다.

http://localhost:8080/work/s/svg

728x90

'project > svg' 카테고리의 다른 글

[Project][SVG] Text를 그려보자!  (0) 2022.07.07

+ Recent posts