이 글은 Today I Learn 시리즈의 212번째 기록입니다. (총 213개)

로그스톤 샵의 소리꽃 KeyBloom 페이지에는 모션마다 작은 데모 화면이 돈다. 앱을 실행하지 않아도 건반을 치면 파티클이 어떻게 피어나는지 보이게 하려는 것이다. 이 데모는 앱을 띄운 것이 아니라, 앱의 건반·파티클 그리기 코드를 웹페이지용으로 옮겨 온 사본이다. 사본이라서 생긴 일이 세 번 이어졌다.


받은 값에는 그 값이 전제한 화면이 들어 있다

09-07에 제품 페이지를 보다가 「파동」 칸의 데모가 파동이 아니라고 짚었다. 모션 이름 목록은 앱을 따라 순서가 바뀌었는데 데모 목록은 옛 순서대로라 이름과 데모가 한 칸씩 밀려 있었다. 순서를 맞추면서 파동 데모를 새로 넣었는데, 앱 값 없이 비슷하게 짜 넣은 것이라 앱과 달랐다. 파티클이 퍼지는 각도를 무작위로 뽑아 고리가 아니라 얼룩처럼 보였다.

09-12에 KeyBloom 세션이 앱에서 쓰는 값을 전부 보내 줬다. 각도는 반원에 고르게, 수명은 모두 같게, 퍼지는 속도는 점점 느려지게. 그대로 넣었더니 고리가 됐다. 그런데 한 값은 그대로 넣으면 안 됐다.

고리의 가로 반경은 「세로 반경 × 9/16」이었다. 앱 화면이 16:9(가로가 긴 와이드 화면)라서, 가로를 9/16만큼 줄여야 화면에서 정원으로 보인다. 샵 데모 타일은 16:9가 아니다. 4:3 타일을 건반 쪽으로 확대해 잘라 보여 준다. 여기에 9/16을 그대로 곱하면 고리가 옆으로 늘어난 타원이 된다. KeyBloom 세션도 값과 함께 「데모 화면이 16:9가 아니면 그 비율로 바꿔야 한다」고 적어 보냈다.

그래서 9/16을 숫자로 박지 않고, 데모가 그려지는 순간의 실제 화면 비율(세로 ÷ 가로)을 계산해 곱하게 했다. 타일 크기나 확대율이 바뀌어도 고리가 안 찌그러진다. 값이 맞춰진 뒤 화면을 보고 고리를 좀 더 넓게 해 달라고 했고, 개수를 늘려 마무리했다.

남이 준 숫자는 숫자만 오는 게 아니다. 그 숫자가 맞았던 화면·환경이 같이 들어 있다. 값을 받으면 「이 값은 어떤 조건에서 맞는 값인가」를 먼저 묻는다. 조건이 다르면 숫자가 아니라 숫자를 만든 규칙을 옮긴다.


사본은 원본이 바뀔 때 조용히 낡는다

09-16에 KeyBloom 0.1.8이 나왔다. 업데이트 내역을 샵에 붙여 달라는 요청에 「제품 페이지 문구·모션 목록은 바뀐 게 없다」는 말이 같이 왔다. 맞는 말이었다. 이번 버전에서 바뀐 것은 건반 모양이었다. 아래 모서리가 둥글어지고, 흰 건반 사이에 틈이 생기고, 검은 건반에 명암과 그림자가 들어갔다.

샵 데모는 옛 건반 그리기 코드의 사본이라 이 변화가 안 따라왔다. 문구도 모션 목록도 그대로인데 데모 속 건반만 앱보다 평평한 옛 모양으로 남았다. 샵 세션이 업데이트 내역을 반영하면서 이 차이를 알려 왔는데, 데모와 앱이 따로 그려지고 있다는 걸 그때 처음 알았다.

앞선 TIL 4에서 복제한 문장은 원본이 바뀌는 순간 거짓이 된다고 적었다. 이번엔 문장이 아니라 그림이 사본이었다. 「문구가 안 바뀌었다」는 확인은 문구에 대해서만 참이고, 앱이 그리는 방식을 바꾸면 데모는 아무 오류 없이 옛날이 된다. 깨지지 않으니 누가 보기 전까지 모른다. 사본을 두기로 했다면, 원본에서 무엇이 바뀌면 사본도 손봐야 하는지 목록으로 정해 둬야 한다. 여기서는 건반·파티클 그리기가 그 목록이다.


모양은 값보다 코드째 받는다

파동 때는 값을 받아 옮겼다. 건반 모양은 방식을 바꿨다. KeyBloom 세션이 「값만 옮기면 모양이 미묘하게 어긋나기 쉽다」며 앱의 건반 그리기 파일을 통째로 공유하겠다고 해서 그러라고 했다.

모양은 숫자 몇 개로 끝나지 않는다. 모서리를 어떤 곡선으로 깎는지, 그림자를 건반보다 먼저 그리는지 나중에 그리는지, 명암을 위에서 아래로 주는지 아래에서 위로 주는지 같은 순서와 방향이 모양을 만든다. 값만 받으면 이런 것은 받는 쪽이 짐작으로 채우고, 짐작한 만큼 어긋난다. 코드째 받으니 옮긴 뒤 원본과 한 줄씩 대조할 수 있었다.

옮겨 배포한 뒤 데모 건반이 앱과 같게 그려졌는지 화면으로 직접 확인했다. 앞으로 건반·파티클 그리기가 바뀌면 이번처럼 코드째 보내 달라고 KeyBloom 세션과 정해 뒀다.

동작의 크기(얼마나 빠르게·넓게)는 값으로 넘겨도 되지만, 모양과 그리는 순서는 코드로 넘겨야 같아진다. 무엇을 넘겨받을지 정할 때 「이게 숫자로 다 표현되나」를 먼저 본다.


요약

  • 받은 값에는 그 값이 맞았던 환경이 들어 있다. 조건이 다르면 숫자 대신 숫자를 만든 규칙을 옮긴다
  • 데모가 원본 코드의 사본이면 원본이 바뀔 때 오류 없이 낡는다. 무엇이 바뀌면 사본도 손볼지 정해 둔다
  • 크기·속도는 값으로, 모양·그리는 순서는 코드로 넘겨받는다

Series: Today I Learn

1 C++ 자료형(Data Type) 2 MD5 vs pHash 3 C++에서 함수의 선언과 정의 4 Tkinter padx, pady 5 메모리와 포인터 변수 6 Call by Value, Call by Reference, Call by Pointer 비교 7 const 8 Gemfile — Jekyll 프로젝트의 의존성 파일 9 kramdown-parser-gfm — Jekyll의 GFM 파서 10 파서(Parser) 11 AHU vs OHU 12 I might try it vs I'll try it 뉘앙스 차이 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 configuration key 15 Git stash vs discard 16 subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 Post 잔디 분석하기 18 Google Sheets Sync 최적화 19 DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 마크다운 표 그리는 방법 21 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 Django 보안 취약점 점검 및 수정 23 OOP Object-Oriented Programming 객체 지향 프로그래밍 24 Fernet 대칭 암호화 25 Jekyll 코드블록 안의 Liquid 태그 26 습관만들기 Pawbit TIL 1 27 insertOnConflictUpdate vs DoUpdate(target) 28 세션 필터 29 아코디언(Accordiaon) UI를 펼친상태로 만들기 30 input의 step 31 습관만들기 Pawbit TIL 2 32 습관만들기 Pawbit TIL 3 33 Word Cloud 34 Google Sheets를 데이터 버스로(with AppSheet) 35 Django 모델 텍스트 필드 자동 수집 패턴 36 localStorage로 섹션 토글 상태 유지 37 순차 ID 생성(`select_for_update()` + `max()` 조합) 38 역참조 검색과 distinct() 39 xlsx 다운로드와 로딩 오버레이 충돌 40 Android 파일 공유 MIME 타입 41 AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 42 크레센도 Phaser + TypeScript TIL 1 43 크레센도 Phaser + TypeScript TIL 2 44 크레센도 Phaser + TypeScript TIL 3 45 크레센도 Phaser + TypeScript TIL 4 46 크레센도 Phaser + TypeScript TIL 5 47 여둘까 Office Layout TIL 1 48 습관만들기 Pawbit TIL 4 49 여둘까 Office Layout TIL 2 50 여둘까 Office Layout TIL 3 51 크레센도 Phaser + TypeScript TIL 6 52 UTF-8 BOM과 PowerShell 파일 쓰기 53 소리꽃 KeyBloom TIL 1 54 습관만들기 Pawbit TIL 5 55 여둘까 Office Layout TIL 4 56 소리꽃 KeyBloom TIL 2 57 소리꽃 KeyBloom TIL 3 58 메트로놈 Simple Metronome TIL 1 59 소리꽃 KeyBloom TIL 4 60 메트로놈 Simple Metronome TIL 2 61 소리꽃 KeyBloom TIL 5 62 습관만들기 Pawbit TIL 6 63 크레센도 Phaser + TypeScript TIL 7 64 메트로놈 Simple Metronome TIL 3 65 소설 타임라인 관리 도구 Lumior TIL 1 66 습관만들기 Pawbit TIL 7 67 정적 블로그 SEO 정비와 Pagefind 검색 도입 68 크레센도 Phaser + TypeScript TIL 8 69 메트로놈 Simple Metronome TIL 4 70 습관만들기 Pawbit TIL 8 71 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 72 메트로놈 Simple Metronome TIL 5 73 모래게임 Sandrop TIL 1 74 습관만들기 Pawbit TIL 9 75 메트로놈 Simple Metronome TIL 6 76 모래게임 Sandrop TIL 2 77 모래게임 Sandrop TIL 3 78 습관만들기 Pawbit TIL 10 79 습관만들기 Pawbit TIL 11 80 메트로놈 Simple Metronome TIL 7 81 모래게임 Sandrop TIL 5 82 모래게임 Sandrop TIL 4 83 습관만들기 Pawbit TIL 12 84 모래게임 Sandrop TIL 6 85 소리꽃 KeyBloom TIL 6 86 모래게임 Sandrop TIL 7 87 모래게임 Sandrop TIL 8 88 소리꽃 KeyBloom TIL 7 89 모래게임 Sandrop TIL 9 90 소리꽃 KeyBloom TIL 8 91 모래게임 Sandrop TIL 10 92 소리꽃 KeyBloom TIL 9 93 콘티온 ContiOn TIL 1 94 소리꽃 KeyBloom TIL 10 95 콘티온 ContiOn TIL 2 96 습관만들기 Pawbit TIL 13 97 콘티온 ContiOn TIL 3 98 모래게임 Sandrop TIL 11 99 소리꽃 KeyBloom TIL 11 100 여둘까 Office Layout TIL 5 101 모래게임 Sandrop TIL 12 102 모래게임 Sandrop TIL 13 103 콘티온 ContiOn TIL 4 104 모래게임 Sandrop TIL 14 105 소리꽃 KeyBloom TIL 12 106 습관만들기 Pawbit TIL 14 107 모래게임 Sandrop TIL 15 108 모래게임 Sandrop TIL 16 109 소리꽃 KeyBloom TIL 13 110 온실 GreenHouse TIL 1 111 콘티온 ContiOn TIL 5 112 모래게임 Sandrop TIL 17 113 소리꽃 KeyBloom TIL 14 114 온실 GreenHouse TIL 2 115 콘티온 ContiOn TIL 6 116 모래게임 Sandrop TIL 18 117 콘티온 ContiOn TIL 7 118 모래게임 Sandrop TIL 19 119 소리꽃 KeyBloom TIL 15 120 모래게임 Sandrop TIL 20 121 모래게임 Sandrop TIL 21 122 소리꽃 KeyBloom TIL 16 123 소리꽃 KeyBloom TIL 17 124 소리꽃 KeyBloom TIL 18 125 여둘까 Office Layout TIL 6 126 소리꽃 KeyBloom TIL 19 127 소리꽃 KeyBloom TIL 20 128 콘티온 ContiOn TIL 8 129 콘티온 ContiOn TIL 9 130 로그스톤 상표 셀프 출원 TIL 1 131 소리꽃 KeyBloom TIL 21 132 로그스톤 샵 LogStone Shop TIL 1 133 소리꽃 KeyBloom TIL 22 134 로그스톤 샵 LogStone Shop TIL 2 135 소리꽃 KeyBloom TIL 23 136 모래게임 Sandrop TIL 22 137 모래게임 Sandrop TIL 23 138 소리꽃 KeyBloom TIL 24 139 로그스톤 샵 LogStone Shop TIL 3 140 모래게임 Sandrop TIL 24 141 소리꽃 KeyBloom TIL 25 142 모래게임 Sandrop TIL 25 143 MiniMacro TIL 1 144 모래게임 Sandrop TIL 26 145 콘티온 ContiOn TIL 10 146 Astro가 무엇인지, 왜 옮기는지 147 모래게임 Sandrop TIL 27 148 소리꽃 KeyBloom TIL 26 149 MiniMacro TIL 2 150 로그스톤 샵 LogStone Shop TIL 4 151 메트로놈 Simple Metronome TIL 8 152 모래게임 Sandrop TIL 28 153 여둘까 Office Layout TIL 7 154 메트로놈 Simple Metronome TIL 9 155 블로그 Astro 이관 TIL 156 여둘까 Office Layout TIL 8 157 로그스톤 샵 LogStone Shop TIL 5 158 모래게임 Sandrop TIL 29 159 오픈데이 Openday TIL 1 160 로그스톤 샵 LogStone Shop TIL 6 161 모래게임 Sandrop TIL 30 162 오픈데이 Openday TIL 2 163 모래게임 Sandrop TIL 31 164 Unreal Engine MCP TIL 1 165 모래게임 Sandrop TIL 32 166 소리꽃 KeyBloom TIL 27 167 콘티온 ContiOn TIL 11 168 오픈데이 Openday TIL 3 169 로그스톤 샵 LogStone Shop TIL 7 170 모래게임 Sandrop TIL 33 171 소리꽃 KeyBloom TIL 28 172 오픈데이 Openday TIL 4 173 여둘까 Office Layout TIL 9 174 오픈데이 Openday TIL 5 175 ScorePlayer TIL 1 176 모래게임 Sandrop TIL 34 177 BuildingHub TIL 1 178 ScorePlayer TIL 2 179 여둘까 Office Layout TIL 10 180 BuildingHub TIL 2 181 ScorePlayer TIL 3 182 Unreal Engine MCP TIL 2 183 궁 미로 PalaceMaze TIL 1 184 메트로놈 Simple Metronome TIL 10 185 메트로놈 Simple Metronome TIL 11 186 오픈데이 Openday TIL 6 187 BuildingHub TIL 3 188 Obsidian vault에서 코드만 빼기 — directory junction 189 ScorePlayer TIL 4 190 여둘까 Office Layout TIL 11 191 오픈데이 Openday TIL 7 192 URL은 바뀔 수 있는 것에 묶지 않는다 193 도구는 기능이 아니라 내 일에 맞는지로 고른다 194 돌이키기 힘든 변경은 작게 먼저 확인한다 195 궁 미로 PalaceMaze TIL 2 196 궁 미로 PalaceMaze TIL 3 197 소리꽃 KeyBloom TIL 29 198 오픈데이 Openday TIL 8 199 BuildingHub TIL 4 200 ScorePlayer TIL 5 201 로그스톤 샵 LogStone Shop TIL 8 202 여둘까 Office Layout TIL 12 203 오픈데이 Openday TIL 9 204 BuildingHub TIL 5 205 MiniMacro TIL 3 206 소리꽃 KeyBloom TIL 30 207 오픈데이 Openday TIL 10 208 여둘까 Office Layout TIL 13 209 소리꽃 KeyBloom TIL 31 210 궁 미로 PalaceMaze TIL 4 211 로그스톤 샵 LogStone Shop TIL 9 212 로그스톤 샵 LogStone Shop TIL 10 읽는 중 213 소리꽃 KeyBloom TIL 32