najakgil / najakgil-blog

🧚 나작길 블로그 | 나작길의 이야기를 담고 있는 블로그
https://najakgil-blog.vercel.app/
0 stars 1 forks source link

[FIX] 화면 사이즈에 따른 이미지 사이즈 변경 #3

Closed anonymousRecords closed 2 months ago

anonymousRecords commented 2 months ago

📌 문제 상황

https://github.com/najakgil/najakgil-tech/assets/97885933/606310db-712a-4ed4-a636-b07920225965

화면 사이즈에 따라 떨어지는 캐릭터 이미지 사이즈 변경이 필요함.

anonymousRecords commented 2 months ago

📌 이슈 분석

    const size = Math.random() * 500 + 100;
    return (
      <Image
        key={index}
        className="snowflake absolute"
        src={characterElements[index % characterElements.length]}
        alt={`snowflake-${index}`}
        style={{
          pointerEvents: 'none',
          // 랜덤한 위치에 눈송이 생성
          left: `${Math.random() * 100}vw`,
          top: `${Math.random() * -600}px`,
          width: `${size}px`,
          height: `${size}px`,
        }}
        width={size}
        height={size}
      />
    );

해당 이슈는 문제 발생을 해결을 위한 이슈보다는, 화면 사이즈별 이미지 크기 변경이라는 추가 기능에 가깝다.
초기에는 위처럼 size만 정의되어 있기에 화면 사이즈별 이미지 크기가 변경되지 않는 것은 당연한 일이다.

📌 문제 해결

    // 모바일 디바이스 여부 확인
    const isMobile = window.innerWidth <= 768;
    // 모바일 사이즈와 비모바일 사이즈 설정
    const size = Math.random() * (isMobile ? 300  : 500) + 100;

window.innerWidth <= 768을 기점으로 모바일 디바이스 여부를 확인하였다.

여기서 고민한 것은 isMobile이라고 따로 정의하지 않고

const size = Math.random() * (window.innerWidth <= 768 ? 300  : 500) + 100;

이렇게 작성하는 것이었다. 그런데 이렇게 하면 다른 사람이 읽을 때 왜 이렇게 작성한 건지 의도 파악이 어려울 것 같다는 생각이 들었다.
isMobile이면 모바일 사이즈 때문인 걸 알 거 같은데, 아닐 경우 windown.innderWidth 화면 사이즈를 왜 768로 끊은거지? 이렇게 사고가 시작할 것 같았다.

위와 같은 이유로 isMobile을 명시하고 작성하였다.

anonymousRecords commented 2 months ago

📌 추가 이슈

ReferenceError: window is not defined 에러가 발생했는데, 이는 Next.js에서 SSR 시, window 객체를 서버에서 사용할 수 없기 때문이다.

따라서 useEffect를 사용해서 window 객체에 접근하는 코드를 클라이언트 측에서만 실행되도록 했다.

const [snowflakeSizes, setSnowflakeSizes] = useState<number[]>([]);

  useEffect(() => {
    // 모바일 디바이스 여부 확인
    const isMobile = window.innerWidth <= 768;
    // 눈송이 크기 랜덤 설정
    const sizes = Array.from({ length: SNOWFLAKE_COUNT }).map(() =>
      Math.random() * (isMobile ? 300 : 500) + 100
    );
    setSnowflakeSizes(sizes);

    const snowflakes = document.querySelectorAll(".snowflake");
    snowflakes.forEach((snowflake) => {
      animateSnowflake(snowflake);
    });
  }, []);

그리고 처음에는 number[]이 아닌 number로만 sizes를 정의했다.
그런데 이렇게 하니까, 한 사이즈로 이미지 크기가 통일되었다. 그러니까 랜덤으로 사이즈 하나가 정해지고, 해당 사이즈로 이미지 크기가 다 통일되어 버린 것이다.

그래서 number[]로 하여, [124.3, 243.5, ...]와 같이 숫자 배열로 랜덤으로 생성한 사이즈들을 담아서 전해주었다. 이랬더니 랜덤으로 사이즈들이 정의되었다.