4주차 · 수업 노트
클릭으로 고르기 — 서재의 완성
책장 코드는 3주차와 같아요. 이번 주 미션은 클릭 — 책을 고르면 그 책이 앞으로 돌아 나오고, 아래에 제목이 뜹니다. 나만의 서재가 완성돼요.
첫 번째 · 이름표
책마다 각도·제목·저자를 붙여 둡니다
상수 저자들 = [ // 표지에 적힌 저자들 — 내 책의 저자로 바꿔 보세요 (번호 순서대로) 'Elwin Marrow', 'Evelyn Thorne', 'Amelia Rowan', 'Liora Vance', 'Rowan Ellis', 'Marcus Ellsworth', 'Corin Ashvale', 'Iris Calder', '편집부', 'Tobias Quill', 'Mirelle Dastan', 'Adrian Holloway', 'Celeste Briar', 'Naomi Ashcroft', 'Julian Mercer', ] 상수 제목들 = [ // 표지에 적힌 책 제목들 — 내 책의 제목으로 바꿔 보세요 (번호 순서대로) "The Clockmaker's Silence", "The Last Orchard of Winter", "The Quiet Architecture of Everyday Decisions", "A Garden Beneath the Ocean Floor", "The Library Where Shadows Borrow Names", "Beyond the Horizon of Innovation", "The Seventh Map of Nowhere", "The Sea That Dreamed of Mountains", "The Energy Journal", "When Lanterns Learned to Breathe", "Ashes That Remember the Wind", "The City Beneath the Sleeping Sun", "The Flowers That Chose the Moon", "The Moon Weaver's Daughter", "When Light Waited", ]
반복문 위에 저자·제목 목록을 배열로 준비합니다 — i번째 책은 저자들[i]·제목들[i]. 표지 이미지에 인쇄된 그대로예요.
제목 안에 작은따옴표(')가 들어 있어서 제목들은 큰따옴표("...")로 감쌌어요 — 문자열을 감싼 따옴표와 같은 따옴표가 안에 또 나오면 문장이 거기서 일찍 끝나 버립니다.
// 3주차 반복문 끝에 세 줄 추가 책.각도 = 각책의각도 // 클릭했을 때 쓰려고 이름표처럼 붙여 둔다 책.제목 = 제목들[i] // 표지에 적힌 책 제목 책.저자 = 저자들[i] // 표지에 적힌 저자 이름 그룹.추가(책)
클릭했을 때 "이 책이 몇 도에 있고, 무슨 책이고, 누가 썼는지" 바로 알 수 있게, 책마다 각도·제목·저자를 붙여 둡니다.
이번 주는 맨 위 각도 계산 줄부터 이름을 각책의각도로 씁니다 — 책.각도 = 각도라고 쓰면 왼쪽·오른쪽이 같은 말처럼 보여 헷갈리니, 처음부터 "이 책의 각도"라는 뜻이 뚜렷한 이름으로 시작해요.
내가 만든 물건에는 마음대로 이름표(새 속성)를 붙여 둘 수 있어요 — 클릭했을 때 꺼내 씁니다.
두 번째 · 정보창
화면 아래 책 제목 띄울 자리
상수 정보창 = 문서.만들기('div')
정보창.스타일.cssText = 'position:fixed; left:20px; bottom:20px; color:white'
정보창.스타일.표시 = '숨김'
문서.본문.붙이기(정보창)
문서.만들기('div')는 HTML 조각을 만드는 것 — 화면 아래에 뜨는 글줄입니다. 처음엔 표시 = '숨김'으로 숨겨 두고, 책을 클릭하면 글자를 넣고 보여줄 거예요.
정보창.글자 = 넣을 글, 정보창.스타일.표시 = '보임'/'숨김' 으로 보이고 숨깁니다.
세 번째 · 애니메이션
평소엔 자동 회전, 고르면 그 책 앞으로
변수 선택책 = 없음 // 아직 아무 책도 고르지 않았다
렌더러.애니메이션시작(() => {
만약 (선택책 === 없음) {
그룹.회전.y += 0.003
}
렌더러.렌더링(장면, 카메라)
})
3주차 애니메이션에 만약 한 줄이 생겼어요. 고른 책이 없으면(없음) 3주차처럼 자동 회전, 책을 고르면 자동 회전이 멈추고 — 아래 클릭 코드의 부드럽게돌기가 그 책을 앞으로 스르륵 데려갑니다.
나머지(%)도, 목표 변수도 여기엔 필요 없어요. "고르면 멈춘다, 빈 곳을 누르면 다시 돈다"만 쓰고, 스르륵 이동은 부드럽게돌기가 알아서 합니다.
없음은 "아직 아무것도 고르지 않았다"라는 빈 값이에요 — 실행할 때 null로 번역됩니다. 참·거짓처럼 코드의 낱말입니다.
네 번째 · 창 이벤트 모아 두기
클릭 — 광선으로 책을 찾습니다
상수 광선 = 새 삼차원.광선()
창.이벤트걸기('클릭', (e) => {
광선.겨누기(e, 카메라)
상수 포인트 = 광선.닿은것찾기(그룹.자식들)
만약 (포인트[0]) {
선택책 = 포인트[0].물체
그룹.부드럽게돌기(선택책.각도 - 수학.파이 / 4)
정보창.글자 = 선택책.제목 + ' · ' + 선택책.저자
정보창.스타일.표시 = '보임'
} 아니면 {
선택책 = 없음
정보창.스타일.표시 = '숨김'
}
})
창.이벤트걸기('크기변경', () => {
카메라.화면비율 = 창.너비 / 창.높이
카메라.투영갱신()
렌더러.크기설정(창.너비, 창.높이)
})
광선(레이캐스터)은 카메라에서 마우스 쪽으로 빛줄기를 쏴서, 닿은 기록을 찾아 줍니다. 광선.겨누기(e, 카메라)가 클릭한 지점 쪽으로 광선을 겨누고, 닿은것찾기(그룹.자식들)가 닿은 기록을 가까운 순서로 돌려줘요 — 기록에는 물체 말고도 거리·좌표 같은 정보가 더 들어 있어서, 실제 물체는 포인트[0].물체로 따로 꺼냅니다. 책에 닿았으면 부드럽게돌기가 그 책의 각도까지 가까운 방향으로 스르륵 돌려줍니다. 빈 곳을 누르면 선택책이 없음으로 돌아가 다시 자동 회전.
Tip
카메라는 45도 방향(12, 0, 12)에서 가운데를 보고 있어요. 그래서 "고른 책이 정면에 오려면 그룹을 얼마나 돌려야 하지?"의 답이 부드럽게돌기(책.각도 - 수학.파이/4) 입니다 — 책의 원래 각도에서 카메라 방향(45도 = 파이/4)을 뺀 만큼.
창 이벤트(클릭·크기변경)는 매주 같은 습관으로 코드 맨 아래에 모아 둡니다.
다섯 번째 · 부드럽게돌기의 수학
원판을 몇 도 돌려야 그 책이 카메라 앞에 올까
카메라는 움직이지 않아요 — 항상 45도 자리만 봅니다. 책마다 원래 자리 번호가 있어요 — 책.각도 (만들 때 붙인 이름표). 원판(그룹)을 돌린 만큼, 책의 실제 자리는 그만큼 줄어듭니다. 돌릴 양 = 책의 원래 각도 − 45도 예) 120도 자리 책을 클릭하면 — 원판을 120 − 45 = 75도 돌린다 → 책의 실제 자리 = 120 − 75 = 45도 = 카메라 앞!
이게 부드럽게돌기(선택책.각도 - 수학.파이/4)의 전부예요. 괄호 안의 식이 "몇 도 돌릴지"(목표)를 정하고, 부드럽게돌기는 그 목표까지 매 프레임 남은 거리의 4%씩 다가가 약 1.5초에 걸쳐 스르륵 돕니다.
책을 클릭해 보세요 — 원판이 공식대로 돌아 그 책을 카메라 앞으로 데려갑니다 (빈 곳 클릭 = 선택 해제)
책의 각도 = — · 목표 = 책의 각도 − 45도 = — · 지금 그룹.회전 = 0도
위에서 내려다본 그림이에요. 아무것도 안 고르면 천천히 자동 회전(+= 0.003), 책을 고르면 자동 회전이 멈추고 목표까지 남은 거리의 4%씩 — 실제 수업 코드와 똑같은 규칙으로 움직입니다.
마무리
4주 동안 배운 것
1주차 장면 · 카메라 · 렌더러 · 빛 · 도형 · 애니메이션 2주차 텍스처 · 반복문 · 이벤트(휠) · 나머지 연산 3주차 cos·sin 원형 배치 · 자동 회전 · 웹 배포 4주차 클릭(광선) · 서재 완성
여섯 단계 뼈대(장면→카메라→렌더러→빛→도형→애니메이션)는 4주 내내 그대로였어요. 그 위에 매주 한 겹씩 쌓아서 서재가 완성됐습니다.
이제 표지 이미지를 내 그림으로 바꾸면, 진짜 "나의 서재"가 됩니다.