Daily UI

Glassmorphism in Flutter

flutter developer 2025. 1. 31. 13:32

๐ŸŽจ What I Designed

https://github.com/suojae/flutter_ui_lab/blob/main/lib/2025/01/31.dart

 

flutter_ui_lab/lib/2025/01/31.dart at main · suojae/flutter_ui_lab

Contribute to suojae/flutter_ui_lab development by creating an account on GitHub.

github.com


๐Ÿ”Ž  How I Made It

์‚ฌ์šฉํ•œ ์ฃผ์š” ์œ„์ ฏ: ClipRect, BackdropFilter, ImageFilter

 

What is ClipRect?

https://stackoverflow.com/questions/70255171/clip-objects-drawn-outside-of-canvas

ClipRect๋Š” ์ž์‹์œ„์ ฏ(child)์„ ์‚ฌ๊ฐํ˜• ํ˜•ํƒœ๋กœ ํด๋ฆฌํ•‘ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ํ™”๋ฉด ์ „์ฒด์— ์œ„์ ฏ์ด ์žˆ๋”๋ผ๋„ ClipRect๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ถ€์˜์—ญ๋งŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋•Œ ์ฃผ์˜ํ• ์ ์€ ๋ ˆ์ด์•„์›ƒ ์ž์ฒด์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํด๋ฆฌํ•‘๋œ ๋ฐ”๊นฅ๋ถ€๋ถ„์€ ๋ณด์ด์ง€ ์•Š์ง€๋งŒ ์‹ค์ œ๋กœ ๊ณต๊ฐ„์„ ๊ทธ๋Œ€๋กœ ์ฐจ์ง€ํ•˜๊ฒŒ ๋œ๋‹ค.

 

ClipRect๋กœ ์ฃผ์˜ํ•  ์ ์€ GPU์—์„œ ์ถ”๊ฐ€์ ์ธ ํด๋ฆฌํ•‘ ์—ฐ์‚ฐ์ด ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ๊ณผ๋„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ผญ ํ•„์š”ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. ์‹ค์ œ๋กœ ๊ณต์‹๋ฌธ์„œ์—๋Š” ๋ถˆํ•„์š”ํ•œ ํด๋ฆฌํ•‘์„ ์—†์• ์„œ ์„ฑ๋Šฅ๊ฐœ์„ ํ•œ ์‚ฌ๋ก€๋ฅผ ์†Œ๊ฐœ์ค‘์ธ๋ฐ , 2018๋…„ 5์›” ๊ธฐ์ค€์œผ๋กœ Flutter ๊ฐค๋Ÿฌ๋ฆฌ ์•ฑ์˜ ํ‰๊ท  ํ”„๋ ˆ์ž„ ๋ž˜์Šคํ„ฐํ™” ์‹œ๊ฐ„์ด ์•ฝ 35ms์˜€๋Š”๋ฐ, ์ด๋Š” 60fps์˜ ๋ถ€๋“œ๋Ÿฌ์šด ๋ Œ๋”๋ง์„ ์œ„ํ•œ 16ms๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ์ˆ˜์น˜์˜€๋‹ค. ๋ถˆํ•„์š”ํ•œ ํด๋ฆฝ ๊ด€๋ จ ์ž‘์—…์„ ์ œ๊ฑฐํ•จ์œผ๋กœ์จ, ํ”„๋ ˆ์ž„๋‹น 35ms์—์„œ 17.5ms๋กœ ๊ฑฐ์˜ 2๋ฐฐ์˜ ์†๋„ ํ–ฅ์ƒ์„ ์ด๋ฃจ์—ˆ๋‹ค๊ณ  ๋‚˜์™€์žˆ๋‹ค.

 

 

What is BackdropFilter?

BackdropFilter๋Š” Flutter์—์„œ ํŠน์ • ์œ„์ ฏ์˜ ๋ฐฐ๊ฒฝ์„ ํ๋ฆฌ๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ๊ทธ๋ž˜ํ”ฝ ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•  ๋•Œ์‚ฌ์šฉํ•˜๋Š” ์œ„์ ฏ์ด๋‹ค. ์ด๋•Œ ์ฃผ์˜ํ•  ๊ฒƒ์€ BackdropFilter ๊ฐ€ ์ ์šฉ๋œ ์œ„์ ฏ ๋’ค์— ์žˆ๋Š”๊ฒƒ๋“ค์€ ํ๋ ค์ง€์ง€๋งŒ BackdropFilter ์•ˆ์˜ Child๋Š” ํ๋ ค์ง€์ง€ ์•Š๋Š”๋‹ค. ์œ„์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด BackdropFilter ์•ˆ์— Child๋กœ Center(Text()) ์œ„์ ฏ์ด ์žˆ์ง€๋งŒ

 

์œ„์™€ ๊ฐ™์ด Child๋ถ€๋ถ„์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๊ณ  ๋’ท๋ฐฐ๊ฒฝ๋งŒ blurํšจ๊ณผ๊ฐ€ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

What is ImageFilter?

ImageFilter๋Š” Flutter์—์„œ ๊ทธ๋ž˜ํ”ฝ ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•˜๋Š” API์ด๋‹ค. ์ฃผ์š” ํ•„ํ„ฐ๋กœ๋Š” ๋‘๊ฐ€์ง€ - ๋ธ”๋Ÿฌํšจ๊ณผ์™€ ํ–‰๋ ฌ ๋ณ€ํ™˜ - ๊ฐ€ ์žˆ๋‹ค. 

 

https://medium.com/skylar-salernos-tech-blog/image-convolution-filters-explained-c878f1056e78

์™œ ํ–‰๋ ฌ๋ณ€ํ™˜๊ณผ ๋ธ”๋Ÿฌํšจ๊ณผ๊ฐ€ ๊ฐ™์ด์žˆ๋Š”๊ฑฐ์ง€ ๋ผ๋Š” ์˜๊ตฌ์‹ฌ์ด ๋“ค์–ด ์ฐพ์•„๋ดค๋Š”๋ฐ ๋ธ”๋Ÿฌ ํšจ๊ณผ๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ๊ต‰์žฅ์ด ํฅ๋ฏธ๋กœ์› ๋‹ค. ๋ธ”๋Ÿฌํšจ๊ณผ์˜ ๊ธฐ๋ณธ์›๋ฆฌ๋Š” ์ฃผ๋ณ€ ํ”ฝ์…€์„ ์„ž์–ด์„œ ํ‰๊ท ๊ฐ’์„ ๋งŒ๋“ ๋‹ค. 

 

๋ธ”๋Ÿฌ ํšจ๊ณผ๋ฅผ ํ•œ ์ค„ ์š”์•ฝํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

๐Ÿ“Œ ๋ธ”๋Ÿฌ ํšจ๊ณผ = ์›๋ž˜ ํ”ฝ์…€ ๊ฐ’ × ๋ธ”๋Ÿฌ ์ปค๋„ → ํ”ฝ์…€ ๊ฐ’์ด ์ฃผ๋ณ€๊ณผ ์„ž์ด๋ฉด์„œ ํ‰ํƒ„ํ™”๋˜๋Š” ํšจ๊ณผ

 

 

๋‚ด๋ถ€ ์ฝ”๋“œ๋ฅผ ๋œฏ์–ด๋ณด๋ฉด blur๋ฉ”์„œ๋“œ๋Š” ๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ ๋ฐฉ์‹์„ ์ ์šฉํ•œ๋‹ค๊ณ  ์ฃผ์„์ด ๋‹ฌ๋ ค์žˆ๋‹ค. ๊ทธ๋Ÿผ ๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ๋ž€ ๋ฌด์—‡์ผ๊นŒ? ์•ž์„œ ํŠน์ •ํ–‰๋ ฌ์„ ๊ณฑํ•œ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ ๋˜‘๊ฐ™์€ ์ˆ˜๊ฐ€ ์žˆ๋Š” ํ–‰๋ ฌ์„ ๊ณฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ "๊ฐ€์šฐ์Šค ๋ถ„ํฌ" ๊ธฐ๋ฐ˜์œผ๋กœ ์ˆ˜๊ฐ€ ๋ถ„ํฌ๋œ ํ–‰๋ ฌ๊ฐ’์„ ๋ณธ๋ž˜ ํ”ฝ์…€ ํ–‰๋ ฌ์— ๊ณฑํ•ด์„œ ์ข€๋” ๋ถ€๋“œ๋Ÿฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์šด blur์ฒ˜๋ฆฌ๋ฐฉ๋ฒ•์ด๋‹ค.

https://velog.io/@wyjung0731/Gaussian-Filter

 

 

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

 

์ด๋ฏธ์ง€๋ฅผ ๋ณด๋ฉด sigmaX = 100, sigmaY = 0 (์™ผ์ชฝ)์—์„œ๋Š” ๊ฐ€๋กœ ๋ฐฉํ–ฅ์œผ๋กœ ์ค„๋ฌด๋Šฌ๊ฐ€ ์ƒ๊ธฐ๊ณ , sigmaX = 0, sigmaY = 100 (์˜ค๋ฅธ์ชฝ)์—์„œ๋Š” ์„ธ๋กœ ๋ฐฉํ–ฅ์œผ๋กœ ์ค„๋ฌด๋Šฌ๊ฐ€ ์ƒ๊ธฐ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ‘œํ˜„ํ•˜์ž๋ฉด

 

๋ธ”๋Ÿฌ๋Š” ์ด๋ฏธ์ง€์˜ ํ”ฝ์…€์„ ํผ๋œจ๋ฆฌ๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. 

  • ๋ถ“์„ ์ขŒ์šฐ๋กœ๋งŒ ๋ฌธ์ง€๋ฅด๋ฉด? ๐Ÿ‘‰ ์œ„์•„๋ž˜ ๋ฐฉํ–ฅ์€ ์น ํ•ด์ง€์ง€ ์•Š์•„์„œ ์ค„๋ฌด๋Šฌ๊ฐ€ ์ƒ๊น€.
  • ๋ถ“์„ ์œ„์•„๋ž˜๋กœ๋งŒ ๋ฌธ์ง€๋ฅด๋ฉด? ๐Ÿ‘‰ ์ขŒ์šฐ ๋ฐฉํ–ฅ์ด ์น ํ•ด์ง€์ง€ ์•Š์•„์„œ ์ค„๋ฌด๋Šฌ๊ฐ€ ์ƒ๊น€.

๐Ÿ’ก ๋ธ”๋Ÿฌ๋„ ๋˜‘๊ฐ™๋‹ค

  • sigmaX = 100, sigmaY = 0 → ๊ฐ€๋กœ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ํผ์ง 
  • sigmaX = 0, sigmaY = 100 → ์„ธ๋กœ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ํผ์ง 

 

๊ทธ๋ž˜์„œ ์ด๊ฑธ ํ”Œ๋Ÿฌํ„ฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•Œ๋ฉด ์–ด๋–ค๊ฒŒ ์ข‹์„๊นŒ? 

 

 

์‚ฌ์šฉ์ž๊ฐ€ ํ™•๋Œ€ํ•œ๋งŒํผ Sigma๊ฐ’์„ ๊ฐ€์ค‘์‹œ์ผฐ๋”๋‹ˆ ์žฌ๋ฐŒ๋Š” ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค! (๊ฐ€์„ฑ๋น„..์ตœ๊ณ ..! ๐Ÿ˜ญ)  ๋‚˜์ค‘์— ์ด๊ฑธ๋กœ ์ฐจ๋ผ๋ฆฌ ์ „์ฒด๋ทฐ์— ์‹œ๊ทธ๋งˆ๊ฐ’์„ ๋„ฃ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ํ„ฐ์น˜ํ•˜๋Š”๋ถ€๋ถ„๋งŒ ์‹œ๊ทธ๋งˆ๋ฅผ 0์œผ๋กœ ๋„ฃ์–ด์„œ ์œ ๋ฆฌ์ฐฝ์˜ ๊น€์„ ๋‹ฆ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ค„ ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.


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