디자이너들은 다 안다는 스쿼클 도형은 카카오톡 프로필에 쓰이고 있는 둥근 사각형 모형을 생각하면 된다.
이번에 회사 디자이너님이 웹 사이트에 적용하고 싶어 하셔서, 적용을 하는 과정에 엄청난 트러블 슈팅들이 생겨났고 자료도 많이 없어서 기록을 시작했다.
1️⃣ svg로 이미지를 다운하기
디자이너님이 만들어 놓은 피그마 도형을 클릭해서 먼저 svg로 Export를 한다.
이 이미지를 쓰는 것은 아니고 이미지 안에 있는 형태를 사용해야 하는 것이다.
👌 예를 들어, 50x50 사이즈의 스쿼클 svg를 다운했다고 한다면,
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.5 25C0.5 15.6527 2.06433 9.58027 5.8223 5.8223C9.58027 2.06433 15.6527 0.5 25 0.5C34.3473 0.5 40.4197 2.06433 44.1777 5.8223C47.9357 9.58027 49.5 15.6527 49.5 25C49.5 34.3473 47.9357 40.4197 44.1777 44.1777C40.4197 47.9357 34.3473 49.5 25 49.5C15.6527 49.5 9.58027 47.9357 5.8223 44.1777C2.06433 40.4197 0.5 34.3473 0.5 25Z" fill="#AAA9FD" stroke="#D2E0F3"/>
</svg>
이런 svg 코드가 나온다. 이걸 이용을 해서 시작해야 한다.
2️⃣ 재사용을 해야 하기 때문에, 컴포넌트 하나 만들어 놓기
예를 들면, 이렇게 만들면 된다.
내가 만드는 웹 사이트의 프로필은 사이즈가 세 개라서 세 개를 만들어 두었다.
👌 재사용을 할 건데, 왜 세 개나 만드나요? 프롭스로 하면 되지 않나?
🔹 나도 이거 해결해보고 싶었는데, 프롭스하는 것보다 이게 훨씬 간편하다. path등이 사이즈별로 다르기 때문이다.
3️⃣ 만든 컴포넌트에 svg 코드 가져오기
이렇게 아까 저장해둔 svg 코드를 가져온다 여기서 부터 복잡한게 시작되지만 그대로 따라하면 쉽다.
내가 너무 많은 트러블을 겪었기 때문에 ㅠㅠㅠ
import React from 'react';
const SquircleIamge50:React.FC = () => (
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.5 25C0.5 15.6527 2.06433 9.58027 5.8223 5.8223C9.58027 2.06433 15.6527 0.5 25 0.5C34.3473 0.5 40.4197 2.06433 44.1777 5.8223C47.9357 9.58027 49.5 15.6527 49.5 25C49.5 34.3473 47.9357 40.4197 44.1777 44.1777C40.4197 47.9357 34.3473 49.5 25 49.5C15.6527 49.5 9.58027 47.9357 5.8223 44.1777C2.06433 40.4197 0.5 34.3473 0.5 25Z" fill="#AAA9FD" stroke="#D2E0F3"/>
</svg>
);
export default SquircleIamge50;
4️⃣ 스쿼클 이미지 만들기
👌 위에 50x50 사이즈로 복붙했는데, 아래서부턴 40x40 으로 수정해서 코드 작성을 해보려고 한다. 비교를 하고 싶어서!
import React from 'react';
const SquircleIamge40:React.FC = () => (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid slice"
clipPath=url(#clipSquircle40)
>
<defs>
<path
id="shapeSquircle40"
d="M0.5 20C0.5 12.5277 1.75183 7.70527 4.72855 4.72855C7.70527 1.75183 12.5277 0.5 20 0.5C27.4723 0.5 32.2947 1.75183 35.2715 4.72855C38.2482 7.70527 39.5 12.5277 39.5 20C39.5 27.4723 38.2482 32.2947 35.2715 35.2715C32.2947 38.2482 27.4723 39.5 20 39.5C12.5277 39.5 7.70527 38.2482 4.72855 35.2715C1.75183 32.2947 0.5 27.4723 0.5 20Z"
/>
<clipPath
id="clipSquircle40"
>
<use xlinkHref="#shapeSquircle40" />
</clipPath>
</defs>
<image
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
clipPath="url(#clipSquircle40)"
xlinkHref="이미지 주소"
/>
</svg>
);
export default SquircleIamge40;
이 코드 그대로 가져다 쓰면, 스쿼클 바로 만들어진다.
image 안 xlinkHref에 사용하고 싶은 이미지 주소를 입력하면 된다.
5️⃣ 재사용을 하기 위한 작업 1 - 이미지 주소 props로 가져오기
이 블로그를 보는 사람들이 내가 작성한 코드를 복붙하는 방법도 있겠지만, 스쿼클의 경우에는 복붙하면 쉽지 않 것이라 생각한다. 각자 props 하는 것들이 다를 것이고 만드는 방법을 이해하고 넘어가야 한다.
👌 imagePath를 string 타입으로 설정하기
👌 image안에서 xlinkHref={imagePath}로 수정해서, 실제로 내가 사용할 이미지 가져오기
👌 스쿼클 사용할 곳에서 이미지 데이터 넣어주기
❗ 여기까지 했고 이미지 스쿼클 다 만들었는데 완료인가요?? NO!!!
몇 개 없는 스쿼클 관련 블로그가 여기까지만 되어 있었는데, 지금부터 문제가 발생한다....
❗헤더에 사이즈가 동일한 스쿼클이 있고 컨텐츠에도 있다면?
❗그러면 동일한 id 를 가진 스쿼클들이 계속 생겨나게 된다.
❗신기하게도 PC 사이즈에선 문제가 없다. 미디어 쿼리를 사용한 사이즈부터 스쿼클이 안 되기 시작한다.
👌 여기서 발견한 문제는 모두 id가 동일하기 때문이라는 것, 그럼 id도 프롭스로 별도 적용을 해주면 된다.
6️⃣ 재사용을 하기 위한 작업 2 - id props로 가져오기
👌 위에서 imagePath 설정한 곳에 clipId, shpaeSquircleId를 만들어준다.
👌 svg 태그의 clipPath 수정하기
👌 path 태그의 id 수정하기
👌 clipPath id, use태그 xlinkHref 수정하기
👌image태그의 clipPath 수정하기
7️⃣ 사용할 곳에서 clipId, shapeSquircleId 별도 적용하기
❗트러블슈팅 추가 발생
👌 이미지 배경 색상이 투명일 경우엔? 이미지를 보냈기 때문에 스쿼클 배경색도 투명으로 나온다.
👌 svg내 style 적용해주면 해결된다. 투명으로 하고 싶으면 투명으로, 원하는 색상이 있으면 적용하기
✅ 그렇다면 왜 사이즈별로 컴포넌트를 만들었는지??
👌 svg의 width, height, viewBox / path의 d 때문이다.
하나하나 width, height, d를 props로 보내주는게 오히려 번거롭고 d는 길이가 너무 길어서 더 불편하다.
스쿼클은 보통 프로필에 적용되므로, 프로필은 일정한 사이즈를 가지고 있는 경우가 많기 때문에 따로 만드는 것이 더 유리하다.
결론적으로 보면 아주 쉬운 내용들이, 개발을 하는 과정에선 복잡하고 어렵고 시간이 오래 걸린다.
겪다 보면 성장하는게 느껴지지만, 그 시간을 어떻게 기록하는지가 중요한 것 같다ㅠㅠ.
✅ 최종 코드
import React from 'react';
interface SquircleImageProps {
imagePath: string;
clipId: string;
shapeSquircleId: string;
}
const SquircleIamge40:React.FC<SquircleImageProps> = ({
imagePath, clipId, shapeSquircleId,
}) => (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid slice"
clipPath={`url(#${clipId})`}
// eslint-disable-next-line react-perf/jsx-no-new-object-as-prop
style={{ background: 'white' }}
>
<defs>
<path
id={shapeSquircleId}
// eslint-disable-next-line max-len
d="M0.5 20C0.5 12.5277 1.75183 7.70527 4.72855 4.72855C7.70527 1.75183 12.5277 0.5 20 0.5C27.4723 0.5 32.2947 1.75183 35.2715 4.72855C38.2482 7.70527 39.5 12.5277 39.5 20C39.5 27.4723 38.2482 32.2947 35.2715 35.2715C32.2947 38.2482 27.4723 39.5 20 39.5C12.5277 39.5 7.70527 38.2482 4.72855 35.2715C1.75183 32.2947 0.5 27.4723 0.5 20Z"
/>
<clipPath
id={`${clipId}`}
>
<use xlinkHref={`#${shapeSquircleId}`} />
</clipPath>
</defs>
<image
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
clipPath={`url(#${clipId})`}
xlinkHref={imagePath}
/>
</svg>
);
export default SquircleIamge40;
'제니의 개발일지 > 도움이 되었던 것 정리' 카테고리의 다른 글
Apollo GraphQL - 연습 1일차 (0) | 2023.05.23 |
---|---|
Tex 문법 정리 (0) | 2023.04.10 |
[TypeScript] useRef 모달 바깥 영역 클릭 이벤트 (0) | 2023.03.27 |
[리액트 React] 이미지 업로드 이름 찾아오기 (1) | 2023.01.02 |
[React 리액트] 버튼 클릭 모달 열기, 닫기 (2) | 2022.12.28 |