JavaScript

웹 개발의 필수 언어

동적인 웹 페이지 구현을 위한 핵심 프로그래밍 언어.

Java

객체지향 프로그래밍

안정적이고 확장성 있는 백엔드 개발의 대표 언어.

HTML

웹의 기초

웹 페이지의 구조를 정의하는 마크업 언어.

React

현대적 UI 라이브러리

효율적인 사용자 인터페이스 구축을 위한 JavaScript 라이브러리.

CSS

웹 디자인의 핵심

웹 페이지의 시각적 표현을 담당하는 스타일 언어.

Spring

자바 웹 프레임워크

기업급 애플리케이션 개발을 위한 강력한 프레임워크.

nextjs/웹사이트 만들기

별의 반짝임 효과 구현하기

lamarcK 2025. 4. 15. 14:42
// 2. 별만 있는 패턴 정의 (호버된 경로용)
        const starPattern = document.createElementNS(SVG_NAMESPACE, "pattern");
        starPattern.setAttribute("id", "stars-only-pattern"); // 별 패턴 ID
        starPattern.setAttribute("patternUnits", "userSpaceOnUse"); // ★ 중요: 별 크기 고정
        starPattern.setAttribute("width", "200"); // 패턴 타일 크기
        starPattern.setAttribute("height", "200");
        // 패턴 배경은 투명하게 (아무것도 안 그림)

        // 별 생성 로직 (애니메이션 포함)
        const stars = [
          /* ... 별 좌표 ... */ 
          { cx: "18", cy: "32", r: "1.1" },
          { cx: "43", cy: "85", r: "0.9" },
          { cx: "72", cy: "28", r: "1.3" },
          { cx: "117", cy: "55", r: "1.0" },
          { cx: "159", cy: "23", r: "1.2" },
          { cx: "136", cy: "132", r: "0.8" },
          { cx: "32", cy: "152", r: "1.4" },
          { cx: "64", cy: "179", r: "1.1" },
          { cx: "185", cy: "117", r: "0.9" },
          { cx: "96", cy: "67", r: "1.3" },
        ];
        stars.forEach((star) => {
          //별의 위치, 크기 설정용
          const starElement = document.createElementNS(SVG_NAMESPACE, "circle");
          starElement.setAttribute("cx", star.cx); // 원의 중심 x좌표 설정
          starElement.setAttribute("cy", star.cy); // 원의 중심 y좌표 설정
          starElement.setAttribute("r", star.r);   // 원의 반지름 설정
          starElement.setAttribute("fill", STAR_STYLE.fill);
          starElement.style.opacity = `${STAR_STYLE.opacity}`; // 초기 투명도
          //별 반짝임 구현 애니메이션
          const animate = document.createElementNS(SVG_NAMESPACE, "animate");
          animate.setAttribute("attributeName", "opacity");
          animate.setAttribute("values", STAR_ANIMATE_VALUES);
          animate.setAttribute("dur", `${1 + Math.random() * 1.5}s`); //별 반짝임 주기 1+ 랜덤 초(0~1)*1.5초 랜덤한 별의 반짝임 구현
          animate.setAttribute("repeatCount", "indefinite"); //애니메이션 무한 반복
          starElement.appendChild(animate);
          starPattern.appendChild(starElement); // ★ 패턴에 별만 추가
        });
        defs.appendChild(starPattern); // 별 패턴 defs에 추가
**1. 패턴 생성 및 기본 설정
const starPattern = document.createElementNS(SVG_NAMESPACE, "pattern");
starPattern.setAttribute("id", "stars-only-pattern"); // 나중에 이 ID로 패턴을 참조
starPattern.setAttribute("patternUnits", "userSpaceOnUse"); // 별들의 크기와 위치가 고정됨
starPattern.setAttribute("width", "200"); // 패턴의 가로 크기
starPattern.setAttribute("height", "200"); // 패턴의 세로 크기
**2. 별들의 정보 배열
const stars = [
    { cx: "18", cy: "32", r: "1.1" }, // 첫 번째 별의 위치와 크기
    { cx: "43", cy: "85", r: "0.9" }, // 두 번째 별의 위치와 크기
    // ... 더 많은 별들
];
**3. 각 별 생성 및 설정:
stars.forEach((star) => {
    // 별(원) 요소 생성
    const starElement = document.createElementNS(SVG_NAMESPACE, "circle");
    
    // 별의 위치와 크기 설정
    starElement.setAttribute("cx", star.cx);
    starElement.setAttribute("cy", star.cy);
    starElement.setAttribute("r", star.r);
    
    // 별의 스타일 설정
    starElement.setAttribute("fill", STAR_STYLE.fill); // 별 색상
    starElement.style.opacity = `${STAR_STYLE.opacity}`; // 별 투명도
**4. 별 반짝임 애니메이션 설정:
    // 애니메이션 요소 생성
    const animate = document.createElementNS(SVG_NAMESPACE, "animate");
    
    // 애니메이션 속성 설정
    animate.setAttribute("attributeName", "opacity"); // 투명도를 변화시킴
    animate.setAttribute("values", STAR_ANIMATE_VALUES); // 투명도 변화 값들
    animate.setAttribute("dur", `${1 + Math.random() * 1.5}s`); // 랜덤한 지속 시간
    animate.setAttribute("repeatCount", "indefinite"); // 무한 반복
    
    // 애니메이션을 별에 추가
    starElement.appendChild(animate);
**5. 요소들의 조립:
    // 완성된 별을 패턴에 추가
    starPattern.appendChild(starElement);
});

// 완성된 패턴을 defs에 추가
defs.appendChild(starPattern);

최종 결과:

200x200 크기의 반복되는 패턴 안에 각기 다른 위치와 크기를 가진 별들이 있고 각 별은 각자 다른 주기로 반짝이며 이 패턴이 호버된 지역을 채우게 된다. 이렇게 생성된 패턴은 나중에 url(#stars-only-pattern)으로 참조하여 사용할 수 있다.


더 복잡하게 별을 채우거나 특정 패턴을 사용하거나 랜덤성을 늘리는 방법도 있긴하지만 굳이 그럴 필요성은 느끼지 못했다.