본문 바로가기
개발개발/LifeGraph_인생그래프

[인생 그래프] SCSS 반응형 디자인 구현하기

by yelimu 2025. 2. 12.

폰트 크기, 여백 등의 스타일은 미디어 쿼리로 쉽게 반응형 구현이 가능하다.

scss에서는 변수를 선언할 수 있어서 매우 편리하다

// variables.scss
// 반응형 너비
$mobile: 375px;
$tablet: 768px;
$desktop: 1024px;


@import "./variables";
.border {
	// 기본 스타일

    @media (max-width: $mobile) {
      // 모바일 너비에서 보여줄 스타일
    }
  }

 

또한 폰트 크기를 px 단위에서 rem 단위로 변경하였다.

html {
  font-size: 62.5%;
}

body {
  font-size: 1.6rem;
}

브라우저 기본 폰트 크기 = 16px 의 62.5% = 10px 

rem은 최상위 루트를 기준으로 계산하므로 1rem = 10px 이 된다.

body에 다시 1.6rem을 적용해서 기본값은 16px 크기가 되도록 한다.


문제가 되는 부분은 그래프의 반응형 구현이다.

Point 위치를 absolute로 했기 때문에 그래프를 생성 중 또는 결과 페이지에서 윈도우 너비를 변경해도 그래프는 고정되어있다.

즉 그래프의 축적이 변경되지 않는건데, 이 문제를 어떻게 해결할 수 있을까? 

Point 생성할때 x, y 좌표를 상대적인 값으로 받아야 할까? 

 

다시 handleClickPoint 함수를 보면

  const handleClickPoint = (e: ReactMouseEvent<HTMLDivElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    const newId = index + 1;
    setIndex(newId); // id 순차적으로 증가
    addPoint({ id: index, x, y, title: "📍" }); // 클릭한 좌표 추가
  };

윈도우 너비가 변할때 rect 객체의 left 값도 함께 바뀌면 될거같다.

상태로 관리하고, useEffect에서 윈도우 너비 width가 바뀔때 상태 업데이트 되면 해결되지않을까?

=> ✖️

새롭게 추가하는 점은 상관없는데 이미 클릭된 점의 위치가 수정되어야함 🙆‍♂️


먼저 윈도우 너비 리사이즈 이벤트를 감지해야 한다. 

import { useEffect, useState } from "react";
import debounce from "../util/debounce";

const useMovePointByWidth = () => {
  const [width, setWidth] = useState(window.innerWidth);

 
  // 윈도우 리사이즈 감지
  useEffect(() => {
    const handleResize = () => {
      setWidth(window.innerWidth);
    };
    const debounceResize = debounce(handleResize, 200); 

    window.addEventListener("resize", debounceResize);

    return () => {
      window.removeEventListener("resize", debounceResize);
    };
  }, []);


export default useMovePointByWidth;

과도한 리사이즈 이벤트가 발생하기때문에 디바운스를 추가해야한다.

 

resize가 일어날때 변경되는 값: width

prevWidth 와 width를 비교해서 값이 달라졌을때 setPoints 에 조정된 x 값을 갖는 newPoints 를 넘겨준다

  const [prevWidth, setPrevWidth] = useState(window.innerWidth);
  const { points, setPoints } = useGraphStore();

... 
 useEffect(() => {
    // 이미 저장된 points x좌표 조정
    if (width !== prevWidth) {
      const newPoints: PointData[] = points.map((point) => ({
      ...point, x: point.x * (width / prevWidth) 
      }));
      setPoints(newPoints);
    }
    setPrevWidth(width);
  }, [width, points]);

 

Point 생성하는 페이지와, 그래프를 보여주는 결과 페이지에서 각각 x좌표 조정이 필요해서 훅으로 만들었다.

points 를 전역 상태로 관리하고있으니까 한쪽에서만 setPoints해도 결과페이지에도 업데이트된 정보가 넘어갈거라고 생각했다.

그러나 이미 path가 생성된 후에는 기존 좌표값을 조정해주는 로직이 필요하다.

 

import { create } from "zustand";
import { PointData } from "../types/pointType";

interface GraphStore {
  setPoints: (newPoints: PointData[]) => void;
}

export const useGraphStore = create<GraphStore>((set) => ({
  setPoints: (newPoints) =>
    set(() => ({
      points: newPoints,
    })),
}));

 

store가 자꾸만 커진다 ㅎㅎ...

새로운 데이터로 완전히 바꿔주는 set함수를 추가해주었다. 

 

윈도우 너비를 극단적으로 줄여도 잘 반영된다 ㅎ 

이미지를 클릭하면 사이트로 이동합니다.