Skip to content
/ VizBeat Public

Delightful 3d audio visualization๐ŸŽธ๐ŸŽง

Notifications You must be signed in to change notification settings

WooWan/VizBeat

Repository files navigation

๐Ÿ’ ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋งŽ์€ interaction๊ณผ ์• ๋‹ˆ๋ฉ”์ด์…˜, 3d ๊ธฐ์ˆ ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿฃ VizBeat๋ฅผ ๋ฐฉ๋ฌธํ•ด์„œ ์ €์˜ ์—ญ๋Ÿ‰๊ณผ ๊ฐ€๋Šฅ์„ฑ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š” ๋ฐ๋ชจ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ

๋งŽ์€ ๋…ธ๋ ฅ๊ณผ ์‹œ๊ฐ„, ๊ทธ๋ฆฌ๊ณ  ์• ์ •์„ ๋‹ด์•„ ์กธ์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์™„์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ๋ฟ ์•„๋‹ˆ๋ผ, ๋””์ž์ธ, UI/UX, ์„œ๋ฒ„, ์ธํ”„๋ผ ๋ชจ๋‘ ์ง์ ‘ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

๐ŸŽธ ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

VizBeat๋Š” ์Œ์›์„ ๋ณด์ปฌ, ๊ธฐํƒ€, ๋ฒ ์ด์Šค, ํ”ผ์•„๋…ธ, ๋“œ๋Ÿผ์˜ ์Œ์› ํŠธ๋ž™์œผ๋กœ ๋ถ„๋ฆฌํ•œ๋’ค ๊ฐ ์Œ์›๋“ค์˜ ์ฃผํŒŒ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์‹œ๊ฐํ™”ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

(์Œ์› ๋ถ„๋ฆฌ๋Š” ํŒŒ์ด์ฌ ์„œ๋ฒ„์—์„œ AI ๋ชจ๋ธ์„ ์ด์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์•…๊ธฐ์˜ ์Œ์›์œผ๋กœ ๋ถ„๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.)

ย VizBeat๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค

1. Musics

โ˜‘ ๋ฎค์ง ํ”Œ๋ ˆ์ด๋ฆฌ์ŠคํŠธ

์™ผ์ชฝ ์ƒ๋‹จ์— ๋ฎค์ง ํ”Œ๋ ˆ์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ์Œ์› ์žฌ์ƒ/์ •์ง€, seek bar ๊ตฌํ˜„, ์ด์ „ ๋…ธ๋ž˜ ๋‹ค์Œ ๋…ธ๋ž˜ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. GIF์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์Œ์› ์žฌ์ƒ ๋ชฉ๋ก๊ณผ ์˜ค๋ฅธ์ชฝ์˜ Three.js ์•จ๋ฒ”๋“ค์€ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

โ˜‘ ์Œ์› ์—…๋กœ๋“œ
์Œ์› ์—…๋กœ๋“œ ์—…๋กœ๋“œ ์™„๋ฃŒ
Image1 Image2

์™ผ์ชฝ navbar์˜ ์Œ์•… ์ถ”๊ฐ€ํ•˜๊ธฐ๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ์Œ์›์„ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Œ์›์€ ์•„๋ž˜ 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • ์Œ์› ํŒŒ์ผ ์—…๋กœ๋“œ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์Œ์›์„ ์ง์ ‘ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Œ์›์˜ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ์•„ํ‹ฐ์ŠคํŠธ, ์Œ์› ์ œ๋ชฉ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

  • ์œ ํŠœ๋ธŒ ๊ฒ€์ƒ‰ ์œ ํŠœ๋ธŒ ๊ฒ€์ƒ‰ api๋ฅผ ํ†ตํ•ด ์œ ํŠœ๋ธŒ ์Œ์›์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โ˜‘ ์Œ์› ๋ถ„๋ฆฌ

์œ ์ €๊ฐ€ ์—…๋กœ๋“œ ๋˜๋Š” ์œ ํŠœ๋ธŒ ๊ฒ€์ƒ‰์œผ๋กœ ์Œ์›์„ ์„ ํƒํ•˜๊ณ  ์ œ์ถœํ•˜๋ฉด ์Œ์›์„ ํŒŒ์ด์ฌ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๊ณ , ์„œ๋ฒ„์—์„œ AI ๋ชจ๋ธ์„ ์ด์šฉํ•˜์—ฌ ์Œ์›์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


2. Stage

โ˜‘ Visualizing

์ค‘์‹ฌ ์› ๊ธฐ์ค€์œผ๋กœ cos, sin ํ•จ์ˆ˜๋ฅผ ํ†ตํ•˜์—ฌ ๋™์‹ฌ์›์„ ํ˜•์„ฑํ•˜๊ณ , ๋†’์ด์™€ ๋„ˆ๋น„๋Š” ์Œ์› ์ฃผํŒŒ์ˆ˜์˜ ์ œ๊ณฑ์— ๋น„๋ก€ํ•˜์—ฌ ๋ณ€ํ™”ํ•ฉ๋‹ˆ๋‹ค.

โ˜‘ ๋ฉ€ํ‹ฐ ํŠธ๋ž™ ํ”Œ๋ ˆ์ด์–ด

๋ฉ€ํ‹ฐ ํŠธ๋ž™ ํ”Œ๋ ˆ์ด์–ด์—์„œ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋งˆ์Šคํ„ฐ ๋ณผ๋ฅจ ๋ฐ ์‹ฑ๊ธ€ ๋ณผ๋ฅจ ์กฐ์ ˆ, ์žฌ์ƒ/์ •์ง€

  • ์Œ์› ๋‹ค์šด๋กœ๋“œ

    ์›๋ณธ ์Œ์›, ๋ถ„๋ฆฌ๋œ ์Œ์›๋“ค๊ณผ mixed ์Œ์›๊นŒ์ง€ ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘€ย ์ €๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์ด๋Ÿฐ ๊ณ ๋ฏผ์„ ํ–ˆ์–ด์š”

VizBeat์—์„œ๋Š” ๋ฌด๊ฑฐ์šด 3d๋ฅผ ๋งŽ์ด ๋‹ค๋ฃจ์–ด์•ผ ํ•˜๋‹ค ๋ณด๋‹ˆ, ์„ฑ๋Šฅ ์ตœ์ ํ™”๊ฐ€ ๊ผญ ํ•„์š”ํ–ˆ์–ด์š”

โ˜‘ WASM์„ ์‚ฌ์šฉํ•˜์—ฌ ์Œ์› ์ธ์ฝ”๋”ฉ ์„ฑ๋Šฅ์„ ๊ฐœ์„ (JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Œ€๋น„ 20๋ฐฐ ์†๋„)

๋ฉ€ํ‹ฐ ํŠธ๋ž™ ํ”Œ๋ ˆ์ด์–ด์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์Œ์› ํŠธ๋ž™๋“ค์„ ํ•˜๋‚˜์˜ mp3 ํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด์„œ ๋‹ค์šด๋กœ๋“œ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ Blob ํ˜•ํƒœ์˜ ์Œ์›์„ ํ•˜๋‚˜์˜ mp3๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ธ์ฝ”๋”ฉ ๊ณผ์ •์ด ํ•„์š”ํ•œ๋ฐ์š”, JavaScript library๋ฅผ ์‚ฌ์šฉํ•  ์‹œ, 3๋ถ„ ๊ธธ์ด์˜ ์Œ์› ๊ธฐ์ค€ 3๋ถ„์˜ ์ธ์ฝ”๋”ฉ ์‹œ๊ฐ„์ด ๊ฑธ๋ ค์„œ, ์„œ๋น„์Šค์—์„œ ์ ํ•ฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, 7๊ฐœ ์Œ์› ํŒŒ์ผ์„(7mb *8 = 56mb) ์„œ๋ฒ„์™€ ๋งค๋ฒˆ ์ฃผ๊ณ  ๋ฐ›๊ธฐ๋„ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ์„œ FFmpeg WASM์„ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

FFmpeg๋ž€ ๋ฏธ๋””์–ด์™€ ์˜ค๋””์˜ค ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ณ  c๋กœ ์ž‘์„ฑ๋˜์–ด์„œ ๋น ๋ฅธ ์†๋„๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ๊ฒƒ์ด FFmpeg WASM์ž…๋‹ˆ๋‹ค.

  • WASM์„ ๋„์ž…ํ•˜๋ฉด์„œ ์ด๋Ÿฐ ์–ด๋ ค์›€์ด ์žˆ์—ˆ์–ด์š”

       import { fetchFile, toBlobURL } from '@ffmpeg/util';
       
       export async function mergeAudios(blobs: Blob[], onProgress: (progress: number) => void) {
         const { FFmpeg } = await import('@ffmpeg/ffmpeg');
       	
       	// more code...
       })
```

ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Next.js ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, WASM์„ ์ตœ์ƒ๋‹จ์—์„œ importํ•  ์‹œ์— ์„œ๋ฒ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด dynamic import๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ importํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.

WASM ์„ฑ๋Šฅ์ธก์ • (ํŠธ๋ž™ 6๊ฐœ ๊ธฐ์ค€)

| ์Œ์› | ๋…ธ๋ž˜ ๊ธธ์ด | JavaScript(audio-encoder) | FFmpeg wasm | | --- | --- | --- | --- | | ์š”์•„์†Œ๋น„ ์•„์ด๋Œ | 3:34 | 182์ดˆ | 6.5์ดˆ | | Basket case | 3:02 | 170์ดˆ | 6.1์ดˆ |

182์ดˆ โ‡’ 6.5์ดˆ, 170์ดˆ โ‡’ 6.1์ดˆ๋กœ 20๋ฐฐ ์ด์ƒ์˜ ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

โ˜‘ ์˜ค๋””์˜ค Blob๋ฅผ Indexed DB๋ฅผ ์ €์žฅํ•˜์—ฌ ๋™์ผํ•œ ์˜ค๋””์˜ค ํŒŒ์ผ ์ค‘๋ณต ์š”์ฒญ ์ œ๊ฑฐ

1๋ฒˆ ํ•ญ๋ชฉ์—์„œ ์‚ดํŽด๋ณด์•˜๋“ฏ์ด, ๋ฉ€ํ‹ฐ ํŠธ๋ž™ ํ”Œ๋ ˆ์ด์–ด์—์„œ๋Š” 7๊ฐœ ์Œ์› ํŒŒ์ผ์„(7mb *8 = 56mb) ์„ S3์— ์š”์ฒญํ•˜๊ฒŒ ๋˜๋Š”๋ฐ์š”

์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด์„œ ์˜ค๋””์˜ค๋ฅผ ์š”์ฒญํ–ˆ๋Š”๋ฐ, ๋‹ค์šด๋กœ๋“œ ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ™์€ ํŒŒ์ผ์€ ์ค‘๋ณต์ ์œผ๋กœ ์š”์ฒญํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ํŽ˜์ด์ง€์˜ ๊ฒฝ์šฐ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋Œ€์‹ ์— IndexedDB๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ๋ณ‘๋ชฉ์„ ์ค„์—ฌ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง ์‹œ๊ฐ„์ด ์ค„์–ด๋“ค๊ณ , S3 ์š”๊ธˆ๋„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Local Storage ๋Œ€์‹ ์— IndexedDB๋ฅผ ์„ ํƒํ•œ ์ด์œ 

    1. Chrome ๊ธฐ์ค€์œผ๋กœ LocalStorage๋Š” domain ๋ณ„๋กœ ์ตœ๋Œ€ 10mb๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” 50mb์ด์ƒ์˜ mp3 ํŒŒ์ผ์„ ์ €์žฅํ•ด์•ผ ํ•จ์œผ๋กœ, ์ŠคํŽ™ ์ƒ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

    ๋ฐ˜๋ฉด, IndexedDB๋Š” ์‚ฌ์šฉ์ž ๋””์Šคํฌ์˜ 80%๊นŒ์ง€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ audio blob์„ ์ €์žฅํ•˜๊ธฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

    1. audio์„ blob์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š”๋ฐ, string ๋งŒ ์ €์žฅ๊ฐ€๋Šฅํ•œ local Storage๋Š” ์˜ค๋””์˜ค ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

โ˜‘ ์œ ๋ คํ•œ UI/UX ๋ฅผ ๊ตฌํ˜„

CSS๋„ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ๋ฒ”์œ„๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ , ํ”„๋กœ์ ํŠธ์—์„œ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ ์ ˆํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜๊ณผ ์œ ์ € ์ธํ„ฐ๋ ‰์…˜์„ UI์— ๋…น์—ฌ๋‚ผ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋žœ๋”ฉ ํŽ˜์ด์ง€์— framer motion๊ณผ scoll ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜๋“ค์„ ๋งŒ๋“ค์–ด์„œ ์‹œ๊ฐ์ ์ธ ์ฆ๊ฑฐ์›€์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • Headless library๋ฅผ ์‚ฌ์šฉํ–ˆ์–ด์š”.

Headelss library๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์„œ๋น„์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค๊ณ , ์ž‘๊ฒŒ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Material ui, Chakra ๋“ฑ์˜ ui ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์žˆ์ง€๋งŒ, ์ €์˜ ์„œ๋น„์Šค๋Š” UI ํ†ต์ผ์„ฑ์„ ์ฃผ๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— headless library๋ฅผ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ค‘์—์„œ๋„ Headless ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ƒํƒœ ์ œ์–ด์™€ ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” shadcn/ui ๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

โ˜‘ ๋ธŒ๋ผ์šฐ์ € ๋ฉˆ์ถค ํ˜„์ƒ ํ•ด๊ฒฐ (PR)

useFrame ์€ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๋‚ด๋ถ€ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” 3d util ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. (๋งค ํ”„๋ ˆ์ž„ 16.6ms ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค)

3d ์˜ค๋ธŒ์ ํŠธ์˜ ์›€์ง์ž„์„ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ setState ๋ฅผ ์ด์šฉํ•˜์—ฌ position์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ๋ณ€๊ฒฝ ์ „ํ›„ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์–ธ๋œป ๋ณด๊ธฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ๋“ฏ ๋ณด์ด์ง€๋งŒ, useFrame์€ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š”๋ฐ์š”,
์ฆ‰, setState๋ฅผ ํ†ตํ•ด height๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋งค frame๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ € ๋ฉˆ์ถค์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
`before`
useFrame(() => {
	setHeight(height - height * 0.2);
})

์›์ธ์„ ์•Œ์•„๋‚ด๋ฉด ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. useRef๋ฅผ ํ†ตํ•˜์—ฌ height๋ฅผ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
`after`
useFrame(() => {
	heightRef.current = height - height * 0.2;
})

๊ฐœ์„  ์ „ => ๊ฐœ์„ ํ›„ ์•ฝ scripting 77% ๊ฐ์†Œ

โ˜‘ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์•„์ง ๋ฐฐ์›Œ์•ผ ํ•  ๋‚ด์šฉ์ด ๋งŽ์ง€๋งŒ, ๊ธฐ์ค€์„ ์„ธ์›Œ์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ค‘์š”ํ•œ ๋กœ์ง์— ๋Œ€ํ•ด์„œ ํ…Œ์ŠคํŠธํ•˜์ž, ๋˜๋„๋ก ํ†ตํ•ฉํ…Œ์ŠคํŠธ๋กœ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋„ ๋ฆฌ์†Œ์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•˜๊ณ  ๊ฒ€์ฆํ•˜๊ธฐ ํž˜๋“  ๋กœ์ง์— ๋Œ€ํ•ด์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•˜๊ณ , ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์ ์ ˆํ•œ ๋ฒ”์œ„๋ฅผ ์ปค๋ฒ„ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, `์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š๋ƒ`๋ณด๋‹ค `์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ–ˆ๋Š”์ง€` ๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜๊ฐ€ ๋ช‡ ๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋ณด๋‹ค ์œ ์ €๊ฐ€ A๋ผ๋Š” ํ–‰๋™์„ ํ–ˆ์„ ๋•Œ์˜ B๋ผ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ๋„“์€ ํ…Œ์ŠคํŠธ ๋ฒ”์œ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Kent์˜ ํ…Œ์ŠคํŠธ ๊ฐ€์ด๋“œ๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ์— ์ง€์‹์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“–ย 3. ํšŒ๊ณ 

์™œ Vizbeat๋ฅผ ๋งŒ๋“ค์—ˆ์„๊นŒ?

ํ”„๋กœ์ ํŠธ๋ฅผ ํšŒ๊ณ ํ•˜๋Š” ์‹œ์ ์—์„œ ๋Œ์ด์ผœ๋ณด๋ฉด ์ •๋ง ๋งŽ์€ ์„ฑ์žฅ๊ณผ ๋‹ค์–‘ํ•œ ์‹œ๋„๋ฅผ ํ•ด๋ดค๋˜ ๊ฒƒ ๊ฐ™์•„์š”.

์กธ์—… ํ”„๋กœ์ ํŠธ ์ฃผ์ œ๋ฅผ ์„ ์ •ํ•  ๋•Œ, 2๊ฐ€์ง€ ๊ธฐ์ค€์„ ์„ธ์› ์–ด์š”

  1. 6๊ฐœ์›” ์ด์ƒ ๋ชฐ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์ œ์ธ๊ฐ€?

    ํ”„๋กœ์ ํŠธ์— ๊ด€ํ•ด ์•„๋ž˜ ์งˆ๋ฌธ์„ ๋ฐ›์€ ์ ์ด ์žˆ์–ด์š”. ์ด ํ”„๋กœ์ ํŠธ๋Š” ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ์–ด?

BM์ด ์–ด๋–ป๊ฒŒ๋ผ?

> ๋ฌผ๋ก  ์ค‘์š”ํ•œ ์งˆ๋ฌธ์ด์ง€๋งŒ ์ œ๊ฐ€ ์˜จ์ „ํžˆ 6๊ฐœ์›” ์ด์ƒ ๋ชฐ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์ œ์—ฌ์•ผ ํ–ˆ์–ด์š”
  1. ๊ธฐ์ˆ ์  ์—ญ๋Ÿ‰๊ณผ ์ž ์žฌ๋ ฅ์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์ธ๊ฐ€?

์ด๋™์šฑ๋‹˜์˜ ๊ธ€ "๊ทธ ์—ฐ์ฐจ์น˜๊ณค ์ž˜ํ•˜๋„ค"์˜ ํ•จ์ •์„ ์ฝ์œผ๋ฉด์„œ ๊ต‰์žฅํžˆ ๊ณต๊ฐ๊ฐ”๋Š”๋ฐ์š”,

์ €๋Š” ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž ์น˜๊ณ  ์ž˜ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹Œ ์ž˜ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์‹œ์žฅ์— ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž๋“ค์ด ๋งŽ์•„์กŒ๊ณ , ๊ทธ ์ค‘์—์„œ ๋ˆˆ์— ๋„๊ธฐ ์œ„ํ•ด์„œ ๋†’์€ ํ€„๋ฆฌํ‹ฐ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ–ˆ์–ด์š”


์™„์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ดค์„ ๋•Œ ๊ธฐ๋ณธ๊ธฐ์™€ ํŠธ๋ Œ๋“œ ์‚ฌ์ด์—์„œ ์ ์ ˆํžˆ ๊ท ํ˜•์„ ๋งž์ถ”๋ฉด์„œ ๋‹ค์–‘ํ•œ ์‹œ๋„๋ฅผ ํ•˜๋ฉด์„œ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๋งŒ์กฑ์Šค๋Ÿฌ์šด ๊ฒฐ๊ณผ๋ฌผ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์˜คํ”ˆ ์†Œ์Šค ๊ธฐ์—ฌ

VizBeat ํ”„๋กœ์ ํŠธ ํšŒ๊ณ ์—์„œ ์˜คํ”ˆ์†Œ์Šค ๊ธฐ์—ฌ๋ฅผ ๋นผ๋†“์„ ์ˆ˜๊ฐ€ ์—†์„ ๊ฒƒ ๊ฐ™์•„์š”

์˜คํ”ˆ์†Œ์Šค ๊ธฐ์—ฌ๋Š” ์ €์™€ ๊ฑฐ๋ฆฌ๊ฐ€ ๋จผ ์ด์•ผ๊ธฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๊ณ , ๋ช‡ ๋…„ ํ›„์— ์‹ค๋ ฅ์„ ํ‚ค์›Œ์„œ ์‹œ๋„ํ•ด๋ณด์ž๊ณ  ์ƒ๊ฐํ–ˆ์–ด์š”

๊ฒฐ๊ณผ์ ์œผ๋กœ, Vizbeat๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ 3๊ฐœ์˜ pull request๋ฅผ ํ†ตํ•ด ์˜คํ”ˆ์†Œ์Šค์— ๊ธฐ์—ฌํ–ˆ์–ด์š”

์ œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ , ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋”์šฑ ๋œป ๊นŠ์—ˆ์Šต๋‹ˆ๋‹ค.

(์ฒซ pull request๊ฐ€ ๋จธ์ง€๋˜์—ˆ๋‹ค๋Š” ์•Œ๋ฆผ์„ ๋ฐ›๊ณ  ๐Ÿณ)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ €์ž์™€ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„œ๋กœ์˜ ์ƒ๊ฐ์„ ๋‚˜๋ˆ„๊ณ  PR์„ ์™„์„ฑํ•ด๋‚˜๊ฐ€๋Š” ๊ฒƒ์€ ํŠนํžˆ ์ฆ๊ฑฐ์šด ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค๐Ÿ˜Š


์˜ฌํ•ด 2์›”์— ์นœ๊ตฌ์™€ ํ•จ๊ป˜ ์กธ์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜์˜€๋Š”๋ฐ, ๋ฐ˜๋…„์ด ์ง€๋‚˜ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค ๋งŒ๋“ค ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•™๊ต, ๊ฐœ๋ฐœ ๋™์•„๋ฆฌ, ์ธํ„ด์„ ๋ณ‘ํ–‰ํ•˜๋ฉด์„œ ๊ฝค ๋ฐ”์œ 4ํ•™๋…„์„ ๋ณด๋‚ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹น์žฅ ์ด๋ฒˆ ๋‹ฌ๋ถ€ํ„ฐ ์ทจ์—… ์‹œ์žฅ์— ๋›ฐ์–ด๋“ค ์ƒ๊ฐ์„ ํ•˜๋‹ˆ ๋–จ๋ฆฌ๊ธฐ๋„ ํ•˜๊ณ , ๊ฑฑ์ •๋„ ๋˜์ง€๋งŒ, ๊ฐ€์Šด ๋›ฐ๋Š” ์ผ์„ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Reference

https://jojoldu.tistory.com/68 https://kentcdodds.com/blog/write-tests https://all-dev-kang.tistory.com/entry/Nextjs-๋ถ„๋ฆฌ๋œ-์Œ์›์„-๋‹ค์‹œ-ํ•˜๋‚˜๋กœ-Web-Assembly-web-worker

About

Delightful 3d audio visualization๐ŸŽธ๐ŸŽง

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages