Skip to content

Latest commit

ย 

History

History
497 lines (336 loc) ยท 37.5 KB

README.md

File metadata and controls

497 lines (336 loc) ยท 37.5 KB


Re-Direction์€ ๊ฐ€๋กœ ์˜์ƒ์˜ ํ”ผ์‚ฌ์ฒด์˜ ์›€์ง์ž„์„ ๋ถ„์„ํ•ด์„œ ์„ธ๋กœ ์˜์ƒ์œผ๋กœ ๋ฐ”๊พธ์–ด์ฃผ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.


Deployed website | Frontend Repository | Backend Repository


๐Ÿ“– CONTENTS


๐Ÿ” Preview


๐Ÿ›  Tech Stacks

Client

JavaScript React Vite TailwindCSS

Server

NodeJS Express.js Multer FFmpeg Sharp

Test

React Dom Testing Vitest Jest

Deployment

Netlify AWS Elastic Beanstalk


๐Ÿ’ฅ Motivation

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


๐Ÿ•น๏ธ Features

๋™์˜์ƒ ์—…๋กœ๋“œ

  • ์‚ฌ์šฉ์ž๋Š” Upload your video๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ ๋™์˜์ƒ์„ ๊ณ ๋ฅด๊ฑฐ๋‚˜ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž์„ ํ•˜์—ฌ ๋™์˜์ƒ ์—…๋กœ๋“œ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ตœ๋Œ€ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ๋Š” 100MB์ด๋ฉฐ, ๋™์˜์ƒ ํฌ๋งท๋งŒ ์—…๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜์ง€ ์•Š๋Š” ํŒŒ์ผ์ด ์—…๋กœ๋“œ ๋  ๊ฒฝ์šฐ, ๊ด€๋ จ ์•ˆ๋‚ด๋ฌธ๊ตฌ๊ฐ€ ์“ฐ์—ฌ์ง„ ํŽ˜์ด์ง€๋กœ ์ด๋™๋ฉ๋‹ˆ๋‹ค.

๋ถ„์„ ์˜์—ญ๊ณผ ์˜ˆ๋ฏผ๋„ ์„ค์ •

  • ์‚ฌ์šฉ์ž๋Š” ๋ชจ์…˜ ํžˆํŠธ๋งต์„ ํ†ตํ•ด ๋ชจ์…˜๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ณ  ์›ํ•˜๋Š” ๊ตฌ๊ฐ„๊ณผ ์˜ˆ๋ฏผ๋„๋ฅผ ์ปจํŽŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ชจ์…˜ํŠธ๋ž™ํ‚น์„ ์ ์šฉํ•˜๊ณ ์‹ถ์€ ๊ตฌ๊ฐ„์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ์ด ๊ตฌ๊ฐ„๋‚ด์˜ ๋ชจ์…˜๋งŒ ์ถ”์ ํ•˜์—ฌ ์„ธ๋กœ์˜์ƒ์ด ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.
    • ๋ชจ์…˜ํŠธ๋ž˜ํ‚น ์˜ˆ๋ฏผ๋„๋ฅผ sensitive, medium, modest ์ค‘์—์„œ ์ทจํ–ฅ์— ๋”ฐ๋ผ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.
      • sensitive: ๋ชจ์…˜์„ ๋น ๋ฅด๊ฒŒ ์ถ”์ ํ•˜๋‚˜ ๋‹ค์†Œ ์‚ฐ๋งŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • modest: ๋ชจ์…˜์„ ์ฒœ์ฒœํžˆ ์ถ”์ ํ•˜๋‚˜ ์ •ํ™•๋„๊ฐ€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ๋ฌผ ๊พธ๋ฏธ๊ธฐ

  • ์‚ฌ์šฉ์ž๋Š” ๊ฒฐ๊ณผ ์˜์ƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ๊ตฌ์™€ ์Šคํ‹ฐ์ปค๋ฅผ ์„ ํƒํ•˜์—ฌ ์˜์ƒ์„ ๊พธ๋ฏธ๊ณ  ์ปจํŽŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊พธ๋ฏธ๊ธฐ๋ฅผ ์›์น˜์•Š์œผ๋ฉด ๊ทธ๋Œ€๋กœ ์ปจํŽŒ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
    • ์šฐ์ธก์ƒ๋‹จ์˜ ์Šคํ”ผ์ปค๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์†Œ๋ฆฌ๋ฅผ ์ผœ๊ฑฐ๋‚˜ ๋Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฌธ๊ตฌ๋Š” ์ด 8๊ฐ€์ง€ ํฐํŠธ๊ฐ€ ์ค€๋น„๋˜์–ด ์žˆ์œผ๋ฉฐ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž์„ ํ†ตํ•ด ์ž์œ ๋กญ๊ฒŒ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์˜์–ด๋งŒ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
      • ์ƒ‰์ƒ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๋นจ๊ฐ•, ํ•˜์–‘, ํŒŒ๋ž‘, ๊ฒ€์ •)
      • ๋ฐฐ๊ฒฝ์ƒ‰์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (ํ•˜์–‘, ๊ฒ€์ •, ํˆฌ๋ช…)
    • ์Šคํ‹ฐ์ปค๋Š” ์ด 9๊ฐ€์ง€ ๋””์ž์ธ์ด ์ค€๋น„๋˜์–ด ์žˆ์œผ๋ฉฐ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž์„ ํ†ตํ•ด ์ž์œ ๋กญ๊ฒŒ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ ๋ฐ˜ํ™˜๋ฐ›๊ธฐ

  • ์ตœ์ข…๊ฒฐ๊ณผ๋ฌผ์ด ์ž๋™์œผ๋กœ ๋‹ค์šด๋กœ๋“œ๋˜์–ด download ํด๋”์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” .mp4 ํ™•์žฅ์ž์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ขŒ์ธก ์ƒ๋‹จ์˜ ๋กœ๊ณ ๋ฅผ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ try with another video?๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋ฉ”์ธํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.

๐Ÿ” Challenges

1. ์–ด๋–ป๊ฒŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ชจ์…˜ ๋ถ„์„์„ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

3์ฐจ์›์˜ ๊ณต๊ฐ„์•ˆ์—์„œ ์‚ฌ๋ฌผ์ด ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ์šฐ๋ฆฌ๋Š” โ€œ์›€์ง์ž„โ€์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ™”๋ฉด ์† ์˜์ƒ๋งค์ฒด์—์„œ โ€œ์›€์ง์ž„โ€์€ ์–ด๋–ป๊ฒŒ ์ •์˜ ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”?

์˜์ƒ๋Š” ๋งŽ์€ ์ˆ˜์˜ ์ด๋ฏธ์ง€๊ฐ€ ์—ฐ์†์ ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ „ํ™˜ํ•˜์—ฌ ํ™”๋ฉด์ด ์›€์ง์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋งŒ๋“œ๋Š” ๋””์ง€ํ„ธ๋งค์ฒด์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜์ƒ์„ ์ด๋ฃจ๋Š” ์—ฐ์†๋œ ์ด๋ฏธ์ง€๋ฅผ ํ”„๋ ˆ์ž„์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ณด๊ณ  ์žˆ๋Š” ํ”„๋ ˆ์ž„๊ณผ ๋‹ค์Œ์— ์˜ฌ ํ”„๋ ˆ์ž„, ๊ทธ ์‚ฌ์ด์— โ€œ๊ฒฉ๋ ฌํ•œ ์ƒ‰์ƒ ๋ณ€ํ™”โ€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ, ํ™”๋ฉด์€ ๋‹จ์ˆœํžˆ ํ‘œ์‹œํ•˜๋Š” ์ƒ‰๊น”์„ ๋ฐ”๊พผ๊ฒƒ์— ๋ถˆ๊ณผํ•˜์ง€๋งŒ ์‚ฌ๋žŒ์€ ์ด๋ฅผ ๋ณด๊ณ  โ€œ์›€์ง์ž„โ€์ด๋ผ๊ณ  ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.

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


2. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์—์„œ ๋น„๋””์˜ค์™€ ์ด๋ฏธ์ง€ ๋‹ค๋ฃจ๊ธฐ

2-1. ๊ธฐ์ˆ  ๊ฒ€์ฆ

๋ฐ”๋‹๋ผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋งŒ์œผ๋กœ๋Š” ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†์–ด, ์–ด๋–ป๊ฒŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•ด์•ผํ• ์ง€ ๋ง‰๋ง‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์กฐ์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ ์˜คํ”ˆ์†Œ์Šค ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํ”„๋ ˆ์ž„์›Œํฌ์ธ FFmpeg์˜ ์กด์žฌ๋ฅผ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. FFmpeg๋Š” npm ํŒจํ‚ค์ง€๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ปค๋งจ๋“œ๋ฅผ ํ†ตํ•ด ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ Node.js ๋‚ด์žฅ๋ชจ๋“ˆ์ธ child_process์„ ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋™์˜์ƒํŒŒ์ผ์˜ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋‚˜ ๊ฐ€๋กœ ์„ธ๋กœ ํฌ๊ธฐ ๊ฐ™์€ ๊ทœ๊ฒฉ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” FFmpeg๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ์ธ FFprobe๋ฅผ ์ด์šฉํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ, FFmpeg๋กœ ์ถ”์ถœํ•œ ํ”„๋ ˆ์ž„ ์ด๋ฏธ์ง€์˜ ํ”ฝ์…€์„ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ค ๊ธฐ์ˆ ์ด ํ•„์š”ํ• ์ง€ ์กฐ์‚ฌ๋ฅผ ํ•œ ๊ฒฐ๊ณผ, Canvas API์˜ getImageData()์™€ ๋ธ”๋ Œ๋”ฉ์„ ์œ„ํ•œ ์†์„ฑ์ธ globalCompositeOperation์„ ์ด์šฉํ•œ ์˜ˆ์‹œ๊ฐ€ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฝ์šฐ ๋ฌด๊ฑฐ์šด ๋ฉ€ํ‹ฐ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” ํŠน์ง•์ด ์žˆ๋‹ค๋ณด๋‹ˆ ํด๋ผ์ด์–ธํŠธ์™€์˜ ์ผ๋ จ์˜ ํ†ต์‹ ์—์„œ ์ˆ˜๋ฐฑ, ์ˆ˜์ฒœ๊ฐœ์— ๋‹ฌํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ์ผ์€ ํ”ผํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์˜์ƒ์„ ๋ถ„ํ•ด => ์ฒ˜๋ฆฌ => ์žฌ์กฐ๋ฆฝํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๊นŒ์ง€์˜ ๊ณผ์ •์—์„œ ์œ ์ €์—๊ฒŒ ์ด๋ฏธ์ง€๋ฅผ ๋ Œ๋”ํ•˜์—ฌ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๊ณผ์ •์ด ์—†๋Š” ์ ๋„ ๊ณ ๋ คํ•˜์—ฌ, Canvas API๋Š” ์„ ํƒ์ง€์—์„œ ์ œ์™ธํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์„œ๋ฒ„์‚ฌ์ด๋“œ์ธ Node.js์—์„œ ์ด์šฉ๊ฐ€๋Šฅํ•œ ์ด๋ฏธ์ง€ ํ”„๋กœ์„ธ์‹ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ์„ ์ง€ ์กฐ์‚ฌํ•ด๋ณด์ž, ๋Œ€ํ‘œ์ ์œผ๋กœ Jimp์™€ Sharp๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์žฅ๋‹จ์ ์„ ๋น„๊ตํ•ด๋ณด์•˜์œผ๋‚˜ C๋กœ ๊ฐœ๋ฐœ๋œ Sharp๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํ‚น ์ ์ˆ˜๊ฐ€ ์•ž๋„์ ์œผ๋กœ ๋†’์•„, ์ˆ˜๋งŽ์€ ๋น„๋””์˜ค ํ”„๋ ˆ์ž„์„ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ํ”„๋กœ์ ํŠธ์— ๋”ฑ ๋งž๊ฒ ๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Sharp๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” Canvas API์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ธ”๋ Œ๋”ฉ์„ ์œ„ํ•œ composite ๋‚ด์žฅ๋ฉ”์„œ๋“œ๋„ ์กด์žฌํ•˜์˜€๊ธฐ์— Canvas API๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ง  ๋ชจ์…˜๋ถ„์„์˜ ๊ณผ์ •์„ ๊ทธ๋Œ€๋กœ ์‹คํ˜„์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฆฌ๋ผ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

composite๋Š” ๋‘ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ๋กœ, ์˜ต์…˜์œผ๋กœ "difference"๋ฅผ ์ฃผ์–ด ๋‘ ์ด๋ฏธ์ง€ ์‚ฌ์ด์— ๋‹ฌ๋ผ์ง„ ๋ถ€๋ถ„์ด ๊ฐ•์กฐ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”บ difference์˜ต์…˜์„ ์ ์šฉํ•œ ํ•ฉ์„ฑ์ด๋ฏธ์ง€


์›€์ง์ž„์ด ๊ฑฐ์˜ ์—†๋Š” ํ”ฝ์…€์€ ์–ด๋‘์šด ์ƒ‰๊น”์„ ๋„๊ณ  ์›€์ง์ž„์ด ๋งŽ์€ ํ”ฝ์…€์€ ๋ฐ์€ ์ƒ‰๊น”์„ ๋„๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. RGB๋Š” ํ”ฝ์…€์ด ๊ฐ€์ง„ ์‚ผ์›์ƒ‰์˜ ์†์„ฑ์œผ๋กœ์จ ์ƒ‰์ƒ์ด ๋ฐ์„ ์ˆ˜๋ก RGB์˜ ํ•ฉ๊ณ„ ์Šค์ฝ”์–ด๊ฐ€ ๋†’์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์œ„ ์ด๋ฏธ์ง€์˜ ๋ชจ๋“  ํ”ฝ์…€์˜ RGB ์Šค์ฝ”์–ด ๋ถ„์„์„ ํ•˜๋ฉด ๋ณ€ํ™”๊ฐ€ ๊ฒฉ๋ ฌํ–ˆ๋˜ ๋ถ€๋ถ„์„ ๊ฐ€๋ ค๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


2-2. ๋ถ„์„์‹œ ์ถ”์ถœํ•˜๋Š” ํ”„๋ ˆ์ž„์„ ์ตœ๋Œ€ํ•œ ๊ฐ€๋ณ๊ฒŒ

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

์˜ˆ๋ฅผ ๋“ค์–ด 25fps์˜ 1280 x 720 ์˜์ƒ์ด ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ, ๊ณ ์ž‘ 15์ดˆ ๋‚จ์ง“๋˜๋Š” ์˜์ƒ์—์„œ ์ถ”์ถœ๋˜๋Š” ํ”„๋ ˆ์ž„์€ 384๊ฐœ์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ชจ์…˜๋ถ„์„ ์‹œ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋กœ์ง์ด ์ˆœํ™˜ํ•ด์•ผํ•˜๋Š” ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜๋Š” ์ด 8847360000๊ฐœ๋กœ ์–ด๋งˆ์–ด๋งˆํ•œ ๋ถ„๋Ÿ‰์ด ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ํ”ผ์‚ฌ์ฒด์˜ ์†๋„๊ฐ€ ์ด์•Œ์ˆ˜์ค€์ด ์•„๋‹Œ ์ด์ƒ, 25๋ถ„์˜ 1์ดˆ์˜ ๋ชจ์…˜์„ ํ•˜๋‚˜ ํ•˜๋‚˜ ๋ถ„์„ํ•  ํ•„์š”๋Š” ์—†์œผ๋ฉฐ, ์ด๋ฏธ์ง€์˜ ํ€„๋ฆฌํ‹ฐ๊ฐ€ ๋‚ฎ๋”๋ผ๋„ ํฐ ์˜์—ญ์— ๊ฑธ์นœ ์ƒ‰์ƒ ์ฐจ์ด๋ฅผ ๋ถ„์„ํ•˜๋Š”๋ฐ๋Š” ์ถฉ๋ถ„ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋”ฐ๋ผ์„œ ์ดˆ๋‹น 13๋งค๋กœ ์ถ”์ถœํ•  ํ”„๋ ˆ์ž„์˜ ๊ฐœ์ˆ˜๋ฅผ ์ ˆ๋ฐ˜๊ฐ€๋Ÿ‰์œผ๋กœ ์ค„์ด๊ณ , ํฌ๊ธฐ ๋˜ํ•œ 100 x 56์œผ๋กœ ๋Œ€ํญ ์ถ•์†Œํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ด๋ฏธ์ง€ ํ˜•์‹ ๋˜ํ•œ PNG-24๋ณด๋‹ค ๋น„ํŠธ์ˆ˜๊ฐ€ ์ ์–ด ํ•œ๊ฒฐ ๊ฐ€๋ฒผ์šด PNG-8๋ฅผ ์ฑ„ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์œ„์˜ ๋‘ ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•ด๋ณด๊ณ  ๋ถ„์„์šฉ ํ”„๋ ˆ์ž„ ํด๋”์˜ ์ด ์šฉ๋Ÿ‰์„ ๋น„๊ตํ•ด๋ณด๋‹ˆ, 15์ดˆ ์˜์ƒ ๊ธฐ์ค€์œผ๋กœ 823KB์˜ ํด๋”๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ 141.1MB์™€ ๋น„๊ตํ•˜์—ฌ ๋“œ๋ผ๋งˆํ‹ฑํ•˜๊ฒŒ ๊ฐ€๋ฒผ์›Œ์ง์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ์ ์œผ๋กœ ํผํฌ๋จผ์Šค๋„ ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


2-3. ๋ชจ์…˜ ๋ถ„์„๋ถ€ํ„ฐ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜๊นŒ์ง€

FFmpeg์™€ Sharp๋ฅผ ์ด์šฉํ•œ ๋ชจ์…˜๋ถ„์„์˜ ๊ณผ์ •์„ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์œ„์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ƒ์„ธํžˆ ํ•˜๋‚˜ํ•˜๋‚˜ ์งš์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. ๋น„๋””์˜ค ์—…๋กœ๋“œ
    ์œ ์ €๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋น„๋””์˜ค๋ฅผ ์—…๋กœ๋“œํ•˜๋ฉด multer๋ฅผ ํ†ตํ•˜์—ฌ ๋ฐฑ์—”๋“œ๋กœ ์ „์†ก๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  2. ๋ถ„์„์šฉ ์ €ํ€„๋ฆฌํ‹ฐ ํ”„๋ ˆ์ž„ ์ถ”์ถœ
    ๋จผ์ € FFmpeg๋ฅผ ์ด์šฉํ•˜์—ฌ ํ”„๋ ˆ์ž„๊ฐ„์˜ ๋น„๊ต๋ฅผ ์œ„ํ•ด์„œ ์˜์ƒ์„ ์ด๋ฃจ๋Š” ํ”„๋ ˆ์ž„๋“ค์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
    ์˜ค์ง ๋ถ„์„์šฉ์œผ๋กœ ์“ฐ์ผ ์˜ˆ์ •์ด๋ฏ€๋กœ ์ €ํ€„๋ฆฌํ‹ฐ์˜ ํ”„๋ ˆ์ž„๋“ค์„ ์ดˆ๋‹น 13๋งค๋งŒ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

  3. ๋ชจ์…˜ ํžˆํŠธ๋งต ์˜์ƒ ์ƒ์„ฑ
    Sharp์˜ composite ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋‘ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑํ•˜์—ฌ ๋ณ€ํ™”ํ•œ ๊ตฌ๊ฐ„๋งŒ์„ ๋„์ถœํ•ฉ๋‹ˆ๋‹ค.

  4. ๋ถ„์„ํ•  ์˜์—ญ ์ปจํŽŒ
    ์œ ์ €๋Š” ๋ฐ˜ํ™˜๋œ ๋ชจ์…˜ํžˆํŠธ๋งต ํ”„๋ฆฌ๋ทฐ ์˜์ƒ์„ ํ† ๋Œ€๋กœ ๋ชจ์…˜ ๋ถ„์„์„ ์š”์ฒญํ•  ์˜์—ญ๊ณผ ์˜ˆ๋ฏผ๋„๋ฅผ ์ปจํŽŒํ•ฉ๋‹ˆ๋‹ค.

  5. ๊ณ ํ€„๋ฆฌํ‹ฐ ํ”„๋ ˆ์ž„ ์ถ”์ถœ
    FFmpeg๋ฅผ ์ด์šฉํ•˜์—ฌ ์›๋ณธ์˜์ƒ์—์„œ ๊ณ ํ€„๋ฆฌํ‹ฐ์˜ ํ”„๋ ˆ์ž„์„ ์ดˆ๋‹น 25๋งค๋กœ ์ถ”์ถœํ•ด์ค๋‹ˆ๋‹ค.

  6. ์˜์—ญ ๋‚ด๋ถ€์—์„œ ๋ชจ์…˜ ๋ถ„์„, ์ตœ์ ํ™”
    ์ด๋ฏธ์ง€์˜ ํ”ฝ์…€์„ ์ˆœํšŒํ•˜๋ฉฐ ์Šค์ฝ”์–ด๊ฐ€ ๊ฐ•ํ•œ ์„ธ๋กœ์ค„์˜ ์œ„์น˜๋ฅผ ๋ฐฐ์—ด์— ๋‹ด์Šต๋‹ˆ๋‹ค.
    ๋ฐฐ์—ด์— ๋‹ด์„์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฐ€๋ฆฌ๋Š” ๊ธฐ์ค€์ ์ธ Threshold๋Š” ์‹คํ—˜์„ ํ†ตํ•ด ์–ป์€ ์ ์ ˆํ•œ ์ˆซ์ž๋กœ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉฐ ํ”ฝ์…€์ด ๋‹จ์ˆœ ๋…ธ์ด์ฆˆ์ธ์ง€ ๋ชจ์…˜์— ํ•ด๋‹นํ•˜๋Š”์ง€๋ฅผ ๊ฐ€๋ ค์ค๋‹ˆ๋‹ค.
    "๋ชจ์…˜๋ถ„์„ ๋ฐฐ์—ด"์˜ ์ค‘์•™์„ ๊ตฌํ•œ ํ›„, ํฌ๋กญ์˜ ๊ธฐ์ค€์ ์ด ๋˜๋Š” ์ขŒ์ธก ์ตœ์ƒ๋‹จ์˜ ์ขŒํ‘œ๊ฐ’์„ ๊ตฌํ•˜์—ฌ "์ขŒํ‘œ ๋ฐฐ์—ด"์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
    ์•ˆ์ •์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐ์—ด๋‚ด๋ถ€์˜ ์ขŒํ‘œ๊ฐ’์„ ์ตœ์ ํ™”ํ•ด์ค๋‹ˆ๋‹ค.

  7. ํ”„๋ ˆ์ž„์„ ํฌ๋กญํ•˜์—ฌ ์„ธ๋กœ์˜์ƒ ์ƒ์„ฑ
    ์ขŒํ‘œ๋ฐฐ์—ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ Sharp๋ฅผ ์ด์šฉํ•ด ํ”„๋ ˆ์ž„๋“ค์„ ํฌ๋กญํ•ด์ค๋‹ˆ๋‹ค.
    ํฌ๋กญ์ด ์™„๋ฃŒ๋œ ํ”„๋ ˆ์ž„๋“ค์„ FFmpeg๋ฅผ ์ด์šฉํ•ด ๋น„๋””์˜ค๋กœ ํ•ฉ์ณ์ค๋‹ˆ๋‹ค.
    ์ด๋•Œ์— ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด๋†“์•˜๋˜ ์˜ค๋””์˜ค ํŒŒ์ผ๊ณผ ์˜์ƒ์„ ํ•จ๊ป˜ ๋จน์‹ฑํ•ด์ค๋‹ˆ๋‹ค.

  8. ๊พธ๋ฏธ๊ธฐ ์ปจํŽŒ
    ์œ ์ €๋Š” ๋ชจ์…˜๋ถ„์„ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธํ•˜๊ณ  ์˜์ƒ์„ ๊พธ๋ฐ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊พธ๋ฏธ๊ธฐ๋ฅผ ํ•˜์ง€์•Š๊ณ  ๊ทธ๋Œ€๋กœ ์ปจํŽŒํ•˜๋ฉด 10๋ฒˆ์งธ ๋‹จ๊ณ„๋กœ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

  9. ๊พธ๋ฏธ๊ธฐ ๋ฐ˜์˜ํ•˜์—ฌ ์ตœ์ข…์˜์ƒ ์ƒ์„ฑ
    FFmpeg์˜ ํ•„ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์œ ์ €๊ฐ€ ์ œ์ถœํ•œ ๋””์ž์ธ๋Œ€๋กœ ์˜์ƒ์„ ํŽธ์ง‘ํ•˜๊ณ  ์ตœ์ข…๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  10. ์ตœ์ข…์˜์ƒ ๋ฐ˜ํ™˜
    S3์— ์—…๋กœ๋“œ๋œ ๊ฒฐ๊ณผ๋ฌผ์˜ url์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.


3. ๊ฒฐ๊ณผ์˜์ƒ์„ ์ตœ์ ํ™”ํ•˜์—ฌ ์œ ์ €๋งŒ์กฑ๋„ ๋†’์ด๊ธฐ

๋ชจ์…˜๋ถ„์„์˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๋‹ด๊ธด ์ขŒํ‘œ๋ฐฐ์—ด์€ ๋‹จ์ˆœํžˆ ๋ชจ์…˜ ์Šค์ฝ”์–ด๊ฐ€ ๋†’์•˜๋˜ ๋ถ€์œ„์˜ ์ค‘์•™์„ ์ถ”์ ํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด๋ผ, ์ขŒํ‘œ๋“ค์ด ์„œ๋กœ๊ฐ„์— ์—ฐ๊ฒฐ๋˜์–ด์žˆ์ง€ ์•Š๊ฑฐ๋‚˜ ๋Š์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Œ€๋กœ ์ตœ์ ํ™” ์—†์ด ํ”„๋ ˆ์ž„์„ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, ์‚ฌ๋žŒ์ด ๊ด€๋žŒํ•˜๊ธฐ์—๋Š” ๋งค์šฐ ๋ถˆํŽธํ•˜๊ณ  ์‚ฐ๋งŒํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ฐ˜ํ™˜๋˜์–ด ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

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

์ด๋ฅผ ์œ„ํ•ด์„œ ๊ณณ๊ณณ์—์„œ ์„ ํ˜•๋ณด๊ฐ„๋ฒ• โ€œlinear interpolationโ€์ด๋ผ ์ผ์ปซ์–ด์ง€๋Š” ๋‘ ์ง€์  ์‚ฌ์ด์˜ ์ค‘๊ฐ„ ๊ฐ’์„ ๊ตฌํ•˜๋Š” ๊ฐœ๋…์ด ํ™œ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

3-1. ๋ชจ์…˜์ด ์—†๋Š” ๊ตฌ๊ฐ„(0)์˜ ์ฒ˜๋ฆฌ

๋Œ„์Šค ์ปค๋ฒ„ ์˜์ƒ, ํ˜น์€ ๊ผฌ๋ฆฌ๋ฅผ ๊ณ„์† ํ”๋“œ๋Š” ๊ฐ•์•„์ง€ ์˜์ƒ์ด ์•„๋‹Œ ์ด์ƒ, ๋ชจ์…˜์ด ์žฆ์•„๋“œ๋Š” ๊ตฌ๊ฐ„์€ ์–ด๋–ค ์˜์ƒ์ด๋“  ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๋Ÿฌ๊ตฐ๋ฐ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐฐ์—ด ์•ˆ์— โ€œ๋ชจ์…˜์—†์Œโ€ ์ฆ‰, 0์ด ์„ž์—ฌ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋ชจ์…˜์ด ๋๋‚œ ๊ตฌ๊ฐ„๊ณผ ๋‹ค์‹œ ์‹œ์ž‘๋˜๋Š” ๊ตฌ๊ฐ„ ์‚ฌ์ด์˜ ๋งค๋„๋Ÿฝ๊ฒŒ ์ด์–ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ˆœํ™˜ ์ค‘ ๋ชจ์…˜์ด ๋๋‚˜์„œ 0์ด ๋ฐœ๊ฒฌ๋˜๊ฒŒ ๋˜๋ฉด ๋ชจ์…˜์ด ๋‹ค์‹œ ์‹œ์ž‘๋˜๊ธฐ ์ „๊นŒ์ง€์˜ gap์„ ์„ธ๊ณ , increment๋ฅผ (๋‹ค์Œ ๊ฐ’ - ์ด์ „ ๊ฐ’ / gap) ๋”ํ•˜์—ฌ ์กฐ๊ธˆ์”ฉ ์ƒ์Šนํ•˜๋Š” ๊ฐ’๋“ค์„ ํ•˜๋‚˜ ํ•˜๋‚˜ pushํ•ด ์ค๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ, ์—ฐ์†์ ์œผ๋กœ 0์ด ๋“ฑ์žฅํ•˜๋Š” ๊ตฌ๊ฐ„์ด ์œ ํšจํ•œ ๊ฐ’๋“ค๋กœ ์ฑ„์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

3-2. ๋ถˆ๊ทœ์น™์ ์œผ๋กœ ํŠ€๋Š” ์ขŒํ‘œ๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ๊ธฐ

  • ์—…๋กœ๋“œ๋˜๋Š” ์˜์ƒ์—๋Š” ๋…ธ์ด์ฆˆ๊ฐ€ ์žˆ๊ฑฐ๋‚˜, ํ™”๋ฉด์˜ ๊ฐ€์žฅ์ž๋ฆฌ์— ๋“ฑ์žฅํ•˜๋Š” ํ–‰์ธ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [โ€ฆ , 10, 5, 10 , โ€ฆ], [โ€ฆ , 35, 10, 36 , โ€ฆ] ๊ณผ ๊ฐ™์ด ๋‘ ์ˆซ์ž๋“ค์˜ ์‚ฌ์ด์— ๊ธ‰๊ฒฉํ•˜๊ฒŒ ์ฐจ์ด๊ฐ€ ๋‚˜๋Š” ์ˆ˜๊ฐ€ ๋“ค์–ด์žˆ์„ ๊ฒฝ์šฐ, ๊ฐ€์šด๋ฐ ์ˆซ์ž๋ฅผ ์ค‘๊ฐ„๊ฐ’์œผ๋กœ ๋ฎ์–ด์”Œ์šฐ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ตฌ์ถ•ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ธ‰๊ฒฉํžˆ ์นด๋ฉ”๋ผ๊ฐ€ ์—‰๋šฑํ•œ ๊ณณ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๋ถ€์ ์ ˆํ•œ ๋ถ€๋ถ„์„ ๋งŽ์ด ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

3-3. ์ขŒํ‘œ ๋ฐฐ์—ด์„ ๋ถ€๋“œ๋Ÿฌ์šด ์„ ํ˜•์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ

  • ์œ ์ €๊ฐ€ ์„ ํƒํ•œ n์„ ๋ถ„๊ธฐ์  ์‚ผ์•„, ๋ถ„๊ธฐ์ ๋“ค ์‚ฌ์ด๋ฅผ ์„ ํ˜•์œผ๋กœ ๋ˆŒ๋Ÿฌ์ฃผ๋Š” ๋กœ์ง์ž…๋‹ˆ๋‹ค.
    ๋ฏผ๊ฐ๋„์˜ ๊ฐ•, ์•ฝ์„ ์กฐ์ ˆํ•˜๋Š” ์Šฌ๋ผ์ด๋” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์œ ์ €๊ฐ€ ๊ฐ๋„๋ฅผ ์„ค์ •ํ•˜๋ฉด ์–ด๋Š์ •๋„ ๋น ๋ฅด๊ธฐ์™€ ๋ฏผ๊ฐ๋„๋กœ ์นด๋ฉ”๋ผ๊ฐ€ ๋ชจ์…˜์„ ์ถ”์ ํ• ์ง€๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. n์˜ ์ˆซ์ž๊ฐ€ ๋‚ฎ์œผ๋ฉด ๋ถ„๊ธฐ์  ์‚ฌ์ด๊ฐ€ ์ข์•„์ ธ ์ถ”์ ์ด ์ •ํ™•ํ•˜์ง€๋งŒ ๋‹ค์†Œ ์‚ฐ๋งŒํ•˜๋ฉฐ, n์˜ ์ˆซ์ž๊ฐ€ ๋†’์œผ๋ฉด ๋ถ„๊ธฐ์  ์‚ฌ์ด๊ฐ€ ๋ฉ€์–ด์ ธ ๋ถ€๋“œ๋Ÿฝ์ง€๋งŒ ๋œ ์˜ˆ๋ฏผํ•œ ์ถ”์ ์ •๋„๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • ์Šฌ๋ผ์ด๋”๋Š” sensitive, medium, modest์˜ ์„ธ๊ฐ€์ง€ ์„ ํƒ์ง€๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์‚ฌ์ „์— ์‹คํ—˜์„ ํ†ตํ•ด ์ƒ์‹์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ๋„์ถœํ•˜๋Š” ์ˆซ์ž๋“ค๋กœ ํ• ๋‹นํ•˜์˜€์Šต๋‹ˆ๋‹ค.
    ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฐฐ์—ด ๋‚ด๋ถ€์˜ ์ˆซ์ž๊ฐ€ ๋ถ€๋“œ๋Ÿฌ์šด path๋ฅผ ์ด๋ฃจ๊ฒŒ ๋˜์–ด ๋งˆ์น˜ ์นด๋ฉ”๋ผ๊ฐ€ ํ”ผ์‚ฌ์ฒด๋ฅผ ์ซ“์•„ ์ด๋™ํ•˜๋Š” ๋“ฏํ•œ ์•ˆ์ •์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

3-4. ์œ ์ €์˜ ์ฃผ๊ด€์„ ๋ฐ˜์˜ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ์ถ”๊ฐ€

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

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

Re-Direction์€ ์–ผ๊ตด์ด๋‚˜ ์‚ฌ๋ฌผ์ธ์‹๊ณผ๊ฐ™์€ AI๊ธฐ์ˆ ์„ ์“ฐ์ง€ ์•Š๋Š” ํ”„๋กœ์ ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ”ผ์‚ฌ์ฒด๊ฐ€ ๋งŽ๊ฑฐ๋‚˜ ๋ฐฐ๊ฒฝ์ด ์‹ฌํ•˜๊ฒŒ ์š”๋™์น˜๋Š” ๊ฒฝ์šฐ ๋ชจ์…˜๋ถ„์„์— ํ•œ๊ณ„๋ฅผ ๋ณด์ด๋Š” ์ผ€์ด์Šค๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์œ„์— ๋‚˜์—ดํ•œ ๋งŽ์€ ์ตœ์ ํ™”์™€ ๊ฐœ์„ ์ฑ…์„ ํ†ตํ•ด์„œ ๋ณด๋‹ค ์•ˆ์ •์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ด๋ฅผ ๋ฐ›์•„๋ณธ ์‚ฌ์šฉ์ž์˜ ๋งŒ์กฑ๋„๋ฅผ ํฌ๊ฒŒ ๋†’์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

4. ๊ธ€๊ท€์™€ ์Šคํ‹ฐ์ปค๋ฅผ ์–ด๋–ป๊ฒŒ ์˜์ƒ์— ์‚ฝ์ž…ํ• ๊นŒ?

4-1. ๊ฐ„ํŽธํ•œ ๊พธ๋ฏธ๊ธฐ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณตํ•˜๊ธฐ

๊ฐ์ข… ์ด๋ฒคํŠธ์™€ ์†์„ฑ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•  ๊ธฐํšŒ๋ฅผ ๊ฐ€์ ธ๋ณด๊ธฐ ์œ„ํ•˜์—ฌ ๊พธ๋ฏธ๊ธฐ ๊ธฐ๋Šฅ์˜ ํ•ต์‹ฌ์ธ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—†์ด ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

1. ๊ตฌํ˜„์„ ์œ„ํ•œ ์žฌ๋ฃŒ

์ œ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž ๋กœ์ง์— ์“ฐ์ธ ์žฌ๋ฃŒ๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. mouseDown: ๋งˆ์šฐ์Šค ์™ผ์ชฝ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋Š” ์ด๋ฒคํŠธ: ํƒ€๊ฒŸ์˜ ์ขŒํ‘œ ๊ฐฑ์‹ ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  2. mouseMove: ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ด๋Š” ์ด๋ฒคํŠธ: ํƒ€๊ฒŸ์˜ ์ขŒํ‘œ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.
  3. mouseUp: ๋งˆ์šฐ์Šค ์™ผ์ชฝ๋ฒ„ํŠผ์—์„œ ์†๊ฐ€๋ฝ์„ ๋–ผ๋Š” ์ด๋ฒคํŠธ: ํƒ€๊ฒŸ์˜ ์ขŒํ‘œ ๊ฐฑ์‹ ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
  4. useRef: ์Šคํฌ๋ฆฐ ์ƒ์˜ ๋น„๋””์˜ค์ขŒํ‘œ๋ฅผ ํŒŒ์•…ํ•ด์ฃผ์–ด ์™ผ์ชฝ์ƒ๋‹จ ๊ผญ์ง€์ ์ด ์œˆ๋„์šฐ ๋ฆฌ์‚ฌ์ด์ฆˆ์— ์ƒ๊ด€์—†์ด ํ•ญ์ƒ 0, 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.
    ์ด๋กœ์จ ๋“œ๋ž˜๊ทธ์ œํ•œ๊ตฌ์—ญ์ด ์–ด๋– ํ•œ ๊ฒฝ์šฐ๋ผ๋„ ๋น„๋””์˜ค์™€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  5. ClientX, ClientY: ํƒ€๊ฒŸ์˜ ์œ„์น˜๊ฐ€ ๋งˆ์šฐ์Šค์ปค์„œ ์œ„์น˜๋ฅผ ๋”ฐ๋ผ ๊ฐฑ์‹ ๋  ์ˆ˜ ์žˆ๋„๋ก ์Šคํฌ๋ฆฐ์ƒ ์ปค์„œ์˜ ์‹ค์‹œ๊ฐ„ ์œ„์น˜๋ฅผ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค.

2. DnD ์˜์—ญ ์ œํ•œ

์—ฌ๊ธฐ์— ์ œํ•œ๋œ ์˜์—ญ์„ ํƒ€๊ฒŸ์ด ๋ฒ—์–ด๋‚˜์ง€ ๋ชปํ•˜๋„๋ก ๊ฐ ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ์–ผ๋ฆฌ๋ฆฌํ„ด ๋กœ์ง์„ ๋ถ™์ด์ž ์•ˆ์ •์ ์ธ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž ๊ธฐ๋Šฅ์ด ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒํ•˜์ขŒ์šฐ๋ณ€๊ณผ ์‚ฌ๋ฐฉ์˜ ๊ผญ์ง€์ ์„ ๋ฒ—์–ด๋‚˜๋Š” ์กฐ๊ฑด๋“ค์˜ ๊ฒฝ์šฐ ๊ฐ์ข… ์ˆซ์ž์™€ ๋ถ€๋“ฑํ˜ธ๋“ค๋กœ ํ‘œํ˜„๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์„์˜ ๋„์›€ ์—†์ด๋Š” ๊ฐ€๋…์„ฑ์ด ๋งค์šฐ ๋–จ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์œ„ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ ๊ฐ ์˜ˆ์™ธ์ƒํ™ฉ๋“ค์„ ๋ณ€์ˆ˜ํ™”ํ•˜๊ณ  ๊ฐ์ข… ๋งค์ง๋„˜๋ฒ„๋“ค์„ ๋ชจ๋‘ ์ƒ์ˆ˜์ฒ˜๋ฆฌํ•˜๋Š” ๋ฆฌํŒฉํ„ฐ๋ง์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

3. ํƒ€๊ฒŸ์˜ ์Šค์ผ€์ผ์— ๋ฐ˜์‘ํ•˜๋„๋ก ๋ฐœ์ „์‹œํ‚ค๊ธฐ

๊พธ๋ฏธ๊ธฐ ์š”์†Œ์˜ ๊ฒฝ์šฐ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ข…๋ฅ˜๋ณ„๋กœ ์ œ๊ฐ๊ฐ์ด๋ฉฐ ๊ธ€๊ท€ input ๋˜ํ•œ ๋‚ด์šฉ์— ๋”ฐ๋ผ ํฌ๊ธฐ๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํƒ€๊ฒŸ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๊ฑฐ๋‚˜ ์ž‘์•„์ง€๋”๋ผ๋„ ๋ฐ˜์‘ํ˜•์œผ๋กœ ์˜์—ญ์ œํ•œ์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ์‹œ์ผœ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ useRef๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๋‹น ์š”์†Œ์˜ DOM๋…ธ๋“œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด๋“ค์—ฌ ํ™œ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ์Šคํ‹ฐ์ปค ์ปดํฌ๋„ŒํŠธ ์˜ˆ์‹œ
  const stickerRef = useRef<HTMLImageElement>(null);

  function setElementScale() {
    if (stickerRef.current) {
      setTargetElementScale(stickerRef.current.width, stickerRef.current.height);
    }
  }

  // ...

  <img
    // ๊ฐ์ข… ์–ดํŠธ๋ฆฌ๋ทฐํŠธ
    ref={stickerRef}
  />

์ด์–ด์„œ ์œ ์ €๊ฐ€ ์š”์†Œ๋ฅผ ๋“œ๋ž˜๊ทธํ•˜๊ธฐ ์œ„ํ•ด ํด๋ฆญํ–ˆ์„ ์‹œ setElementScale ํ•จ์ˆ˜๊ฐ€ ์ž‘๋™๋˜์–ด, targertElementScale์— ํƒ€๊ฒŸ ์Šคํ‹ฐ์ปค์˜ ํฌ๊ธฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธฐ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๋Š” ์ด์–ด์„œ ๋“œ๋ž˜๊ทธ์•ค๋“œ๋ž์„ ๋‹ด๋‹นํ•˜๋Š” ํ•จ์ˆ˜๋‚ด๋ถ€์—์„œ ๋“œ๋ž˜๊ทธ ์˜์—ญ์ œํ•œ ํ•ด์ฃผ๋Š”๋ฐ ์‚ฌ์šฉ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

4-2. ์š”์ฒญ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฌผ ๋ฐ˜ํ™˜

ํด๋ผ์ด์–ธํŠธ๋‹จ์—์„œ ์˜์ƒ๊พธ๋ฏธ๊ธฐ์™€ ๊ด€๋ จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ชจ๋‘ ์™„์„ฑ๋˜์ž, ๋‹ค์Œ์œผ๋กœ ์œ ์ €๊ฐ€ ์ปจํŽŒํ•œ ๋””์ž์ธ์„ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์˜์ƒ์— ์‚ฝ์ž…ํ•  ๊ฒƒ์ธ๊ฐ€๋ผ๋Š” ๋ฌธ์ œ์— ๋ด‰์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋˜์–ด ์˜ค๋Š” ๊ฒฐ๊ณผ๋ฌผ์ด ์œ ์ €๊ฐ€ ์„ค์ •ํ•˜๊ณ  ์ œ์ถœํ•œ ๋ชจ์Šต๊ณผ ์˜ค์ฐจ ์—†์ด ์ •ํ™•ํ•˜๊ฒŒ ์ผ์น˜ํ•ด์•ผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ €, ๋‹ค์–‘ํ•œ ์กฐ์‚ฌ์™€ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ํ†ตํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ffmpeg์˜ ํ•„ํ„ฐ ์ปค๋งจ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ธ€์ž๋‚˜ ์ด๋ฏธ์ง€๋ฅผ ์˜์ƒ์˜ ์›ํ•˜๋Š” ์œ„์น˜์— ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ffmpeg์˜ โ€œdrawtextโ€ ์ปค๋งจ๋“œ์—๋Š” ๋ฐฐ๊ฒฝ์ƒ‰, ๊ฐœํ–‰, ๊ฐ€์šด๋ฐ ์ •๋ ฌ๋“ฑ์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ธ€์”จ์˜ ๋ฐฐ๊ฒฝ์ƒ‰์˜ ๊ฒฝ์šฐ, ๊ทธ ์—ญํ• ์„ ๋Œ€์‹  ํ•ด์ค„ โ€œ์‚ฌ๊ฐํ˜•โ€์„ drawbox๋ฅผ ์ด์šฉํ•ด ๋ณ„๋„๋กœ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • ์˜์ƒ์— ์‚ฝ์ž…ํ•  ํฐํŠธ์™€ ์ด๋ฏธ์ง€ ํŒŒ์ผ์€ local path์—์„œ ๋ถˆ๋Ÿฌ์™€์•ผํ•˜๋ฉฐ, S3 url์„ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ด๋ฏธ์ง€ ์‚ฝ์ž…๊ธฐ๋Šฅ์—์„œ .svgํ™•์žฅ์ž๋Š” ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์œ„๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ FFmpeg์˜ ์ปค๋งจ๋“œ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ„์ถ”๋ ค ์„œ๋ฒ„์— ์ „์†กํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, .ttfํŒŒ์ผ๊ณผ .pngํŒŒ์ผ์„ ๋ชจ๋‘ S3์— ์—…๋กœ๋“œํ•˜๊ณ , edit ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ FFmpeg์˜ ์ž‘์—…์„ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ๋‚ด๋ ค๋ฐ›๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—…์„ ์œ„ํ•œ ์žฌ๋ฃŒ๋“ค์˜ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜๋ฉด, ๊ธ€๊ท€์™€ ์Šคํ‹ฐ์ปค์˜ ์œ ๋ฌด์— ๋”ฐ๋ผ FFmpeg ์ปค๋งจ๋“œ์— Argument๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

"-i",
path.join(SAVING_DIR_RESULT, "result_video.mp4"),
// 0๋ฒˆ์งธ ๋ฏธ๋””์–ด: ๋น„๋””์˜ค
"-i",
downloadedFiles.stickerPath,
// 1๋ฒˆ์งธ ๋ฏธ๋””์–ด: ์Šคํ‹ฐ์ปค
"-filter_complex",
// ํ•„ํ„ฐ์ ์šฉ ์ปค๋งจ๋“œ. ์ดํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ.
`[1:v]scale=150:-1[scaled_sticker];[0:v][scaled_sticker]overlay=x=${stickerX}:y=${stickerY},drawbox=x=${fontX}:y=${fontY - 7}:w=${fontWidth}:h=35:color=${fontBg}:t=fill,drawtext=text=${fontContent}:x=${fontX}+${fontWidth}/2-text_w/2:y=${fontY}:fontsize=30:fontcolor=${fontColor}:fontfile=${downloadedFiles.typefacePath}`,
// [1:v]... 1๋ฒˆ์งธ ์ธ๋ฑ์Šค ์š”์†Œ์ธ ์Šคํ‹ฐ์ปค์˜ ์Šค์ผ€์ผ์„ ์กฐ์ ˆ
// [0:v]... 0๋ฒˆ์งธ ์ธ๋ฑ์Šค ์š”์†Œ์ธ ๋น„๋””์˜ค ์œ„์— ์Šคํ‹ฐ์ปค๋ฅผ ์˜ค๋ฒ„๋ ˆ์ด, drawbox= ๊ธ€๊ท€ ๋’ค์ชฝ์— ์œ„์น˜ํ•  ๋ฐ•์Šค๋ฅผ ์ž‘์„ฑ, drawtext= ๊ธ€๊ท€๋ฅผ ์ž‘์„ฑ.
"-y",
// ๋ฎ์–ด์“ฐ๊ธฐ ํ—ˆ์šฉ
path.join(SAVING_DIR_EDITED_RESULT, "edited_video.mp4"),
// ์ €์žฅํ•  ๊ฒฝ๋กœ๋ฅผ ์ง€์ • & ๊ฒฐ๊ณผํŒŒ์ผ ์ด๋ฆ„์„ค์ •

๐Ÿ”บ ์Šคํ‹ฐ์ปค์™€ ๊ธ€๊ท€๋ฅผ ๋™์‹œ ์ ์šฉํ•  ๊ฒฝ์šฐ ์•„๊ทœ๋จผํŠธ ์˜ˆ์‹œ

  • HTML์˜ inputํƒœ๊ทธ์˜ ์†์„ฑ์—์„œ ์ง€์›ํ•˜๋Š” โ€œtransparentโ€์˜ ๊ฒฝ์šฐ, FFmpeg๊ฐ€ ์•Œ์•„๋“ฃ๋Š” ์†์„ฑ๋ช…์€ ์•„๋‹ˆ๋ฏ€๋กœ, ๋ถ„๊ธฐ๋ฅผ ์„ค์ •ํ•ด์ฃผ์–ด โ€œtransparentโ€๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ์—๋งŒ drawbox๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋กœ์ง์„ ์ปค๋ฉ˜๋“œ ๋ฐฐ์—ด์— pushํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋˜ํ•œ ๊ฐ€์šด๋ฐ ์ •๋ ฌ์˜ ๊ฐœ๋…๋„ FFmpeg๋Š” ์•Œ์ง€ ๋ชปํ•˜๋ฏ€๋กœ FFmpeg ์ปค๋งจ๋“œ ๋ฌธ๋ฒ•์„ ์ด์šฉํ•˜์—ฌ ๊ณ„์‚ฐ์‹์„ ์ž‘์„ฑํ•ด์•ผ๋งŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

HTML๊ด€๋ จ ์†์„ฑ๊ฐ’๋“ค์„ FFmpeg๊ฐ€ ์ง€์›ํ•˜๋Š” ํ˜•์‹์— ๊ฑธ๋งž๊ฒŒ ๋ฐ”๊ฟ”์ฃผ๋Š” ์ž‘์—…์€ ๋งˆ์น˜ ์„œ๋กœ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ์“ฐ์ธ ๊ธ€์˜ ๋ฒˆ์—ญ์ž‘์—…๊ณผ ํก์‚ฌํ•˜๋‹ค๊ณ  ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค. ๊ธด ์‹œ๊ฐ„๋™์•ˆ์˜ ์‹œํ–‰์ฐฉ์˜ค ๋์— ์˜ฌ๋ฐ”๋ฅธ ์ปค๋งจ๋“œ๋ฌธ๋ฒ•์„ ์ ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๋‹จ์—์„œ ์œ ์ €๊ฐ€ ์„ค์ •ํ•œ ๋ชจ์Šต์ด ๋˜‘๊ฐ™์ด ์˜์ƒ์— ์‚ฝ์ž…๋œ ๊ฒƒ์„ ๋ณด์•˜์„ ๋•Œ๋Š” ํฌ๋‚˜ํฐ ๋ณด๋žŒ์„ ๋Š๋‚„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


5. ๊ตฌ์กฐ๋ฅผ ์ตœ์ ํ™”ํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ

์ดˆ๊ธฐ์—๋Š” ๊พธ๋ฏธ๊ธฐ ์š”์†Œ์˜ ํ•ญ๋ชฉ์ด ํฐํŠธ์™€ ์Šคํ‹ฐ์ปค, ๋‹จ ๋‘๊ฐ€์ง€์ž„์— ๋”ฐ๋ผ ๊ฐ์ข… state ๋ฐ ๋กœ์ง๋“ค์˜ ์งœ์ž„์ƒˆ์™€ ๋‘ ์š”์†Œ ์‚ฌ์ด์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋งค์šฐ ๋†’์€ ์ƒํƒœ์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ GIF๋‚˜ ๊ทธ๋ฆฌ๊ธฐ, ํ•„ํ„ฐ ๋“ฑ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด ๊พธ๋ฏธ๊ธฐ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋  ๋•Œ, ์ˆ˜๋งŽ์€ ๊ณณ์—์„œ ์ˆ˜์ •์ด ์ผ์–ด๋‚˜์•ผ ํ•œ๋‹ค๋ฉด ๊ฐœ๋ฐฉํ์‡„์›์น™์— ์–ด๊ธ‹๋‚˜๊ณ  ์ค‘๋ณต์ฝ”๋“œ๊ฐ€ ์ฆ๊ฐ€ํ•  ๊ฒƒ์ด ์˜ˆ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ™•์žฅ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋” ๋‚˜์€ ์„ค๊ณ„๋Š” ์—†์„๊นŒ ๊ณ ๋ฏผํ•œ ๊ฒฐ๊ณผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์š”์†Œ ๋ณ„ state๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ตฌ์กฐ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋ง

์ฒซ๋ฒˆ์งธ๋กœ, ๊ฐ ์š”์†Œ ๋ณ„๋กœ ์…‹์—…ํ•ด์ฃผ์—ˆ๋˜ ๋“œ๋ž˜๊ทธ ์œ ๋ฌด, ์ขŒํ‘œ ๋“ฑ์˜ ์Šคํ…Œ์ดํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๊ณต์šฉ์Šคํ…Œ์ดํŠธ๊ฐ€ ์š”์†Œ์˜ ์ข…๋ฅ˜๋‚˜ ๊ฐœ์ˆ˜์™€ ๊ด€๊ณ„์—†์ด ๋™์ž‘ํ•˜๋„๋ก ๊ตฌ์กฐ๋ฅผ ๋ฆฌํŒฉํ„ฐ๋งํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๋ณ€๊ฒฝ ์ „
ใ‚นใ‚ฏใƒชใƒผใƒณใ‚ทใƒงใƒƒใƒˆ 2023-12-07 22 21 53
๐Ÿ”บ ๊ธฐ์กด ๊ตฌ์กฐ๋ฅผ ๋„์‹์œผ๋กœ ํ‘œํ˜„. ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ์š”์†Œ์˜ ๊ฐœ์ˆ˜๋ณ„์— ๋น„๋ก€ํ•˜์—ฌ ๋ฐœ์ƒ.
  • ๋ณ€๊ฒฝ ํ›„
ใ‚นใ‚ฏใƒชใƒผใƒณใ‚ทใƒงใƒƒใƒˆ 2023-12-07 22 22 11

์ด๋กœ์จ ๊ฐ ์š”์†Œ์˜ isDragging์ด true/false๋กœ ํ† ๊ธ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํƒ€๊ฒŸ๋ช…์ด isDragging์— ์ง์ ‘ ๋‹ด๊ธฐ๋„๋ก ํ•ด, ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜์™€ ์ƒ๊ด€์—†์ด ํ•œ ์Œ์˜ state์™€ ์„ธํ„ฐ๋งŒ์œผ๋กœ DnD๊ฐ€ ์ž‘๋™ํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋น„์Šทํ•œ ๊ด€์‹ฌ์‚ฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๊ณณ์— ๋ชจ์œผ๊ธฐ

๋‘๋ฒˆ์งธ๋กœ, ๊ฐ ์š”์†Œ์— ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฌ๋Ÿฌ state๋“ค์— ํฉ์–ด์ ธ์žˆ๊ธฐ์— ํ•œ ๊ฐ์ฒด์— ๊น”๋”ํ•˜๊ฒŒ ๋ชจ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์œ ์ €๊ฐ€ ์–ด๋–ค ์š”์†Œ๋ฅผ ์„ ํƒํ•˜๋ฉด ๊ด€๋ จ ๊ฐ์ฒด๊ฐ€ selectedDecos๊ฐ์ฒด์— ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ / ์ œ๊ฑฐ๋˜๋„๋ก ๋ฆฌํŒฉํ„ฐ๋งํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ๋ณ€๊ฒฝ ์ „
ใ‚นใ‚ฏใƒชใƒผใƒณใ‚ทใƒงใƒƒใƒˆ 2023-12-07 22 22 20
๐Ÿ”บ ๊ธฐ์กด ๊ตฌ์กฐ๋ฅผ ๋„์‹์œผ๋กœ ํ‘œํ˜„. ์ƒˆ ๊พธ๋ฏธ๊ธฐ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜์•ผํ•  ๊ฒฝ์šฐ ๊ด€๋ จ state๋ฅผ ๋ณ„๋„๋กœ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜๊ณ  selectedDecos๋‚ด๋ถ€์— name๊ณผ url ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ ๋ณต์žกํ•œ ์ˆ˜์ •์ด ํ•„์š”ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๋ณ€๊ฒฝ ํ›„
ใ‚นใ‚ฏใƒชใƒผใƒณใ‚ทใƒงใƒƒใƒˆ 2023-12-07 22 22 28

์ƒˆ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋˜๋”๋ผ๋„ selectedDecos์˜ ๋‚ด๋ถ€๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ, ์„ ํƒ๋œ ์š”์†Œ์˜ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๊ฐ€ ๋‹ด๊ธด selectedDecos๊ฐ€ ๊ทธ๋Œ€๋กœ ๋ฐฑ์—”๋“œ ์š”์ฒญ์‹œ์— ํŽ˜์ด๋กœ๋“œ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด api๋ฆฌํ€˜์ŠคํŠธ ์‹œ ๋ณด๋‚ด๋Š” ๊ฐ์ฒด ๋‚ด๋ถ€๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ํ•ด์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์š”์†Œ ๋ณ„ ๋ถ„๊ธฐ ๋กœ์ง ์ œ๊ฑฐ

๋งˆ์ง€๋ง‰์œผ๋กœ, ๋””์ž์ธ ์š”์†Œ ๋ณ„ ์ขŒํ‘œ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ๊ฐ์˜ coord state๊ฐ€ ์•„๋‹Œ, selectedDecos์˜ ํ•˜์œ„๊ฐ์ฒด ๋‚ด๋ถ€์— ์ €์žฅ๋˜๋„๋ก ๋ณ€๊ฒฝ๋จ์— ๋”ฐ๋ผ handleMouseMove์—์„œ๋„ ๊ฐœ์„ ์ด ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

  • ๊ธฐ์กด ์ฝ”๋“œ
 function handleMouseMove(event) {
    switch (isDragging) {
      case "sticker":
        moveDecoElement(videoRect, event, setStickerCoord, targetElementScale);
        break;
      case "font":
        moveDecoElement(videoRect, event, setFontCoord, targetElementScale);
        break;
    }
  }

๊ธฐ์กด์—๋Š” ์š”์†Œ๋ณ„๋กœ ์ขŒํ‘œ state๊ฐ€ ๋”ฐ๋กœ ์กด์žฌํ–ˆ๊ธฐ์— setStickerCoord, setFontCoord๊ณผ ๊ฐ™์€ ์•Œ๋งž์€ setter๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด swtich๋ฌธ์„ ํ™œ์šฉํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ์„  ํ›„
  function handleMouseMove(event) {
    moveDecoElement(isDragging, videoRect, event, setCoord, targetElementScale);
  }

ํƒ€๊ฒŸ์ •๋ณด๊ฐ€ ๋‹ด๊ธด isDragging์„ ์ธ์ž๋กœ ๋ฐ›์•„, ํ•ด๋‹น ํƒ€๊ฒŸ์˜ ๊ฐ์ฒด ๋‚ด๋ถ€ ์ขŒํ‘œ๋ฅผ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒˆ ์š”์†Œ์˜ ์ถ”๊ฐ€์— ๋งž์ถ”์–ด switch๋ฌธ์— ์ผ€์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์—†์–ด์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

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

๐Ÿ—“ Schedule

  • ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 2023๋…„ 8์›” 7์ผ - 9์›” 5์ผ

  • 1์ฃผ์ฐจ

    • ์•„์ด๋””์–ด ์ˆ˜์ง‘, ์„ ์ •
    • ๊ธฐ์ˆ  ์Šคํƒ ๊ฒฐ์ • ๋ฐ ๊ฒ€์ฆ
    • ESLint, Prettier ์„ค์ •
    • KANBAN ์ž‘์„ฑ
  • 2์ฃผ์ฐจ

    • ๋ฆฌ์•กํŠธ ๋ฐ Node.js/Express ํ™˜๊ฒฝ ์„ธํŒ…
    • RESTful API ์ž‘์„ฑ
    • ๋ฉ”์ธํ™”๋ฉด ๊ตฌํ˜„
    • ๋กœ๋”ฉ ๊ตฌํ˜„
    • ์˜์—ญ์ง€์ • ๋กœ์ง ๊ตฌํ˜„
  • 3์ฃผ์ฐจ

    • ์˜์ƒ ๋ถ„์„๊ณผ์ • ๊ตฌํ˜„
    • ์˜์ƒ ํฌ๋กญ ๋ฐ ๋ฐ˜ํ™˜๊ณผ์ • ๊ตฌํ˜„
    • ์˜์ƒ ๊พธ๋ฏธ๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • 4์ฃผ์ฐจ

    • ๋ฐฐํฌ
    • ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ
    • README ์ž‘์„ฑ

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

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

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

์•ž์œผ๋กœ๋„ ๋งŽ์€ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ๊ฒฝํ—˜์„ ํ†ตํ•˜์—ฌ ์ง€์‹ํ˜•ํƒœ๋กœ ์•Œ๊ณ  ์žˆ๋˜ ๊ฒƒ์„ ์ง์ ‘ ์‹ค์ฒœํ•˜๊ณ  ์Šค์Šค๋กœ ์ฒดํ™”ํ•˜๋Š” ๊ธฐํšŒ๋ฅผ ๊ฐ€์ง€๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ž‘์€ ์‚ฐ์„ ๋„˜๋Š” ๊ฒฝํ—˜์„ ํ•œ ํ›„์— ๋” ํฐ ์‚ฐ์— ๋„์ „ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด, ํ”„๋กœ์ ํŠธ์˜ ์ˆ˜์ค€๊ณผ ๋”๋ถˆ์–ด ์ € ๋˜ํ•œ ํ•จ๊ป˜ ์„ฑ์žฅํ•ด ๋‚˜๊ฐ€๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.