๐Ÿ“š Study/Html, css

[svg] SVG viewBox๋ฅผ ์•Œ์•„๋ณด์ž

kkh1902 2022. 9. 6. 16:02
728x90
๋ฐ˜์‘ํ˜•

๋ชฉ์ฐจ

  • SVG๋ž€
  • viewBox๋ž€
    • ์˜๋ฏธ
    • ๊ธฐ๋ณธ ์˜ˆ์‹œ
    • ์œ„์น˜ ์กฐ์ • ์˜ˆ์‹œ
    • ํ™•๋Œ€, ์ถ•์†Œ ์˜ˆ์‹œ

SVG๋ž€

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

viewBox๋ž€

์˜๋ฏธ

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

viewBox ์†์„ฑ ๊ฐ’

viewBox ์†์„ฑ์˜ ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

viewBox="<min-x> <min-y> <width> <height>"

์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ min-x์™€ min-y๋Š” svg๊ฐ€ ๊ทธ๋ ค์ง€๋Š” ์˜์—ญ์˜ ์‹œ์ž‘์ , ์™ผ์ชฝ ์ƒ๋‹จ์˜ ๊ผญ์ง“์ ์œผ๋กœ, width์™€ height๋Š” ๊ฐ๊ฐ ์˜์—ญ์˜ ๊ฐ€๋กœ, ์„ธ๋กœ ๊ธธ์ด๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

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

๊ธฐ๋ณธ ์˜ˆ์‹œ

์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด svg ์š”์†Œ ์ค‘์— circle์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.

const App = () => (
  <div style={{ marginTop: '50px', marginLeft: '50px' }}>
    <div style={{ backgroundColor: 'yellow', width: '300px', height: '300px' }}>
      <svg viewBox="0 0 200 200">
        <circle r="100" fill="blue" />
      </svg>
    </div>
  </div>
);

export default App;

viewport์—์„œ svg๋Š” width์™€ height๊ฐ€ ๊ฐ๊ฐ 300px์ธ ์˜์—ญ ์•ˆ์— ์œ„์น˜ํ•˜๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ svg์˜ viewBox๋Š” "0 0 200 200"์ด๋ฏ€๋กœ, viewport์˜ width, height 300px์˜ ๊ธธ์ด๋Š” svg viewBox ์ขŒํ‘œํ‰๋ฉด ๊ธฐ์ค€์œผ๋กœ 200์˜ ๊ธธ์ด๊ฐ€ ๋œ๋‹ค. svg์˜ ์š”์†Œ ์ค‘์—์„œ circle์˜ ์ขŒํ‘œ ๋˜ํ•œ svg์˜ viewBox์˜ ์ขŒํ‘œ๋ฅผ ๋”ฐ๋ฅด๊ฒŒ ๋œ๋‹ค. circle ์š”์†Œ์˜ ์ค‘์‹ฌ ์ขŒํ‘œ ์†์„ฑ cx์™€ cy๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ์ƒํƒœ์ด๋ฏ€๋กœ ํ˜„์žฌ cx="0", cy="0"์ด ์ ์šฉ๋œ ์ƒํƒœ์ด๋ฉด์„œ, ๋ฐ˜์ง€๋ฆ„ r=100์˜ circle ์š”์†Œ๊ฐ€ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํŠน์ง•์€ ์› ์ค‘์‹ฌ์„ ๊ธฐ์ค€์œผ๋กœ ์ œ1, 3, 4 ์‚ฌ๋ถ„๋ฉด(๋ณด๋ผ์ƒ‰ ๋ถ€๋ถ„)์€ svg viewBox ์˜์—ญ์„ ๋ฒ—์–ด๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— viewport์—์„œ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ด๋‹ค.

์œ„์น˜ ์กฐ์ • ์˜ˆ์‹œ

์ด๋ฒˆ์—๋Š” ๋‹ค๋ฅธ ์˜ˆ์‹œ๋ฅผ ๋ณด์ž.

์ผ๋‹จ circle ์š”์†Œ์— cx="100", cy="100"์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

const App = () => (
  <div style={{ marginTop: '50px', marginLeft: '50px' }}>
    <div style={{ backgroundColor: 'yellow', width: '300px', height: '300px' }}>
      <svg viewBox="0 0 200 200">
        <circle cx="100" cy="100" r="100" fill="blue" />
      </svg>
    </div>
  </div>
);

export default App;

ํ˜„์žฌ ์ƒํƒœ์—์„œ viewBox๋ฅผ ์ด์šฉํ•ด์„œ ์–ด๋–ป๊ฒŒ ๊ธฐ๋ณธ ์˜ˆ์‹œ์™€ ๊ฐ™์€ ๋ชจ์–‘์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ. ๋ฐ”๋กœ min-x์™€ min-y๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

viewBox์˜ min-x, min-y๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด viewport์—์„œ ๋ณด์ด๋Š” ์˜์—ญ(ํ˜„์žฌ ์˜ˆ์‹œ์—์„œ์˜ width, height 300px ์˜์—ญ)์ด ๋™์ผํ•˜์ง€๋งŒ, svg์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ์˜์—ญ์€ ๋ณ€๊ฒฝ๋œ๋‹ค. viewBox๊ฐ€ "0 0 200 200"๋ถ€ํ„ฐ "1 1 200 200", "2 2 200 200" ์ด๋Ÿฐ ์‹์œผ๋กœ "100 100 200 200"๊นŒ์ง€ ๋ณ€๊ฒฝ๋˜๋ฉด, ์•„๋ž˜ ์˜์ƒ๊ณผ ๊ฐ™์ด ๋œ๋‹ค. ์˜์ƒ์€ ์œ„์˜ ์™ผ์ชฝ ์‚ฌ์ง„์˜ ๋นจ๊ฐ„ ๋„ค๋ชจ๊ฐ€ ์˜ค๋ฅธ์ชฝ ์‚ฌ์ง„์˜ ๋นจ๊ฐ„ ๋„ค๋ชจ ์œ„์น˜๋กœ ์ด๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ๋นจ๊ฐ„ ๋„ค๋ชจ๋Š” ์‹ค์ œ๋กœ ํ™”๋ฉด์—์„œ ๋ณด์ด๋Š” ๋ถ€๋ถ„์ด๋ฏ€๋กœ ์ •์ง€๋˜์–ด ์žˆ๋‹ค. ์ฆ‰, ๋นจ๊ฐ„ ๋„ค๋ชจ ํ™”๋ฉด์ด ๋™๋‚จ์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์€ ํŒŒ๋ž€ ์›์ด ๋ถ์„œ์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฏ€๋กœ ์˜์ƒ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚œ๋‹ค.

ํ™•๋Œ€, ์ถ•์†Œ ์˜ˆ์‹œ

viewBox์˜ width์™€ height๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด svg ์š”์†Œ๋“ค์„ ํ™•๋Œ€ํ•˜๊ฑฐ๋‚˜ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.

const App = () => (
  <div style={{ marginTop: '50px', marginLeft: '50px' }}>
    <div style={{ backgroundColor: 'yellow', width: '300px', height: '300px' }}>
      // ์ด ๋ถ€๋ถ„๋งŒ ๋ณ€๊ฒฝ viewBox="0 0 100 100" / viewBox="0 0 200 200" / viewBox="0 0 300 300"
      <svg viewBox="0 0 100 100">
        <circle cx="100" cy="100" r="100" fill="blue" />
      </svg>
    </div>
  </div>
);

export default App;

viewBox์˜ ์†์„ฑ๊ฐ’ ์ค‘ width์™€ height๋ฅผ ๊ฐ๊ฐ 100, 200, 300์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋”๋ผ๋„ viewport์—์„œ ๋ณด์ด๋Š” ์˜์—ญ(width, height 300px)์€ ๋™์ผํ•˜์ง€๋งŒ, svg ์˜์—ญ ์•ˆ์—์„œ์˜ ์š”์†Œ๋ฅผ ํ™•๋Œ€ํ•˜๊ฑฐ๋‚˜ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ๋‹ค.

728x90
๋ฐ˜์‘ํ˜•