page-swarm-rebuild은(는) 무엇을 하나요?
버전 1.3.0 (모듈, 애드온, 스타일시트 및 이 파일; 저장소의 CHANGELOG.md 참조; SwarmRebuild.version).
프리젠테이션 전용 인트로 효과. 페이지의 실제 DOM은 절대 수정되지 않습니다. 레이어는 <head> 내 하나의 캐스케이드 레이어드 스타일시트로 숨겨졌다가 드러나고, 모든 애니메이션은 <html>에 추가된 오버레이에서 발생하며, 종료 시 둘 다 제거됩니다. 의존성 없음, 네트워크 요청 없음(GDPR 친화적), 레이아웃 시프트 없음, 사운드 없음, 페이지가 절반만 숨겨진 상태로 남지 않음(보호 참조).
원본 효과의 명세(타임라인, 시각 요소, HUD, 스크롤 곡선): references/effekt-leiras.md(헝가리어). 이 파일과 해당 파일이 일치하지 않는 경우, 이 파일이 우선합니다(설명서 작성 후 제품 결정이 내려졌습니다).
파일
| 파일 | 목적 |
|---|---|
assets/swarm-rebuild.js | 모듈, 읽을 수 있는 소스(클래식 스크립트, window.SwarmRebuild 설정; 번들러에서 가져오기도 가능). |
assets/swarm-rebuild.min.js, swarm-rebuild-debug.min.js, swarm-rebuild.min.css | 일반 HTML 사이트용 축소 빌드(scripts/build-min.cjs; 설치 프로그램에서 사용; 번들러는 자체적으로 소스를 축소). |
assets/swarm-rebuild.css | #swarm-rebuild-root 하에 범위가 지정된 오버레이 스타일. |
assets/swarm-rebuild-debug.js | 디버그 애드온: 컨트롤 바, 자동 스크롤 투어, 테스트 훅. 방문자에게는 절대 로드되지 않음. ?rebuild-debug=1 / debug: true로만 가져옴. 어쨌든 모듈 옆에 설치하십시오(라이브 사이트에서 테스트하는 방법입니다). |
assets/react/SwarmRebuild.jsx | React / Next.js 클라이언트 래퍼 + <SwarmRebuildHead />(페인트 전 스니펫); 디버그 애드온은 별도의 지연 청크입니다. |
assets/demo/ | 가상의 어두운 포트폴리오 데모(assets/demo/index.html, 214개 레이어(데스크톱), 6.6 뷰포트 높이, 고정 헤더). |
tests/index.html | 모든 모드의 모든 테스트 페이지로 연결(또한 GitHub Pages 시작 페이지). |
tests/pages/dental/ | 가상 치과: 밝은 테마, 전화 링크, 고정 "Call us" + 예약 바(모바일), 고정 공지(데스크톱). |
tests/pages/lang-*/ | 헝가리어, 아랍어(오른쪽에서 왼쪽), 일본어 및 이모지가 풍부한 페이지(모든 언어로 타이핑)의 가상 페이지. |
tests/pages/law/, accounting/, bootstrap/, spa/ | 가상 실제 패턴: 웹 폰트, 고정 헤더, 동의 배너, iframe, 지연 이미지, 다크 모드, 긴 페이지, 스크롤 리빌, Bootstrap (npm), 단일 페이지 앱, 비디오. |
tests/pages/nextjs/ | 가상 Next.js 15 App Router 앱: React 카운터(수화 점검), 고정 도움말 버튼. |
scripts/verify.cjs | Playwright를 사용한 한 페이지 점검(4단계 참조). |
scripts/run-tests.cjs | 세 테스트 페이지(데스크톱 및 모바일)에서 verify.cjs 실행; 요약 테이블 출력. |
scripts/bench-fps.cjs | 이전 모듈 버전 대 현재 버전의 프레임 레이트, 동일 머신, 교차 실행. |
scripts/build-site.cjs | 세 테스트 페이지를 정적 사이트(GitHub Pages)로 빌드하거나 로컬 네트워크에 제공. |
scripts/next-app.cjs | 헬퍼: Next.js 테스트 앱을 임시 폴더에 준비/빌드. |
scripts/build-min.cjs | .min 파일을 빌드하고 크기 예산을 확인(terser와 csso npm 필요). |
scripts/perf.cjs | 효과 유무에 따른 Lighthouse 메트릭(LCP, CLS, TBT, Speed Index, 접근성, SEO). |
scripts/sync-snippet.cjs | 모듈의 head 스니펫을 React 래퍼, SKILL.md 및 테스트 페이지로 복사. |
scripts/record-video.cjs | 포트폴리오용 효과를 .mp4 / .webm으로 녹화(디버그 투어, 컨트롤 바 숨김). |
scripts/project.cjs | legacy/에 백업과 함께 프로젝트에 효과 설치, 다시 제거, 원본 복원. |
scripts/test-project.cjs | 설치 프로그램 테스트: 백업, 손상된 프로젝트 후 복원(해시 동일), 제거. |
제품 결정 (참조 비디오를 재정의)
- 기본 모드는
scroll: 빌드는 방문자의 스크롤을 따라가며, 보이는 것만 빌드됩니다. 요소는 화면에 60% 이상 나타날 때 시작되고(buildVisible), 뷰 아래나 위는 빌드되지 않으며, 작업 중인 에이전트는 화면을 떠나지 않습니다. - 방문자는 컨트롤 바를 보지 못하며 자동 스크롤도 없음. 바와 투어는 디버그 애드온에 있으며,
?rebuild-debug=1또는debug: true로만 로드됩니다. 애드온 없이mode: 'tour'는scroll로 폴백됩니다. - 가시적인 컨트롤 없이 항상 나갈 수 있는 방법: Esc, Tab, Enter, 기타 키(Shift/Ctrl/Alt/Meta 단독 제외) 및 모든 클릭/탭은 애니메이션과 레이아웃 시프트 없이 즉시 완성된 페이지를 표시합니다.
prefers-reduced-motion은 효과가 전혀 없음을 의미합니다(WCAG 2.2.2). - 스크롤 키는 스크롤: Space, 화살표, Page Up/Down 및 Home/End(페이지 자체에 포커스가 있고 Ctrl/Alt/Meta 없이)는 마우스 휠처럼 빌드를 구동합니다. 포커스된 링크, 버튼 또는 필드에서 또는 수정자 키와 함께 사용하면 다른 키처럼 효과를 종료합니다. Tab, Enter 및 Esc는 항상 종료하므로 키보드 사용자는 첫 번째 Tab에서 실제 콘텐츠(및 포커스 순서)에 도달합니다.
- 효과를 종료하는 클릭은 방문자가 보지 못한 작업을 수행하지 않음: 아직 완료되지 않은 콘텐츠(숨겨져 있거나 아직 빌드 중)에 착륙하면 무시됩니다(
pointerdown에서 이미preventDefault+stopPropagation, 따라서 포커스, 링크, 버튼 동작 없음). 완료된 콘텐츠(보이는, 내부 또는 공개 중인 항목 없음 - 예: 처음부터 표시된 전화 링크 또는 빌드된 버튼)에 착륙하면 정상 클릭으로 처리되고 동시에 효과가 종료됩니다. 이유: 모든 클릭을 무시하면 보이는 "Call us" 링크가 첫 번째 탭에서 실패하게 됨; 모든 클릭을 통과시키면 방문자가 보지 못한 링크를 따르게 됨. 터치 스크롤 및 스크롤바는 절대 효과를 종료하지 않음(스크롤은 빌드가 구동되는 방식입니다). - 사운드 없음. 모듈에 오디오 코드가 없습니다.
모드
| 모드 | 속도 | 동작 |
|---|---|---|
scroll (기본값) | 3배 | 자동 스크롤 없음. 에이전트는 보이는 것만 빌드: 요소는 높이의 최소 buildVisible(60%)이 화면에 있을 때 시작; 화면보다 높은 요소는 화면의 60%를 채울 때 시작하여 위에서 아래로 빌드. 뷰 외부는 빌드되지 않으며 작업 중인 에이전트는 뷰를 떠나지 않음(화면보다 높은 프레임은 화면 가장자리에서 당겨짐). 빠른 스크롤(휠, 키, Home/End) 후 보이는 부분은 약 1-2초 내에 채워짐: 해당 레이어가 먼저 시작되고, 더 많은 에이전트가 합류(최대 8명 추가)하며 작업이 더 빠르게 실행됨. 뷰를 벗어난 것은 즉시 최종 상태가 됨(보호 참조). |
fast | 6배 | scroll과 동일, 속도 2배. |
tour (디버그 전용) | 1배 | 참조 비디오처럼 자동 스크롤: ~레이어/7초, 카메라는 작업 전선을 따라가며, 커서 링과 함께 하단에서 종료. 녹화 및 나란히 비교용. ?rebuild-speed=6은 이전 "fast" 제공(6배 자동 스크롤, 데모에서 ~9초). 수동 스크롤은 방문자에게 제어권을 넘김; 바의 Tour 버튼이 재개. |
빌드 후 떼는 포커스 요소 주위에 모이고 오버레이는 autoExit초(3초; 디버그 애드온 포함 6초, 투어 모드에서는 절대 안 함) 후 사라집니다.
모션
모든 모션은 기본적으로 미묘하며 motion으로 설정됩니다(구성 참조); ?rebuild-motion=arc:0,...는 A/B 테스트를 위해 일부를 끕니다(디버그 애드온).
- 포커스 요소 (
focus): 시작과 피날레가 그 주위에 떼를 지음. 개발자에게 문의(1단계). 각 단계에서 다음 중 뷰에 절반 이상 있는 첫 번째 요소가 사용됨: 구성된 요소,[data-swarm-focus],h1, 주요 버튼(a.btn,.button,.cta,button[type=submit]...), 로고; 그 다음 뷰에서 가장 큰 그림; 그 다음 뷰의 한 지점. 따라서 페이지 아래쪽의 포커스(예: 마무리 콜 투 액션)는 피날레 역할을 하고, 시작은 주요 제목을 사용합니다. - 떼: 자유 에이전트는 명확히 다른 크기의 2-4개 떼로 날아듭니다(휴대폰: 2). 각 에이전트는 감쇠 스프링에 의해 자신의 떼 내 위치로 당겨집니다. 떼 중심은 포커스 요소 주위 타원에서 움직이며 반경은 호흡하고 속도는 변하므로 에이전트는 스스로 속도를 높였다 줄였다 하며 완벽한 원으로는 절대 달리지 않습니다. 시작은 이미 떼에서 시작합니다(방문자에게는 1초 미만 지속).
- 쉬는 에이전트 (빌드 중 작업 없는 에이전트): 떼를 떠나 뷰 내 자신의 지점으로 이동, 다른 쉬는 에이전트와 최소 72px 떨어짐(겹치는 커서 클러스터 없음), 천천히 표류하고 1.4초 후 사라짐; 다음 작업을 받을 때 쉬는 곳에서 나타남. 피날레에서는 모두 돌아와 포커스 주위 떼를 이룸. 측정 기준: 99.6-100%의 프레임에서 최대 2개의 겹치는 쉬는 커서(1.2: 데모에서 중앙값 6, 최대 20).
- 피날레: 뻣뻣하고 과소 감쇠된 스프링(감쇠 0.63,
motion.spring)이 모든 에이전트를 포커스로 당깁니다: 시작에서 가장 빠르며, 위치를 약 5-20% 지나친 다음 다시 돌아옴; 약 1초 후 스프링이 부드러워지고 떼가 천천히 원을 그리며 돕니다. - 마우스 (시작과 피날레, 데스크톱 전용; 터치 시 절대 안 함, 축소 모션 시 절대 안 함): 포인터 근처의 에이전트가 포인터에서 비켜남(포인터가 빠르게 올수록 더 강하게); 최대 3개의 호기심 많은 에이전트가 작은 원으로 따라가며, 포인터가 멈추면 1.3-2초, 더 빨리 움직일수록 더 짧음(관심은 기본 비율의
(1 + 속도 / 220 px/s)배로 감소). 36px보다 가까이 가지 않음(하드 리미트, 아이콘이 겹치지 않도록); 오버레이는 포인터 이벤트를 무시하므로 클릭이 방해받지 않음. - 중력: 에이전트는 작업 중인 요소를 운반하므로 그곳으로 가는 길(및 운반된 복제본)은 아래로 휘어짐: 처짐 = 0.2 x 수평 거리 x 무게 x 수평성², 무게 = sqrt(면적) / 320 px, 0.2..1로 고정, 최대 56px 및 수평 거리의 5분의 1. 수직 이동은 거의 휘어지지 않음. 작업으로 가는 길도 에이전트의 현재 속도(3차 Hermite 곡선)로 시작하므로 갑작스러운 정지나 회전이 없습니다.
- 난이도: 각 작업의 작업(가는 길 제외)은 요소 면적의 난이도로 조정됨(타이핑의 경우: 입력된 상자): 페이지 평균 근처 2배 면적 ~ 1.6-1.8배 시간, tanh로 압축되어 가장 어려운 작업은 가장 쉬운 작업의 최대 약 4배 소요. 작업 길이와 난이도에 의해 가중치가 정규화되므로(병렬 작업이 긴 작업의 속도를 설정하기 때문에) 전체 빌드는 이전과 동일한 시간이 소요됨; 작은 것과 큰 것 사이의 분할만 변경됩니다.
- 라이트 (
motion.lite: 'auto'): 휴대폰에서 2개 떼 및 마우스 플레이 없음; 빌드 중 프레임 속도가 2초 동안 38fps 미만으로 유지되면 3개의 트레일 고스트 대신 1개도 사용.
언어 및 쓰기 방향
모듈은 언어를 가정하지 않습니다. 타이핑은 사용자 인식 문자(자소 클러스터, Intl.Segmenter, 결합 마크, ZWJ 시퀀스, 피부 톤, 변이 선택자 및 깃발 쌍을 결합하는 폴백 포함)로 진행됨: 악센트 문자, 이모지 가족, 깃발 또는 아랍어/히브리어 마크가 있는 문자는 절대 분할되지 않음. 입력되지 않은 텍스트는 숨겨진 텍스트로 제자리에 남아 있고, 브라우저는 해당 경계를 넘어 형태를 만들므로 아랍어 글자는 연결된 형태를 유지하고 리플로우되지 않습니다. 오른쪽에서 왼쪽 요소(direction: rtl, 예: <html dir="rtl">): 프레임은 오른쪽 가장자리에서 자라며, 선은 오른쪽에서 왼쪽으로 그려지고, 에이전트는 왼쪽에 타이핑하며 캐럿은 마지막으로 입력된 글자 왼쪽에 위치함; 오른쪽에서 왼쪽 텍스트 내 왼쪽에서 오른쪽 실행(숫자, 이메일 주소, 라틴어 이름)은 붙여넣은 단어처럼 전체가 입력됨. CJK 텍스트(공백 없음) 및 긴 단어는 페이지에서와 정확히 동일하게 줄바꿈됨. 오버레이 자체는 항상 왼쪽에서 오른쪽으로 배치됨(루트에 direction: ltr)므로 오른쪽에서 왼쪽 페이지가 이를 반전시키지 않음. 모든 스크립트의 숫자(\p{Nd})는 숫자로 간주됨. 테스트 페이지: tests/pages/lang-hu (ő / ű, 매우 긴 단어), lang-ar (오른쪽에서 왼쪽, 아랍-인도 숫자, 히브리어 인용문), lang-ja (일본어), lang-emoji. 알려진 제한: 세로 쓰기 모드(writing-mode: vertical-rl)는 입력되지만 프레임은 여전히 왼쪽에서 오른쪽으로 자랍니다.
성능, 검색 엔진, 접근성
-
크기 (방문자가 다운로드하는 것; 디버그 애드온은 절대 다운로드되지 않음): 모듈 70KB 축소 / 27.5KB gzip, 스타일시트 6KB / 1.6KB; 예산 30KB + 2KB gzip (
node scripts/build-min.cjs --check). 모듈을 변경할 때마다.min파일 재빌드(--modules <terser 및 csso가 있는 폴더>). -
Lighthouse (
scripts/perf.cjs, 중앙값 3회, 모바일/데스크톱 프리셋, GPU 없는 테스트 머신):페이지 LCP ms 꺼짐 -> 켜짐 CLS 꺼짐 -> 켜짐 TBT ms 꺼짐 -> 켜짐 Speed Index ms 꺼짐 -> 켜짐 성능 점수 데모, 모바일 2106 -> 2207 0 -> 0 12 -> 10 968 -> 1669 99 -> 99 데모, 데스크톱 483 -> 573 0 -> 0 0 -> 0 266 -> 681 100 -> 100 치과, 모바일 1956 -> 2035 0 -> 0 0 -> 0 754 -> 1763 99 -> 99 치과, 데스크톱 442 -> 490 0 -> 0 0 -> 0 201 -> 767 100 -> 100 법률(웹 폰트), 모바일 2094 -> 2222 0.030 -> 0 0 -> 0 1895 -> 2386 98 -> 97 회계(긴 페이지), 모바일 1707 -> 1973 0 -> 0 0 -> 0 1652 -> 1697 99 -> 98 차단 시간 및 레이아웃 시프트 없음(법률 페이지의 자체 폰트 스왑 시프트조차 숨겨짐). LCP는 50-270ms 증가하고 Speed Index는 최대 약 1초 증가: 첫 번째 뷰가 방문자 앞에서 빌드되므로 시각적으로는 나중에 완료됨 - 이것이 효과 자체입니다. 첫 번째 방문자만(세션당 한 번) 비용을 지불함; 재방문자 및 크롤러는 페이지를 즉시 얻음. 접근성/SEO 점수는 Lighthouse가 페이지가 숨겨져 있는 동안 페이지의 일부를 덜 보기 때문에 한 방향으로 1점씩만 움직입니다.
-
검색 엔진 및 링크 미리보기: 크롤러(봇/크롤/스파이더, Googlebot, Bingbot, facebookexternalhit, 링크 미리보기 등의 사용자 에이전트)는 head 스니펫이나 모듈에서 효과를 절대 얻지 못함: 동일한 DOM(
a11y점검)으로 완성된 페이지를 봅니다. JavaScript 없이 페이지는 절대 숨겨지지 않으며, 효과는 콘텐츠를 제거하지 않습니다(visibility만 사용).
접근성
- WCAG 2.2.2 (일시 중지, 중지, 숨기기):
prefers-reduced-motion은 효과를 완전히 끕니다. 움직이는 콘텐츠는 자동으로 시작되지 않습니다(방문자가 스크롤해야 함). 모든 키보드 사용자는 Tab/Enter/Esc로 종료합니다. Tab은 첫 번째 탭에서 효과를 종료하므로 키보드 사용자가 효과를 통과해야 하는 것이 아닙니다(스크롤 키는 그들의 스크롤 의도에 응답합니다). - WCAG 2.1.1 (키보드): 모든 기능은 키보드 접근 가능: 스크롤 키, 종료 키 및 Tab.
- WCAG 1.1.1 (대체 텍스트): 오버레이는
<img>또는 숨겨진 텍스트를 포함하지 않습니다. 시각 효과는 콘텐츠를 전달하지 않습니다. - WCAG 1.4.1 (색상 사용): 커서 아이콘은 항상 배경과 충분한 대비를 이루는 두 가지 색상을 사용합니다(시력 검사: 데모의 모든 프레임, 모든 상태).
- WCAG 2.3.1 (세 번 깜빡임): 효과는 3Hz 이상에서 깜빡이지 않습니다.
- ARIA:
aria-hidden="true"가 루트 요소에 있습니다. 효과가 활성화된 동안 방문자는 메인 페이지와 상호 작용할 수 없습니다(화면 판독기는 여전히 페이지를 읽지만 모든 키 입력이 종료됩니다). 보조 기술 사용자는 첫 번째 키 입력 후 객체를 얻습니다. 성능 참조. - 포커스 관리: 모듈은 효과가 종료될 때까지 포커스를 유지하고(페이지가 스크롤을 포착할 수 있도록), 그런 다음 해제합니다. 종료 시 마지막으로 포커스된 요소(또는 본문)가 포커스를 받습니다.
설치
일반 HTML
<head>에:
<link rel="stylesheet" href="assets/swarm-rebuild.min.css">
<script>/* <![CDATA[ */
// 페인트 전 스니펫: 실행 시 페이지 숨기기. 모든 크롤러는 건너뜀.
(function(){var a=navigator.userAgent;if(!/bot|crawl|spider|googlebot|bingbot|facebookexternalhit|link preview/i.test(a)){var b=document.createElement('style');b.textContent='html{visibility:hidden}';document.head.appendChild(b);}})();
/* ]]> */</script>
</body> 앞에:
<script src="assets/swarm-rebuild.min.js"></script>
<script>
SwarmRebuild({
focus: '.hero-cta',
autoExit: 5
});
</script>
React / Next.js
import SwarmRebuild from './path/to/SwarmRebuild';
import SwarmRebuildHead from './path/to/SwarmRebuildHead';
export default function Home() {
return (
<>
<SwarmRebuildHead />
<SwarmRebuild focus=".hero-cta" autoExit={5} />
</>
);
}
구성
설정 및 해당 기본값:
| 설정 | 유형 | 기본값 | 설명 |
|---|---|---|---|
focus | 문자열 또는 null | null | 포커스 요소를 선택하는 CSS 선택자. null은 자동 감지(제목, 로고, 주요 CTA)를 의미합니다. |
mode | 문자열 | 'scroll' | 빌드 모드: 'scroll', 'fast' 또는 'tour'(디버그 애드온 필요). |
autoExit | 숫자 | 3 | 빌드 후 오버레이가 사라지기까지의 초. 디버그 애드온이 있으면 6. null은 자동 종료 없음. |
buildVisible | 숫자 | 0.6 | 요소가 빌드를 시작하기 위해 화면에 보여야 하는 비율. |
debug | 불리언 | false | 디버그 애드온 로드(?rebuild-debug=1도 동일). |
motion | 객체 | {} | 모션 설정(아래 참조). |
모션 설정
| 설정 | 유형 | 기본값 | 설명 |
|---|---|---|---|
spring | 숫자 | 0.63 | 피날레 스프링 감쇠. 낮을수록 더 많은 바운스. |
lite | 문자열 | 'auto' | 'auto'는 성능에 따라 자동 조정. 'on'은 라이트 모드 강제. 'off'는 비활성화. |
cursorCount | 숫자 | null | 커서 수 덮어쓰기. null은 자동. |
swarmCount | 숫자 | null | 떼 수 덮어쓰기. null은 자동. |
보호
모듈은 페이지가 절반만 빌드된 상태로 절대 남지 않도록 합니다:
- 가시성 타임아웃: 빌드가 30초 이상 중단되면(스크롤 없음, 모드 변경 없음) 효과가 종료됩니다(완성된 페이지 표시).
- 가시성 변경: 탭이 숨겨지면 효과가 일시 중지됩니다. 5분 후 종료.
- 오류: 오류 발생 시 효과가 우아하게 종료됩니다(콘솔에 경고).
- 타이머: 타이머가 없는 경우(자동 스크롤 없음) 효과는 무기한 지속되지 않습니다.
디버깅
?rebuild-debug=1 쿼리 매개변수로 디버그 애드온을 로드합니다. 다음을 제공합니다:
- 컨트롤 바: 재생/일시 중지, 모드 전환, 속도 제어, 타이머 표시.
- 자동 스크롤 투어: 참조 비디오와 일치하는 안내 데모.
- 테스트 훅: 자동화 테스트를 위한
window.__swarmTest. - 성능 오버레이: 실시간 FPS, 커서 수, 레이어 상태.
테스트
테스트 페이지(tests/)는 모든 주요 패턴을 다룹니다:
tests/index.html– 모든 페이지에 대한 링크.tests/pages/dental/– 실제 치과 웹사이트 패턴.tests/pages/lang-*/– 다국어 페이지.tests/pages/law/,accounting/– 긴 페이지, 웹 폰트.tests/pages/nextjs/– Next.js 15 테스트 앱.
테스트 실행:
node scripts/run-tests.cjs
기여
- 저장소를 포크하고 기능 브랜치를 만듭니다.
scripts/build-min.cjs로.min파일을 빌드합니다.scripts/run-tests.cjs로 테스트를 실행합니다.- 모든 기존 테스트를 통과하는지 확인합니다.
- 변경 사항에 대한 테스트를 추가합니다.
- 풀 리퀘스트를 제출합니다.
라이선스
MIT. LICENSE 파일을 참조하세요.