An open API service indexing awesome lists of open source software.

https://github.com/gravidot/gravidot

Play and share your ideas with multiple gestures on gravidot. ๐Ÿ—ฏ๏ธ๐Ÿค๐ŸŽถ
https://github.com/gravidot/gravidot

jest multi-touch next playwright pwa react reactflow supabase tailwindcss typescript web zustand

Last synced: 4 months ago
JSON representation

Play and share your ideas with multiple gestures on gravidot. ๐Ÿ—ฏ๏ธ๐Ÿค๐ŸŽถ

Awesome Lists containing this project

README

          

# Gravidot

[![display mode](https://github.com/user-attachments/assets/da9f10b1-0f8a-41f2-91de-dbf5eace8394)](https://www.gravidot.com/)

### Play and share your ideas with multiple gestures!

#### ๋ฉ€ํ‹ฐํ„ฐ์น˜๋กœ ์•„์ด๋””์–ด๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์‹ค์‹œ๊ฐ„ ํ˜‘์—…์ด ๊ฐ€๋Šฅํ•œ ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ ์„œ๋น„์Šค


[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fgravidot%2Fgravidot&count_bg=%2338A1FF&title_bg=%23141414&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://github.com/gravidot/gravidot)
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fwww.gravidot.com&count_bg=%23FF641E&title_bg=%23000000&icon=livejournal.svg&icon_color=%23FFFFFF&title=www.gravidot.com&edge_flat=false)](https://www.gravidot.com)
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fmedium.com%2F%40howyoujini%2Fgravidot-0-1-0-%25EB%258B%25A4%25EA%25B0%2599%25EC%259D%25B4-%25EC%2595%2584%25EC%259D%25B4%25EB%2594%2594%25EC%2596%25B4%25EB%25A5%25BC-%25ED%2584%25B0%25EC%25B9%2598%25ED%2595%25B4%25EB%25B3%25BC%25EA%25B9%258C%25EC%259A%2594-%25EF%25B8%258F-f814499cd39c&count_bg=%2382F132&title_bg=%23000000&icon=medium.svg&icon_color=%23FFFFFF&title=Medium&edge_flat=false)](https://medium.com/@howyoujini/gravidot-0-1-0-%EB%8B%A4%EA%B0%99%EC%9D%B4-%EC%95%84%EC%9D%B4%EB%94%94%EC%96%B4%EB%A5%BC-%ED%84%B0%EC%B9%98%ED%95%B4%EB%B3%BC%EA%B9%8C%EC%9A%94-%EF%B8%8F-f814499cd39c)


## ๋ชฉ์ฐจ

- [์•„์ด๋””์–ด ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ](#%EC%95%84%EC%9D%B4%EB%94%94%EC%96%B4-%EB%93%B1%EC%9E%A5-%EB%B0%B0%EA%B2%BD)
- [๋ฉ€ํ‹ฐ ํ„ฐ์น˜๋ฅผ ํ™œ์šฉํ•ด ์•„์ด๋””์–ด ์Šค์ผ€์น˜๋ฅผ ์ง๊ด€์ ์ด๊ณ  ์ฆ๊ฒ๊ฒŒ ๋งŒ๋“ค์ž!](#%EB%A9%80%ED%8B%B0-%ED%84%B0%EC%B9%98%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%B4-%EC%95%84%EC%9D%B4%EB%94%94%EC%96%B4-%EC%8A%A4%EC%BC%80%EC%B9%98%EB%A5%BC-%EC%A7%81%EA%B4%80%EC%A0%81%EC%9D%B4%EA%B3%A0-%EC%A6%90%EA%B2%81%EA%B2%8C-%EB%A7%8C%EB%93%A4%EC%9E%90)
- [์ƒˆ๋กœ์šด ์ฐฝ์˜์  ๊ฒฝํ—˜์„ ๋””์ž์ธํ•˜๋‹ค](#%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%B0%BD%EC%9D%98%EC%A0%81-%EA%B2%BD%ED%97%98%EC%9D%84-%EB%94%94%EC%9E%90%EC%9D%B8%ED%95%98%EB%8B%A4)
- [๊ธฐ๋Šฅ ์†Œ๊ฐœ](#%EA%B8%B0%EB%8A%A5-%EC%86%8C%EA%B0%9C)
- [1. ๋…ธ๋“œ ์ƒ์„ฑ ๋ฐ ํŽธ์ง‘](#1-%EB%85%B8%EB%93%9C-%EC%83%9D%EC%84%B1-%EB%B0%8F-%ED%8E%B8%EC%A7%91)
- [2. ๋ณด๋“œ ํŽธ์ง‘๋ชจ๋“œ](#2-%EB%B3%B4%EB%93%9C-%ED%8E%B8%EC%A7%91%EB%AA%A8%EB%93%9C)
- [3. ํˆด๋ฐ”](#3-%ED%88%B4%EB%B0%94)
- [๊ธฐ์ˆ  ์Šคํƒ](#%EA%B8%B0%EC%88%A0-%EC%8A%A4%ED%83%9D)
- [๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ถ€๋ถ„](#%EA%B0%9C%EB%B0%9C-%EA%B3%BC%EC%A0%95%EC%97%90%EC%84%9C-%EA%B3%A0%EB%AF%BC%ED%96%88%EB%8D%98-%EB%B6%80%EB%B6%84)
- [1. ์•„์ดํŒจ๋“œ ์›น ๋””๋ฒ„๊น… ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?](#1-%EC%95%84%EC%9D%B4%ED%8C%A8%EB%93%9C-%EC%9B%B9-%EB%94%94%EB%B2%84%EA%B9%85-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%98%EB%82%98%EC%9A%94)
- [2. ๋ฌดํ•œ ์บ”๋ฒ„์Šค์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ทธ๋ฆฌ๋“œ ๊ตฌํ˜„: svg ์ฑ„ํƒ](#2-%EB%AC%B4%ED%95%9C-%EC%BA%94%EB%B2%84%EC%8A%A4%EC%9D%98-%EB%B0%B1%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EA%B7%B8%EB%A6%AC%EB%93%9C-%EA%B5%AC%ED%98%84-svg-%EC%B1%84%ED%83%9D)
- [๋ฐฉ๋ฒ• 1๏ธโƒฃ. SVG์˜ pattern์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•](#%EB%B0%A9%EB%B2%95-1%EF%B8%8F%E2%83%A3-svg%EC%9D%98-pattern%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95)
- [๋ฐฉ๋ฒ• 2๏ธโƒฃ. Canvas ํƒœ๊ทธ ๋‚ด์—์„œ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•](#%EB%B0%A9%EB%B2%95-2%EF%B8%8F%E2%83%A3-canvas-%ED%83%9C%EA%B7%B8-%EB%82%B4%EC%97%90%EC%84%9C-%EB%8F%99%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95)
- [3. ๋‚ฎ์€ ํ•ด์ƒ๋„์— DPR ์ ์šฉํ•˜๊ธฐ](#3-%EB%82%AE%EC%9D%80-%ED%95%B4%EC%83%81%EB%8F%84%EC%97%90-dpr-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0)
- [1. DPR(Device Pixel Ratio) ์ ์šฉ](#1-dprdevice-pixel-ratio-%EC%A0%81%EC%9A%A9)
- [2. Canvas ํฌ๊ธฐ ์กฐ์ •](#2-canvas-%ED%81%AC%EA%B8%B0-%EC%A1%B0%EC%A0%95)
- [4. ๋ฉ€ํ‹ฐํ„ฐ์น˜ hook ๊ตฌํ˜„](#4-%EB%A9%80%ED%8B%B0%ED%84%B0%EC%B9%98-hook-%EA%B5%AC%ED%98%84)
- [1. โœŒ๏ธ ๋‘ ์†๊ฐ€๋ฝ(2-finger touch)](#1-%E2%9C%8C%EF%B8%8F-%EB%91%90-%EC%86%90%EA%B0%80%EB%9D%BD2-finger-touch)
- [2. ์„ธ ์†๊ฐ€๋ฝ(3-finger touch)](#2-%EC%84%B8-%EC%86%90%EA%B0%80%EB%9D%BD3-finger-touch)
- [3. ๋„ค ์†๊ฐ€๋ฝ(4-finger touch) - ๋„ํ˜• ํฌ๊ธฐ ์กฐ์ •](#3-%EB%84%A4-%EC%86%90%EA%B0%80%EB%9D%BD4-finger-touch---%EB%8F%84%ED%98%95-%ED%81%AC%EA%B8%B0-%EC%A1%B0%EC%A0%95)
- [4. ๐Ÿคš ๋‹ค์„ฏ ์†๊ฐ€๋ฝ(5-finger touch)](#4-%F0%9F%A4%9A-%EB%8B%A4%EC%84%AF-%EC%86%90%EA%B0%80%EB%9D%BD5-finger-touch)
- [5. ResizeObserver ๊ฒฝ๊ณ : ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•ด๊ฒฐ](#5-resizeobserver-%EA%B2%BD%EA%B3%A0-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%B2%98%EB%A6%AC%ED%95%98%EC%97%AC-%ED%95%B4%EA%B2%B0)
- [ํšŒ๊ณ ](#%ED%9A%8C%EA%B3%A0)


## [์•„์ด๋””์–ด ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ](#๋ชฉ์ฐจ)

### ๋ฉ€ํ‹ฐ ํ„ฐ์น˜๋ฅผ ํ™œ์šฉํ•ด ์•„์ด๋””์–ด ์Šค์ผ€์น˜๋ฅผ ์ง๊ด€์ ์ด๊ณ  ์ฆ๊ฒ๊ฒŒ ๋งŒ๋“ค์ž!

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


### ์ƒˆ๋กœ์šด ์ฐฝ์˜์  ๊ฒฝํ—˜์„ ๋””์ž์ธํ•˜๋‹ค

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


## [๊ธฐ๋Šฅ ์†Œ๊ฐœ](#๋ชฉ์ฐจ)

์ง€๊ธˆ์€ **์•„์ดํŒจ๋“œ** ํ˜น์€ **์Šค๋งˆํŠธํฐ**์—์„œ ์‹œ์—ฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


### [1. ๋…ธ๋“œ ์ƒ์„ฑ ๋ฐ ํŽธ์ง‘](#๋ชฉ์ฐจ)

(ํ„ฐ์น˜๋œ ์ˆœ์„œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์†๊ฐ€๋ฝ ๋ฒˆํ˜ธ๊ฐ€ ๋ถ€์—ฌ๋ฉ๋‹ˆ๋‹ค.)

- **๋”๋ธ” ํด๋ฆญ**: ๋„ํ˜• ๋…ธ๋“œ๋ฅผ **์ƒ์„ฑ**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **ํ•œ ์†๊ฐ€๋ฝ ๋“œ๋ž˜๊ทธ**: ๋„ํ˜• ๋…ธ๋“œ์˜ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **๋‘ ์†๊ฐ€๋ฝ ํ•€์น˜**: ๋‘ ์†๊ฐ€๋ฝ์˜ ๊ฑฐ๋ฆฌ์™€ ๊ฐ๋„๋ฅผ ํ†ตํ•ด ๋„ํ˜• ๋…ธ๋“œ์˜ **ํฌ๊ธฐ์™€ ๊ฐ๋„**๋ฅผ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **์„ธ ์†๊ฐ€๋ฝ**: ์„ธ ์†๊ฐ€๋ฝ ์ค‘, 1๋ฒˆ์งธ์™€ 3๋ฒˆ์งธ์˜ ๊ฐ๋„๋ฅผ ํ†ตํ•ด ๋„ํ˜• ๋…ธ๋“œ์˜ **์ข…๋ฅ˜**๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **๋„ค ์†๊ฐ€๋ฝ**: ๋„ค ์†๊ฐ€๋ฝ ์ค‘, 1๋ฒˆ์งธ์™€ 4๋ฒˆ์งธ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋„ํ˜• ๋…ธ๋“œ์˜ **๋†’์ด์™€ ๋„ˆ๋น„**๋ฅผ ๊ฐ๊ฐ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **๋‹ค์„ฏ ์†๊ฐ€๋ฝ**: ๋‹ค์„ฏ ์†๊ฐ€๋ฝ์˜ ๊ฑฐ๋ฆฌ์— ๋”ฐ๋ผ ๋„ํ˜• ๋…ธ๋“œ์˜ **์ƒ‰**์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- **๋„ํ˜• ๋‹ค์‹œ ๋”๋ธ” ํด๋ฆญ**: ๋„ํ˜• ๋…ธ๋“œ๋ฅผ **์‚ญ์ œ**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


![gravidot](https://github.com/user-attachments/assets/029d1eb4-dca5-4ac3-9cd2-79865b8bdb70)

### [2. ๋ณด๋“œ ํŽธ์ง‘๋ชจ๋“œ](#๋ชฉ์ฐจ)

- ์ต๋ช… ๋กœ๊ทธ์ธ์„ ์ œ๊ณตํ•˜๊ณ  ์‚ฌ์šฉ์ž๋Š” ๋žœ๋ค์˜ ์ด๋ฆ„์œผ๋กœ ๋ณด๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ๋ณด๋“œ์˜ ์ œ๋ชฉ์„ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๊ณ , ์ƒˆ๋กœ์šด ๋ณด๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

![IMG_1258](https://github.com/user-attachments/assets/f0857451-a494-499d-91cf-884aced70373)

### [3. ํˆด๋ฐ”](#๋ชฉ์ฐจ)

- ๋ณด๋“œ์˜ **๋ฐฐ๊ฒฝ ํŒจํ„ด์„ ๋ณ€๊ฒฝ**ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (Dot / Line)
- **๋ณด๋“œ ํŽธ์ง‘ ๋ชจ๋“œ**์™€ **๋…ธ๋“œ ํŽธ์ง‘ ๋ชจ๋“œ**๋กœ ํ† ๊ธ€๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- ํœด์ง€ํ†ต ๋ฒ„ํŠผ์œผ๋กœ ๋ณด๋“œ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


## [๊ธฐ์ˆ  ์Šคํƒ](#๋ชฉ์ฐจ)

![next.js](https://img.shields.io/badge/next-141414?style=for-the-badge&logo=next.js&logoColor=white)
![TypeScript](https://img.shields.io/badge/TypeScript-blue.svg?style=for-the-badge&logo=TypeScript&logoColor=white)
![zustand](https://img.shields.io/badge/zustand-orange?style=for-the-badge&logo=zustand&logoColor=white)
![tailwindcss](https://img.shields.io/badge/tailwindcss-61DAFB?style=for-the-badge&logo=tailwindcss&logoColor=white)

![supabase](https://img.shields.io/badge/supabase-3FCF8E?style=for-the-badge&logo=supabase&logoColor=white)

![ESLint](https://img.shields.io/badge/ESLint-FFD93E?style=for-the-badge&logo=eslint&logoColor=white) ![Prettier](https://img.shields.io/badge/Prettier-pink?style=for-the-badge&logo=prettier&logoColor=white)
![npm](https://img.shields.io/badge/npm-red?style=for-the-badge&logo=npm&logoColor=white)
![vercel](https://img.shields.io/badge/vercel-f0f0f0?style=for-the-badge&logo=vercel&logoColor=black)




## [๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ถ€๋ถ„](#๋ชฉ์ฐจ)

### [1. ์•„์ดํŒจ๋“œ ์›น ๋””๋ฒ„๊น… ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?](#๋ชฉ์ฐจ)

์ €๋Š” Brave ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ„ฐ์น˜ ๋””๋ฐ”์ด์Šค์ธ ์•„์ดํŒจ๋“œ์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ๋””๋ฒ„๊น…์„ ํ• ์ง€ ๊ณ ๋ฏผ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. (์•„์ง๊นŒ์ง€ Brave ์—์„œ ์•„์ดํŒจ๋“œ ์—ฐ๊ฒฐํ•˜์—ฌ ๋””๋ฒ„๊น…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ชป์ฐพ์•˜์Šต๋‹ˆ๋‹ค๐Ÿฅฒ) ์•„์ดํŒจ๋“œ๋Š” Apple ์˜ ๊ฐ•๋ ฅํ•œ ํ†ต์น˜(?) ์•„๋ž˜์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Safari ๋ฅผ ํ†ตํ•ด ๋””๋ฒ„๊น…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

์•„์ดํŒจ๋“œ๋ฅผ C ํƒ€์ž…์˜ ์ผ€์ด๋ธ”๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  Safari ์ƒ๋‹จ์˜ Develop ์„ ํด๋ฆญํ•˜๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด iPadOS ๋ฅผ ํ™•์ธํ•˜์—ฌ ์ฝ˜์†”์ฐฝ์„ ์—ด์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ง localhost ๋กœ ๊ฐœ๋ฐœ์ค‘์ธ ํ™˜๊ฒฝ์ด๋ผ๋ฉด, ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  ifconfig en0๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์„ค์ • ์ •๋ณด ์ค‘ ์ฒซ ๋ฒˆ์งธ ์ด๋”๋„ท ์–ด๋Œ‘ํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ด๋ฏธ์ง€์—์„œ inet ๋’ค์—์žˆ๋Š” โ€œIP ์ฃผ์†Œโ€ + โ€œ:ํฌํŠธ๋ฒˆํ˜ธโ€ ๋ฅผ ์•„์ดํŒจ๋“œ Safari ์— ์ž…๋ ฅํ•˜๋ฉด ์ž˜ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค!


### [2. ๋ฌดํ•œ ์บ”๋ฒ„์Šค์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ทธ๋ฆฌ๋“œ ๊ตฌํ˜„: svg ์ฑ„ํƒ](#๋ชฉ์ฐจ)

๋ฌดํ•œ ์บ”๋ฒ„์Šค์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ทธ๋ฆฌ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

SVG(Scalable Vector Graphics)๋Š” ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ ๊ธฐ๋ฐ˜์˜ ์›น ๊ธฐ์ˆ ๋กœ, ํฌ๊ธฐ ์กฐ์ •๊ณผ ํ’ˆ์งˆ ์œ ์ง€์— ๊ฐ•์ ์„ ๊ฐ€์ง€๋ฉฐ, ๋‹ค์–‘ํ•œ ๊ทธ๋ž˜ํ”ฝ๊ณผ ์‹œ๊ฐ์  ์š”์†Œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. **ํ™•๋Œ€/์ถ•์†Œ ์‹œ ํ’ˆ์งˆ ์œ ์ง€, ๊ตฌํ˜„์˜ ๊ฐ„๊ฒฐ์„ฑ, CSS์™€์˜ ์—ฐ๋™, GPU ๊ฐ€์† ์ง€์›, ๊ทธ๋ฆฌ๊ณ  DOM ์กฐ์ž‘์˜ ์œ ์—ฐ์„ฑ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ SVG์˜ pattern์„ ์ฑ„ํƒ**ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


#### ๋ฐฉ๋ฒ• 1๏ธโƒฃ. SVG์˜ pattern์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

์žฅ์ 

- SVG๋Š” ๋ฒกํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ, ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜ ์ค„์—ฌ๋„ ํ’ˆ์งˆ ์ €ํ•˜ ์—†์ด ๋ Œ๋”๋ง๋˜๋ฏ€๋กœ ํ™•๋Œ€/์ถ•์†Œ(Zoom)์—๋„ ์„ ๋ช…ํ•œ ์ถœ๋ ฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
- pattern ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๋ฆฌ๋“œ ํŒจํ„ด์„ ๋ณด๋‹ค ์†์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- DOM์— ์ถ”๊ฐ€๋œ SVG ์š”์†Œ๋ฅผ ์ง์ ‘ ์กฐ์ž‘ํ•˜๊ฑฐ๋‚˜ ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋„ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค. SVG๋Š” ์ž์ฒด์ ์œผ๋กœ ๋‚ด๋ถ€ DOM์„ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
- CSS์™€์˜ ์—ฐ๋™์ด ๊ฐ€๋Šฅํ•˜์—ฌ, fill ์†์„ฑ์„ ํ™œ์šฉํ•ด ํŒจํ„ด ์Šคํƒ€์ผ๋ง์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- SVG๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ GPU ๊ฐ€์†์„ ํ™œ์šฉํ•˜๋ฏ€๋กœ, ํ™•๋Œ€/์ถ•์†Œ ์‹œ ๋น„๊ต์  ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ 

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


#### ๋ฐฉ๋ฒ• 2๏ธโƒฃ. Canvas ํƒœ๊ทธ ๋‚ด์—์„œ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•

์žฅ์ 

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

๋‹จ์ 

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


### [3. ๋‚ฎ์€ ํ•ด์ƒ๋„์— DPR ์ ์šฉํ•˜๊ธฐ](#๋ชฉ์ฐจ)

#### 1. DPR(Device Pixel Ratio) ์ ์šฉ

ํ˜„๋Œ€ ๋””์Šคํ”Œ๋ ˆ์ด๋Š” ๊ณ ํ•ด์ƒ๋„๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„, Device Pixel Ratio(DPR)์— ๋”ฐ๋ผ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ๊ทธ๋ž˜ํ”ฝ์˜ ์„ ๋ช…๋„๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  **๊ธฐ๋ณธ ํ•ด์ƒ๋„๋กœ๋งŒ Canvas๋ฅผ ์„ค์ •ํ•˜๋ฉด**, ํŠนํžˆ ๊ณ ํ•ด์ƒ๋„ ๋””์Šคํ”Œ๋ ˆ์ด์—์„œ ๊ทธ๋ž˜ํ”ฝ์ด **ํ๋ฆฟํ•˜๊ฑฐ๋‚˜ ํ”ฝ์…€์ด ๋„๋“œ๋ผ์ ธ ๋ณด์ผ ์ˆ˜** ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด **window.devicePixelRatio๋ฅผ** ํ™œ์šฉํ•ด ํ˜„์žฌ ๋””๋ฐ”์ด์Šค์˜ DPR ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ด ๊ฐ’์€ ๋””๋ฐ”์ด์Šค์˜ ๋ฌผ๋ฆฌ์  ํ”ฝ์…€๊ณผ CSS ํ”ฝ์…€ ๊ฐ„์˜ ๋น„์œจ์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๊ณ ํ•ด์ƒ๋„ ๋””์Šคํ”Œ๋ ˆ์ด์ผ์ˆ˜๋ก 1๋ณด๋‹ค ํฐ ๊ฐ’(์˜ˆ: 2, 3 ๋“ฑ)์ด ๋ฉ๋‹ˆ๋‹ค.

์ด ๊ฐ’์„ ๋„ํ˜•์˜ ์œ„์น˜(x, y), ํฌ๊ธฐ(width, height), ์„  ๋‘๊ป˜(lineWidth) ๋“ฑ์˜ **๋ชจ๋“  ๋ Œ๋”๋ง ์†์„ฑ์— ๊ณฑํ•ด์คŒ**์œผ๋กœ์จ ๋””๋ฐ”์ด์Šค ํ•ด์ƒ๋„์— ๋งž์ถ˜ ์„ ๋ช…ํ•œ ๊ทธ๋ž˜ํ”ฝ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, DPR์ด 2์ธ ๊ฒฝ์šฐ, ๋„ํ˜•์˜ ๋ชจ๋“  ์†์„ฑ์„ 2๋ฐฐ๋กœ ํ™•๋Œ€ํ•ด ๊ณ„์‚ฐํ•˜๊ณ  Canvas๊ฐ€ ์ด๋ฅผ ๋ Œ๋”๋งํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.


#### 2. Canvas ํฌ๊ธฐ ์กฐ์ •

Canvas ํƒœ๊ทธ๋Š” **๊ธฐ๋ณธ์ ์œผ๋กœ CSS๋กœ ์„ค์ •๋œ ํฌ๊ธฐ์™€ ์‹ค์ œ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋˜๋Š” ๋‚ด๋ถ€ ํ•ด์ƒ๋„(ํ”ฝ์…€ ํฌ๊ธฐ)๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด** ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, Canvas์˜ CSS ํฌ๊ธฐ์™€ ์‹ค์ œ ํ”ฝ์…€ ํ•ด์ƒ๋„๊ฐ€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ, ๊ทธ๋ž˜ํ”ฝ์ด ํ๋ฆฟํ•˜๊ฒŒ ๋ณด์ด๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด, **Canvas์˜ ๋‚ด๋ถ€ ํ•ด์ƒ๋„๋„ DPR์— ๋งž์ถฐ ์กฐ์ •**ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, CSS๋กœ ์ง€์ •๋œ Canvas์˜ ํฌ๊ธฐ๊ฐ€ 400x300์ด๊ณ  DPR์ด 2๋ผ๋ฉด, ๋‚ด๋ถ€ ํ•ด์ƒ๋„๋ฅผ 800x600์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1. `canvas.width`์™€ `canvas.height` ๊ฐ’์„ **DPR์— ๋”ฐ๋ผ ์ฆ๊ฐ€์‹œ์ผœ** ๊ณ ํ•ด์ƒ๋„๋ฅผ ์ง€์›.
2. Canvas์˜ ์Šคํƒ€์ผ ํฌ๊ธฐ(`style.width`, `style.height`)๋ฅผ **๊ธฐ์กด CSS ํฌ๊ธฐ์™€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€**ํ•˜์—ฌ, ์‹œ๊ฐ์ ์œผ๋กœ๋Š” ๋™์ผํ•œ ํฌ๊ธฐ๋กœ ๋ณด์ด๋„๋ก ์„ค์ •.
3. ์กฐ์ •๋œ ํ•ด์ƒ๋„์— ๋งž๊ฒŒ ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ DPR๋กœ ๊ณ„์‚ฐํ•˜์—ฌ ๋ Œ๋”๋ง.

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


**[DPR ์ ์šฉ ์ „]**

before_dpr

**[DPR ์ ์šฉ ํ›„]**

after_dpr


### [4. ๋ฉ€ํ‹ฐํ„ฐ์น˜ hook ๊ตฌํ˜„](#๋ชฉ์ฐจ)

๋ฉ€ํ‹ฐํ„ฐ์น˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํ„ฐ์น˜ ๊ธฐ๋ฐ˜ ๋””๋ฐ”์ด์Šค์—์„œ ์—ฌ๋Ÿฌ ์†๊ฐ€๋ฝ์„ ๋™์‹œ์— ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ง๊ด€์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ React ํ™˜๊ฒฝ์—์„œ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด `useMultiTouch`๋ผ๋Š” ์ปค์Šคํ…€ Hook์„ ์„ค๊ณ„ํ–ˆ์œผ๋ฉฐ, ์ด Hook์€ ์—ฌ๋Ÿฌ ์†๊ฐ€๋ฝ ํ„ฐ์น˜๋ฅผ ์ธ์‹ํ•˜๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋„ํ˜• ๋…ธ๋“œ๋ฅผ ํŽธ์ง‘ํ•˜๊ฑฐ๋‚˜ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


**1. ๊ธฐ๋ณธ ๋™์ž‘ ์›๋ฆฌ**

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

์‹ค์ œ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ฝ˜์†”์— ์ฐ๊ณ  ์•„์ดํŒจ๋“œ์—์„œ ํ„ฐ์น˜๋ฅผ ํ•ด๋ณด๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด Touch Event ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค ๋ณด๋ฉด ์ œ๊ฐ€ ๋“œ๋ž˜๊ทธ ํ•ด๋‘” Touch ๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์†๊ฐ€๋ฝ 3๊ฐœ๋กœ ํ„ฐ์น˜๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, 3๊ฐœ์˜ TouchList (์œ ์‚ฌ๋ฐฐ์—ด๊ฐ์ฒด) ๊ฐ€ ์žˆ๊ณ , ๊ทธ List ์•ˆ์—๋Š” Touch ๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์กด์žฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


**2. ๋ฉ€ํ‹ฐํ„ฐ์น˜์˜ ํ™œ์„ฑํ™”์™€ ์ดˆ๊ธฐํ™”**

- ํ„ฐ์น˜ ์ด๋ฒคํŠธ ์ถ”์ 

์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์— ์†๊ฐ€๋ฝ์„ ๋Œ€๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ `TouchEvent`๋ฅผ ํ†ตํ•ด ํ„ฐ์น˜ ์ขŒํ‘œ๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ„ฐ์น˜ ํฌ์ธํŠธ(์†๊ฐ€๋ฝ์˜ ์œ„์น˜ ์ขŒํ‘œ)๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

- ๋ฉ€ํ‹ฐํ„ฐ์น˜ ์ƒํƒœ ๊ด€๋ฆฌ

**๋‘ ์†๊ฐ€๋ฝ ์ด์ƒ์ด ๋™์‹œ์— ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•˜**๋ฉด ๋ฉ€ํ‹ฐํ„ฐ์น˜ ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒํƒœ๋Š” `useRef`๋ฅผ ํ™œ์šฉํ•ด ์ง€์†์ ์œผ๋กœ ์ถ”์ ๋˜๋ฉฐ, ์†๊ฐ€๋ฝ์ด ํ™”๋ฉด์—์„œ ๋–ผ์–ด์ง€๋ฉด ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.

- ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ์„ค์ •

๋ฉ€ํ‹ฐํ„ฐ์น˜๊ฐ€ ํ™œ์„ฑํ™”๋˜์—ˆ์„ ๋•Œ ์ดˆ๊ธฐ ๊ฑฐ๋ฆฌ์™€ ๊ฐ๋„๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ด์–ด์ง€๋Š” ์ž‘์—…์—์„œ ๋น„๊ต ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


**3. ์ฃผ์š” ๊ธฐ๋Šฅ๊ณผ ์ฒ˜๋ฆฌ ๋ฐฉ์‹**

#### 1. โœŒ๏ธ ๋‘ ์†๊ฐ€๋ฝ(2-finger touch)

- ๋„ํ˜•์˜ ํฌ๊ธฐ์™€ ํšŒ์ „ ์กฐ์ž‘

๋‘ ์†๊ฐ€๋ฝ์œผ๋กœ ํ„ฐ์น˜ํ•˜๋ฉด ์†๊ฐ€๋ฝ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ์™€ ๊ฐ๋„๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

- ๊ฑฐ๋ฆฌ ๋ณ€ํ™”

์†๊ฐ€๋ฝ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ์ดˆ๊ธฐ ๊ฑฐ๋ฆฌ๋ณด๋‹ค ์ฆ๊ฐ€ํ•˜๋ฉด ๋„ํ˜•์ด ํ™•๋Œ€๋˜๊ณ , ๊ฐ์†Œํ•˜๋ฉด ์ถ•์†Œ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋„ํ˜•์˜ ์Šค์ผ€์ผ์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ํฌ๊ธฐ๋Š” ์ตœ์†Œ 0.5๋ฐฐ์—์„œ ์ตœ๋Œ€ 3๋ฐฐ๊นŒ์ง€ ์ œํ•œํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์™œ๊ณก์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

- ๊ฐ๋„ ๋ณ€ํ™”

์†๊ฐ€๋ฝ ๊ฐ„์˜ ๊ฐ๋„ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋„ํ˜•์„ ํšŒ์ „์‹œํ‚ต๋‹ˆ๋‹ค. ๊ฐ๋„๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐํ•˜๋ฉฐ, ํšŒ์ „ ๊ฐ’์€ ๋ผ๋””์•ˆ ๋‹จ์œ„๋ฅผ ๋„(degree)๋กœ ๋ณ€ํ™˜ํ•ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.


#### 2. ์„ธ ์†๊ฐ€๋ฝ(3-finger touch)

- ๋„ํ˜•์˜ ํ˜•ํƒœ ๋ณ€๊ฒฝ

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

- ๊ฐ๋„ ๊ธฐ๋ฐ˜ ๋„ํ˜• ์„ ํƒ

์†๊ฐ€๋ฝ ๊ฐ„ ๊ฐ๋„๊ฐ€ ์ž‘์„์ˆ˜๋ก ๊ฐ„๋‹จํ•œ ๋„ํ˜•(์˜ˆ: ์›ํ˜•, ์ง์‚ฌ๊ฐํ˜•)์„ ์„ ํƒํ•˜๊ณ , ๊ฐ๋„๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ณต์žกํ•œ ๋„ํ˜•(์˜ˆ: ๋ณ„ ๋ชจ์–‘, ๋‹ค๊ฐํ˜•)์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

- ์ œํ•œ ๋ฒ”์œ„ ์„ค์ •

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


#### 3. ๋„ค ์†๊ฐ€๋ฝ(4-finger touch) - ๋„ํ˜• ํฌ๊ธฐ ์กฐ์ •

๋„ค ์†๊ฐ€๋ฝ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ„ฐ์น˜๋œ ์˜์—ญ์˜ ์ตœ์†Œ, ์ตœ๋Œ€ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๋„ํ˜•์˜ ๊ฐ€๋กœ ์„ธ๋กœ ํฌ๊ธฐ๋ฅผ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

- ํฌ๊ธฐ ์ œํ•œ

๋„ํ˜•์˜ ์ตœ์†Œ ํฌ๊ธฐ๋ฅผ 100px๋กœ ์„ค์ •ํ•˜์—ฌ ๋„ˆ๋ฌด ์ž‘์€ ํฌ๊ธฐ๋กœ ์ธํ•ด ๋„ํ˜•์ด ๋ณด์ด์ง€ ์•Š๊ฑฐ๋‚˜ ์กฐ์ž‘์ด ์–ด๋ ค์›Œ์ง€๋Š” ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

- ๋™์  ํฌ๊ธฐ ๋ณ€๊ฒฝ

๋„ค ์†๊ฐ€๋ฝ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ ๋ณ€ํ™”๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋„ํ˜•์˜ ํญ๊ณผ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.


#### 4. ๐Ÿคš ๋‹ค์„ฏ ์†๊ฐ€๋ฝ(5-finger touch)

- ๋„ํ˜•์˜ ์ƒ‰์ƒ ๋ณ€๊ฒฝ

๋‹ค์„ฏ ์†๊ฐ€๋ฝ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ์ฒซ ๋ฒˆ์งธ ์†๊ฐ€๋ฝ๊ณผ ๋‹ค์„ฏ ๋ฒˆ์งธ ์†๊ฐ€๋ฝ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋„ํ˜•์˜ ์ƒ‰์ƒ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

- ๊ฑฐ๋ฆฌ์™€ ์ƒ‰์ƒ ๋งคํ•‘

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

- ์œ ์—ฐํ•œ ์ƒ‰์ƒ ์ „ํ™˜

๊ฐ ๊ฑฐ๋ฆฌ๋ฅผ ์ž„๊ณ„๊ฐ’(threshold)์œผ๋กœ ๋‚˜๋ˆ„์–ด ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ์ƒ‰์ƒ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ์ƒ‰์ƒ์„ ์ง๊ด€์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


### [5. ResizeObserver ๊ฒฝ๊ณ : ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•ด๊ฒฐ](#๋ชฉ์ฐจ)

```shell
ResizeObserver loop completed with undelivered notifications
```

์ด ๊ฒฝ๊ณ ๋Š” ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์—์„œ ์ž์ฃผ ๋‚˜ํƒ€๋‚˜๋Š” ๋ฉ”์‹œ์ง€๋กœ, ResizeObserver๊ฐ€ ๋ ˆ์ด์•„์›ƒ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ผ๋ถ€ ์•Œ๋ฆผ์„ ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

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

ResizeObserver๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

```js
const resizeObserver = new ResizeObserver(() => {
setTimeout(() => {
// ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋˜๋Š” DOM ์ž‘์—…
}, 0);
});
```


## ํšŒ๊ณ 

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