Skip to content

Parsing

GiveSeo edited this page Dec 29, 2025 · 3 revisions

SVG Parsing ๊ตฌ์กฐ ๋ฐ ์ฒ˜๋ฆฌ

1. ๊ฐœ์š”

๋ณธ ๋ฌธ์„œ๋Š” ๋กœ๋ด‡ํŒ” ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ํ”„๋กœ์ ํŠธ plotto์—์„œ
SVG ํŒŒ์ผ์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„ ๋กœ๋ด‡ ๋™์ž‘ ์ƒ์„ฑ์— ํ•„์š”ํ•œ
๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” SVG ํŒŒ์‹ฑ ๊ณผ์ •์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

SVG ํŒŒ์‹ฑ์€ ์‹œ์Šคํ…œ ์ „์ฒด ๋™์ž‘ ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ฒซ ๋‹จ๊ณ„๋กœ,
์ด ๋‹จ๊ณ„์—์„œ ์ถ”์ถœ๋œ ๊ฒฝ๋กœ ์ •๋ณด๋Š” ์ดํ›„ ์ขŒํ‘œ ๋ณ€ํ™˜,
๊ธฐ๊ตฌํ•™ ๊ณ„์‚ฐ ๋ฐ plotto Path ์ƒ์„ฑ์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


2. SVG ํŒŒ์‹ฑ์˜ ์—ญํ• 

SVG๋Š” XML ๊ธฐ๋ฐ˜์˜ ๋ฒกํ„ฐ ์ด๋ฏธ์ง€ ํฌ๋งท์œผ๋กœ,
๋‹ค์–‘ํ•œ ์š”์†Œ์™€ ์†์„ฑ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋‚˜
plotto ์‹œ์Šคํ…œ์—์„œ๋Š” ๊ฒฝ๋กœ(Path) ์ •๋ณด๋งŒ์„ ์„ ํƒ์ ์œผ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

SVG ํŒŒ์‹ฑ ๋‹จ๊ณ„์˜ ์ฃผ์š” ๋ชฉ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. SVG ํŒŒ์ผ ๊ตฌ์กฐ ํ•ด์„
  2. ๊ฒฝ๋กœ(Path) ์š”์†Œ ์ถ”์ถœ
  3. ๊ฒฝ๋กœ ๋ช…๋ น์–ด๋ฅผ ์ขŒํ‘œ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜
  4. ํŽœ ์—…/๋‹ค์šด ์ƒํƒœ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„

3. ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

3.1. SVG ํŒŒ์ผ

  • ์ž…๋ ฅ ํ˜•์‹: .svg
  • ํŒŒ์‹ฑ ๋ฐฉ์‹: XML ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ ๋ถ„์„
  • ์ฃผ์š” ๋Œ€์ƒ ์š”์†Œ: <path> ํƒœ๊ทธ

3.2. ๊ฒฝ๋กœ(Path) ๋ฐ์ดํ„ฐ

SVG์˜ ๊ฒฝ๋กœ๋Š” d ์†์„ฑ์— ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜๋ฉฐ,
๋ณต์ˆ˜์˜ ๋ช…๋ น์–ด์™€ ์ขŒํ‘œ ์ •๋ณด๊ฐ€ ์ˆœ์ฐจ์ ์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

M 10 10 L 50 50 Z
// d ์†์„ฑ ๋ฌธ์ž์—ด ์˜ˆ์‹œ: "์ด๋™(M) โ†’ ์ง์„ (L) โ†’ ๋‹ซ๊ธฐ(Z)"
  1. ๊ธฐ๋ณธ ๊ตฌ์กฐ SVG <path> ํƒœ๊ทธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.

    • d ์†์„ฑ ๋‚ด๋ถ€๊ฐ€ ๊ณง path ๋ฐ์ดํ„ฐ
    • path ๋ฌธ์ž์—ด์€ ๋ช…๋ น์–ด + ์ˆซ์ž ์ขŒํ‘œ์˜ ๋ฐ˜๋ณต์œผ๋กœ ๊ตฌ์„ฑ ์˜ˆ์‹œ

    <path d="M 100 100 L 200 100 L 200 200 Z" />

    • ์ฃผ์š” PATH ๋ช…๋ น์–ด
      ๋ช…๋ น์–ด ์˜๋ฏธ ์ขŒํ‘œ ๊ฐœ์ˆ˜ ์˜ˆ์‹œ
      M Move to (์ด๋™) 2 M 100 100
      L Line to (์ง์„ ) 2 L 200 100
      H Horizontal line 1 H 250
      V Vertical line 1 V 250
      C Cubic Bezier curve 6 C 200 200 300 300 400 400
      Q Quadratic Bezier curve 4 Q 150 150 200 200
      S Cubic ๊ณก์„  ์—ฐ์†ํ˜• (์ด์ „ ์ œ์–ด์  ๋ฐ˜์‚ฌ) 4 S 300 300 400 400
      T Quadratic ๊ณก์„  ์—ฐ์†ํ˜• (์ด์ „ ์ œ์–ด์  ๋ฐ˜์‚ฌ) 2 T 200 200
      A Arc (์›ํ˜ธ) 7 A 50 50 0 0 1 200 200
      Z Close path (๋‹ซ๊ธฐ) 0 Z
    • ๋Œ€๋ฌธ์ž ๋ช…๋ น์–ด๋Š” ์ ˆ๋Œ€์ขŒํ‘œ(absolute), ์†Œ๋ฌธ์ž๋Š” ์ƒ๋Œ€์ขŒํ‘œ(relative)๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ: l 10 0 โ†’ ํ˜„์žฌ ์œ„์น˜ ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฅธ์ชฝ์œผ๋กœ 10 ์ด๋™

  2. ํŒŒ์‹ฑ ์›๋ฆฌ (๊ฐœ๋…) d ๋ฌธ์ž์—ด์„ ์ขŒํ‘œ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ธฐ๋ณธ ์ ˆ์ฐจ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    1. d ๋ฌธ์ž์—ด์„ ํ† ํฐํ™”(tokenize)
      • ๋ช…๋ น์–ด ๋ฌธ์ž(M/L/C/..) ์™€ ์ˆซ์ž๋ฅผ ๋ถ„๋ฆฌ
    2. ๋ช…๋ น์–ด๋ฅผ ๋งŒ๋‚˜๋ฉด, ๊ทธ ๋ช…๋ น์–ด๊ฐ€ ์š”๊ตฌํ•˜๋Š” ์ขŒํ‘œ ๊ฐฏ์ˆ˜๋งŒํผ ์ˆซ์ž๋ฅผ ์ฝ์Œ
    3. ์„ธ๊ทธ๋จผํŠธ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜์—ฌ ์ €์žฅ

      ์˜ˆ: { cmd: 'L', args: [200, 100] }

    4. ๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ๋„˜์–ด๊ฐ€๋ฉด์„œ ๋ฐ˜๋ณต

4. ํŒŒ์‹ฑ ๊ด€๋ จ ํ•จ์ˆ˜ (spine.js์—์„œ ์ •์˜๋จ)

extractPathPointsFromSvg(svgText, opts = {})

extractPathPointsFromSvg(svgText, opts={}) ํ•จ์ˆ˜๋Š” SVG ์ด๋ฏธ์ง€ ์†Œ์Šค (svgText)๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„, ๊ทธ ์•ˆ์— ํฌํ•จ๋œ ๋ชจ๋“  ๋„ํ˜•(graphic element)๋“ค์˜ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ผ์ • ๊ฐ„๊ฒฉ์˜ ์ ๋“ค์„ ์ถ”์ถœํ•˜๊ณ  ์ด๋ฅผ ์ขŒํ‘œ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ•ฉ๋‹ˆ๋‹ค.

  1. ๋งค๊ฐœ ๋ณ€์ˆ˜

    • ์ด ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

    • svgText : SVG ํŒŒ์ผ์˜ ์›๋ณธ ํ…์ŠคํŠธ ์ž…๋‹ˆ๋‹ค. SVG๋ฅผ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜๋ฉด, ํ•จ์ˆ˜๊ฐ€ ์ด๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ DOM ๊ตฌ์กฐ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    • opts : ๊ฒฝ๋กœ ์ถ”์ถœ๊ณผ ์ƒ˜ํ”Œ๋ง ์˜ต์…˜์„ ๋‹ด์€ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ {}์ด๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. opts ์˜ต์…˜

    ์˜ต์…˜ ์ด๋ฆ„ ํƒ€์ž… / ๊ธฐ๋ณธ๊ฐ’ ์„ค๋ช…
    sampleStep number / null ์ƒ˜ํ”Œ๋ง ๊ฐ„๊ฒฉ๋ฅผ ์ง์ ‘ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์ด ์ฃผ์–ด์ง€๋ฉด ๊ฐ ๊ฒฝ๋กœ๋ฅผ
    ๊ณ ์ •๋œ ๊ฐ„๊ฒฉ์œผ๋กœ ์ƒ˜ํ”Œ๋งํ•˜๋ฉฐ, samplesPerPath์„ค์ •์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.
    samplesPerPath number / 200 ๊ฐ ๋„ํ˜•์˜ ๊ฒฝ๋กœ๋ฅผ ๋ช‡ ๋“ฑ๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ์ง€์— ๋Œ€ํ•œ ๋Œ€๋žต์ ์ธ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.
    ๊ฒฝ๋กœ ์ „์ฒด๋ฅผ ์ด ๊ฐ’์œผ๋กœ ๋‚˜๋ˆ„์–ด ํ‰๊ท  ๊ฐ„๊ฒฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    maxStepClamp number / 2 ์ƒ˜ํ”Œ ๊ฐ„๊ฒฉ์˜ ์ƒํ•œ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๊ธด ๊ฒฝ๋กœ์˜ ๊ฒฝ์šฐ ๊ฐ„๊ฒฉ์ด
    ์ง€๋‚˜์น˜๊ฒŒ ์ปค์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’์œผ๋กœ, ๊ฐ„๊ฒฉ์ด ์ด๋ณด๋‹ค ํฌ๋‹ค๋ฉด
    ์ด ๊ฐ’์œผ๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.
    maxSamplesPerPath number / 3000 ๊ฐ ๊ฒฝ๋กœ๋‹น ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์ƒ˜ํ”Œ ์  ๊ฐฏ์ˆ˜์ž…๋‹ˆ๋‹ค.
    bridgeScale number / 1.0 path ๊ฐ„ ์ด๋™ ๊ฒฝ๋กœ์˜ ๋ฐ€๋„๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์Šค์ผ€์ผ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.

opts๋ฅผ ํ†ตํ•ด ๊ฒฝ๋กœ ์ƒ˜ํ”Œ๋ง ๊ฐ„๊ฒฉ๊ณผ ๋ฐ€๋„๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์ „๋ฐ˜์ ์ธ ์‹คํ–‰ ํ๋ฆ„

    1. SVG ํŒŒ์‹ฑ ๋ฐ ์ค€๋น„
      • ์ฃผ์–ด์ง„ svgText ๋ฌธ์ž์—ด์„ DOM Parser๋ฅผ ์ด์šฉํ•ด SVG DOM ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ๊ฐ€์ƒ์œผ๋กœ ์‚ฌ์šฉํ•  <svg>์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ SVG์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    2. ๋„ํ˜• ์š”์†Œ ์ˆ˜์ง‘
      • SVG ๋‚ด์˜ ๋ชจ๋“  ๊ทธ๋ฆฌ๊ธฐ ์š”์†Œ(<path>, <circle>, <rect>, <line>, <polygon>, <polyline> ๋“ฑ)์„ ์ฐพ๊ณ , ํ‘œ์‹œ ์†์„ฑ์ด ์ˆจ๊น€ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๊ฒƒ๋งŒ ์„ ๋ณ„ํ•ฉ๋‹ˆ๋‹ค.
      • ์ด๋•Œ ๊ฐ ์š”์†Œ๋งˆ๋‹ค ํ•ด๋‹น ์š”์†Œ์— ์ ์šฉ๋œ ๋ณ€ํš ํ–‰๋ ฌ(Transform)์„ ๊ณ„์‚ฐํ•˜์—ฌ ํ•จ๊ป˜ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
    3. ๋„ํ˜•๋ณ„ ๊ฒฝ๋กœ ๋ณ€ํ™˜
      • ์ˆ˜์ง‘ํ•œ ๊ฐ ๋„ํ˜•์„ SVG <path>์™€ ๊ฐ™์€ ํ˜•ํƒœ์ธ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ(d)๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋„ํ˜•(<rect>, <circle>๋“ฑ)์ธ ๊ฒฝ์šฐ์—” ๊ฒฝ๋กœ ๋ช…๋ น์œผ๋กœ ๋ฐ”๊พธ๊ณ , ์ด๋ฏธ <path>์ธ ๊ฒฝ์šฐ์—๋Š” ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋˜, ๋‚ด๋ถ€์— MOVE ๋ช…๋ น์ด ์žˆ์„ ๊ฒฝ์šฐ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    4. ๊ฒฝ๋กœ ์ƒ˜ํ”Œ๋ง
      • ๊ฐ ๊ฒฝ๋กœ์— ๋Œ€ํ•ด ์ผ์ • ๊ฐ„๊ฒฉ์œผ๋กœ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ getPointAtLength๋ฅผ ์ด์šฉํ•ด ์ขŒํ‘œ๋ฅผ ์ƒ˜ํ”Œ๋งํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ์ ์€ ํŽœ์„ ๋“ค์–ด์„œ ์ด๋™(pen = 0)ํ•˜๋ฉฐ, ์•„ํ›„ ์ ์€ ํŽœ์„ ๋Œ€๊ณ  ๊ทธ๋ฆฌ๋Š”(pen = 1)์ƒํƒœ๋กœ ์ƒ˜ํ”Œ๋งํ•˜์—ฌ localPoints ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.
    5. path ์‚ฌ์ด ๋ณด๊ฐ„
      • ์ด์ „ ๊ฒฝ๋กœ์˜ ๋งˆ์ง€๋ง‰ ์ ๊ณผ ๋‹ค์Œ ๊ฒฝ๋กœ ์ฒซ์  ์‚ฌ์ด์— ๊ฑฐ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, ํŽœ์„ ๋“  ์ƒํƒœ๋กœ ํ•ด๋‹น ๊ฐ„๊ฒฉ์„ ์ด๋™ํ•˜๋Š” ์ค‘๊ฐ„ ์ ์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.
    6. ํฌ์ธํŠธ ๋ฐ˜ํ™˜
      • ๋ชจ๋“  ๊ฒฝ๋กœ ์กฐ๊ฐ๋“ค์— ๋Œ€ํ•ด ์ƒ˜ํ”Œ๋ง์ด ๋๋‚˜๋ฉด, ์ด๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ points ๋ฐฐ์—ด์— ์ด์–ด๋ถ™์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ points์—๋Š” SVG์˜ ๋ชจ๋“  ๋„ํ˜•์„ ์ˆœํšŒํ•˜๋Š” ์ขŒํ‘œ ์ ๋“ค์ด ์ฐจ๋ก€๋Œ€๋กœ ๋‹ด๊ธฐ๋ฉฐ, ๊ฐ ์ ์€ ํŽœ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ์–ธ์ œ ์„ ์„ ๊ทธ๋ฆฌ๊ณ  ์–ธ์ œ ์ด๋™ํ•˜๋Š”์ง€ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
        ๋งˆ์ง€๋ง‰์œผ๋กœ ์ด points ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  2. ์‹คํ–‰ ๋™์ž‘

    1. SVG ํŒŒ์‹ฑ ๋ฐ ์ดˆ๊ธฐ ์„ค์ •

      DOM ๊ฐ์ฒด ์ƒ์„ฑ

      • ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ SVG ํ…์ŠคํŠธ๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ DOM ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
      • ์ด ๋•Œ, DOM ํŒŒ์„œ๋ฅผ์ด์šฉํ•˜์—ฌ ์‹ค์ œ SVG DOM ๊ฐ์ฒด๋กœ(doc)๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    2. ์ž„์‹œ SVG ์—˜๋ฆฌ๋จผํŠธ ์ƒ์„ฑ

      • ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ SVG ๊ฒฝ๋กœ ๊ธธ์ด ๋ฐ ์ขŒํ‘œ ๊ณ„์‚ฐ API๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ž„์‹œ <svg>์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ์ด์œ ๋Š”, SVG DOM์˜ getTotalLength() ๋ฐ getPointAtLength() ๋ฉ”์†Œ๋“œ๋Š” SVG ์š”์†Œ๊ฐ€ DOM์— ์žˆ์–ด์•ผ ์ •์ƒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
    3. ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™”

      • ์ตœ์ข…์œผ๋กœ ๋ฐ˜ํ™˜ํ•  ๋ฐฐ์—ด์ธ points๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.(point์—๋Š” {x, y, pen} ๊ฐ์ฒด๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์Œ“์ž…๋‹ˆ๋‹ค.) ๋˜ํ•œ, ์ด์ „ ๋„ํ˜•์˜ ๋งˆ์ง€๋ง‰์„ ์ €์žฅํ•˜๋Š” lastGlobalPt๋„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.(์ฒซ ๋„ํ˜• ํ›„์— ๊ฐ’์„ ์ฑ„์›๋‹ˆ๋‹ค.)
      • ์ด ๊ฐ’์€ path ๊ฐ„ ์ด๋™ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  3. ๋ณ€ํ™˜ ํ–‰๋ ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ

    SVG ์š”์†Œ๋“ค์€ transfrom ์†์„ฑ์„ ํ†ตํ•ด ํ‰ํ–‰์ด๋™, ํšŒ์ „, ์Šค์ผ€์ผ, ๊ธฐ์šธ์ด๊ธฐ(skew)๋“ฑ์˜ ๋ณ€ํ™˜์„ ๊ฐ€์ง€๋ฉฐ, <g> ๊ทธ๋ฃน์„ ์ด์šฉํ•ด์„œ ์ƒ์œ„ ๊ทธ๋ฃน๋“ค์˜ ๋ณ€ํ™˜์ด ๋ˆ„์  ์ ์šฉ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. spine ์ฝ”๋“œ์—์„  ์ด๋Ÿฌํ•œ ๋ณ€ํ™˜์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€ํ™˜ affine ํ–‰๋ ฌ์„ ์ด์šฉํ•ด์„œ ์ขŒํ‘œ๊ณ„ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋ฉฐ, ์ด ํ–‰๋ ฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

    1. I()

      • ํ•ญ๋“ฑ ํ–‰๋ ฌ{a:1, b:0, c:0, d:1, e:0, f:0}์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค(a=1, d=1์ด๊ณ  ๋‚˜๋จธ์ง€ 0์ธ ๋‹จ์œ„ํ–‰๋ ฌ)
    2. T(tx, ty)

      • ์ด๋™ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. x๋ฐฉํ–ฅ tx, y ๋ฐฉํ–ฅ ty๋งŒํผ ํ‰ํ–‰์ด๋™ ์‹œํ‚ค๋Š” ํ–‰๋ ฌ์ž…๋‹ˆ๋‹ค.
    3. S(sx, sy)

      • ์Šค์ผ€์ผ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. x์ถ• ๋ฐฉํ–ฅ sx๋ฐฐ y์ถ• ๋ฐฉํ–ฅ sy๋ฐฐ ํ™•๋Œ€/์ถ•์†Œ ํ•ฉ๋‹ˆ๋‹ค.
    4. R(deg)

      • ํšŒ์ „ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ๊ฐ๋„ ๋งŒํผ ์›์ ์„ ์ค‘์‹ฌ์œผ๋กœ ํšŒ์ „ํ•˜๋Š” ํ–‰๋ ฌ์ž…๋‹ˆ๋‹ค.
    5. KX(deg)

      • X์ถ• ๊ธฐ์ค€ ๊ธฐ์šธ์ด๊ธฐ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ๊ฐ๋„ ๋งŒํผ x์ถ• ๋ฐฉํ–ฅ์œผ๋กœ ๊ธฐ์šธ์ด๋Š” ๋ณ€ํ™˜์ž…๋‹ˆ๋‹ค.
    6. KY(deg)

      • Y์ถ• ๊ธฐ์ค€ ๊ธฐ์šธ์ด๊ธฐ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ๊ฐ๋„ ๋งŒํผ y์ถ• ๋ฐฉํ–ฅ์œผ๋กœ ๊ธฐ์šธ์ด๋Š” ๋ณ€ํ™˜์ž…๋‹ˆ๋‹ค.
    7. multiplyMatrices(m1, m2)

      • ๋‘๊ฐœ์˜ ํ–‰๋ ฌ m1,m2๋ฅผ ๋ฐ›์•„ ์ˆœ์„œ๋Œ€๋กœ ํ•ฉ์„ฑํ•œ ๊ฒฐ๊ณผ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    8. parseTransform(transformStr)

      • "translate(...)", "rotate(...)"์™€ ๊ฐ™์€ SVG transform ์†์„ฑ ๋ฌธ์ž์—ด์„ ์ฝ์–ด๋“ค์ด๊ณ , ๊ทธ ๋ณ€ํ™˜๋“ค์˜ ํ•ฉ์„ฑ ๊ฒฐ๊ณผ๋ฅผ ํ•˜๋‚˜์˜ ํ–‰๋ ฌ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

      ์˜ˆ๋ฅผ ๋“ค์–ด, transform="translate(10, 5) rotate(30)"์™€ ๊ฐ™์€ ๋ฌธ์ž์—ด์„ ํŒŒ์‹ฑํ•˜์—ฌ ํ•˜๋‚˜์˜ ํ–‰๋ ฌ ๊ฐ์ฒด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      • ์ •๊ทœ์‹์œผ๋กœ "์ด๋ฆ„" ํŒจํ„ด์„ ์ฐพ์•„์„œ ๊ฐ ๋ณ€ํ™˜๋ช…๋ น์„ ์ˆœ์„œ๋Œ€๋กœ ํ•ด์„ํ•˜๋ฉฐ, ์•ž์„œ ์ •์˜ํ•œ ํ–‰๋ ฌ ํ•จ์ˆ˜๋“ค์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.
      • ๊ฐ ๋ณ€ํ™˜ ํ–‰๋ ฌ m์„ ์ด์ „๊นŒ์ง€์˜ ๋ˆ„์  ํ–‰๋ ฌ M์— ๊ณฑ์…ˆํ•˜๋ฉฐ ํ•ฉ์„ฑํ•ด ๋‚˜๊ฐ‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด transform ๋ฌธ์ž์—ด์— ๋‚˜์—ด๋œ ๋ณ€ํ™˜์ด ์ˆœ์ฐจ ์ ์šฉ๋œ ์ตœ์ข… ํ–‰๋ ฌ M์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    9. getAccumulatedTransformInclusive(el)

      • <g>๊ทธ๋ฃน์— ์†ํ•œ svg๋Š” ์ž์‹ ์˜ transform์„ ํฌํ•จํ•˜์—ฌ ๋ถ€๋ชจ๋ฅผ ๋”ฐ๋ผ ์ตœ์ƒ์œ„ svg๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ๋ชจ๋“  ๋ณ€ํ™˜์„ ํ•ฉ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
        ์ด ํ•จ์ˆ˜๋Š” ์š”์†Œ ์ž์ฒด -> ๋ถ€๋ชจ์˜ ๋ณ€ํ™˜ .. ์ˆœ์œผ๋กœ ๋ชจ๋‘ ๊ณฑํ•œ ์ „์ฒด ๋ณ€ํ™˜ ํ–‰๋ ฌ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    10. getAccumulatedTransformParentsOnly(el)

      • <use> ์š”์†Œ๋ฅผ ๊ตฌํ•  ๋•Œ, ์ž๊ธฐ ์ž์‹ ์˜ transform์„ ์ ์šฉํ•˜๊ธฐ ์ „ ์ƒ์œ„ ์š”์†Œ์˜ transform์„ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
        ์ด ํ•จ์ˆ˜๋Š” ์š”์†Œ ์ž์ฒด์˜ ๋ณ€ํ™˜์„ ์ œ์™ธํ•˜๊ณ  ๋ถ€๋ชจ๋“ค์˜ ๋ˆ„์  ๋ณ€ํ™˜์„ ๊ตฌํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    11. shouldRender(el)

      • ์‹ค์ œ๋กœ ๊ทธ๋ ค์ง€์ง€ ์•Š๋Š” ์š”์†Œ๋ฅผ ์ œ์™ธํ•˜๋Š” ํ•„ํ„ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

      ์˜ˆ๋ฅผ ๋“ค์–ด, <defs>, display="none"์™€ ๊ฐ™์€ ์š”์†Œ๋Š” ๊ทธ๋ ค์ง€์ง€ ์•Š๋Š” ์š”์†Œ์ธ๋ฐ, ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค.

  4. ๋„ํ˜•์„ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ(path)๋กœ ๋ณ€ํ™˜

    SVG๋‚ด์—๋Š” path ์š”์†Œ ์™ธ์—๋„ <circle>,<rect> ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋ณธ ๋„ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ๋Š” ๋ชจ๋“  ๋„ํ˜•์„ path ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ํ•˜๋‚˜์˜ <path>์š”์†Œ์—๋„ moveTo(M)์œผ๋กœ pen์ด 0์ด ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”๋ฐ,๊ทธ path๋„ ๊ฐ๊ฐ ๋”ฐ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    1. splitSubpathsFixed(dAttr)
    • ์ด ํ•จ์ˆ˜๋Š” svg <path>์˜ d ์†์„ฑ ๊ฐ’์„ ํŒŒ์‹ฑํ•˜์—ฌ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์„œ๋ธŒ ํŒจ์Šค๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

      1. ์ž…๋ ฅ ๋ฌธ์ž์—ด ํ† ํฐํ™”

        • dAttr ๋ฌธ์ž์—ด์„ ์ •๊ทœํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํฐํ™” ํ•ด ํ•œ๊ธ€์ž์˜ ๋ช…๋ น ๋ฌธ์ž(M,I,C)์™€ ์ˆซ์ž ํ† ํฐ์œผ๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

        ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜ˆ๋ฅผ ๋“ค์–ด "M10 10 L20 20"๋ผ๋Š” ๋ฌธ์ž์—ด์€ ["M", "10", "10", "L", "20", "20"]์ฒ˜๋Ÿผ ๋ถ„ํ•ด๋ฉ๋‹ˆ๋‹ค.

        • ๋ช…๋ น์–ด ๋ณ„ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐœ์ˆ˜ ์ •์˜ : PARAMS ๋งต์— ๊ฐ ๋ช…๋ น๋งˆ๋‹ค ์š”๊ตฌ๋˜๋Š” ์ขŒํ‘œ ๊ฐ’์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด ๋‘ก๋‹ˆ๋‹ค. ์ด ๋งต์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ ๋ช…๋ น์—์„œ ๋ช‡๊ฐœ์˜ ํ† ํฐ์„ ์ฝ์–ด์•ผ ํ•˜๋Š”์ง€ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.
      2. ์ƒํƒœ ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™”

        • ๊ฒฝ๋กœ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡๊ฐ€์ง€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. cx, cy๋Š” ํ˜„์žฌ์ ์˜ ์ขŒํ‘œ๋กœ, ์ดˆ๊ธฐ๊ฐ’์€ (0,0)์ž…๋‹ˆ๋‹ค. sx,sy๋Š” ์„œ๋ธŒํŒจ์Šค์˜ ์‹œ์ž‘์ ์œผ๋กœ, ์ƒˆ๋กœ์šด ์„œ๋ธŒ ํŒจ์Šค๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ๊ฐฑ์‹ ๋˜์–ด Z ๋ช…๋ น ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. out๋ฐฐ์—ด์€ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋ผ ์„œ๋ธŒํŒจ์Šค ๋ฌธ์ž์—ด์„ ๋‹ด๋Š” ๋ฆฌ์ŠคํŠธ์ด๋ฉฐ, buf๋ฐฐ์—ด์€ ์„œ๋ธŒํŒจ์Šค์˜ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ž„์‹œ๋กœ ๋ˆ„์ ํ•˜๋Š” ๋ฒ„ํผ์ž…๋‹ˆ๋‹ค. hasSubPath๋Š” ํ˜„์žฌ ๋ˆ„์ ์ค‘์ธ ์„œ๋ธŒํŒจ์Šค๊ฐ€ ์žˆ๋Š”์ง€ ๋‚˜ํƒ€๋‚ด๋ฉฐ, lastCmd๋ณ€์ˆ˜์—์„œ๋Š” ์ง์ „์— ์ฒ˜๋ฆฌํ•œ ๋ช…๋ น์„ ์ €์žฅํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
      3. ํ—ฌํผ ํ•จ์ˆ˜ ์ •์˜

        • isCmd(token) : ์ฃผ์–ด์ง„ ํ† ํฐ์ด ๋ช…๋ น ๋ฌธ์ž์ธ์ง€(a ~ z ๋˜๋Š” A ~ Z) ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
        • flush() : ํ˜„์žฌ buf์— ๋ˆ„์ ๋œ ์„œ๋ธŒํŒจ์Šค ๋ฐ์ดํ„ฐ๋ฅผ out ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ํ›„์—๋Š” buf๋ฅผ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  hasSubpath๋ฅผ false๋กœ ๋ฆฌ์…‹ํ•˜์—ฌ ์ƒˆ๋กœ์šด ์„œ๋ธŒํŒจ์Šค๋ฅผ ์‹œ์ž‘ํ•  ์ค€๋น„๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
        • readNums(n) : ํ˜„์žฌ ํ† ํฐ ์œ„์น˜๋กœ๋ถ€ํ„ฐ ์ˆซ์ž n๊ฐœ๋ฅผ ์ฝ์–ด ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ ํ† ํฐ์„ ์ฝ์„ ์‹œ ์ „์—ญ๋ณ€์ˆ˜ i๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        • emit(cmd, nums) : ํ•˜๋‚˜์˜ SVG ๋ช…๋ น๊ณผ ํ•ด๋‹น ์ขŒํ‘œ ์ˆซ์ž๋“ค์„ buf์— ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
      4. ๋ฉ”์ธ ํŒŒ์‹ฑ ๋ฃจํ”„

        1. ํ† ํฐํ™” ๋œ ๋ช…๋ น ๋ชฉ๋ก์„ ์ˆœํšŒํ•˜๋ฉฐ ์‹ค์ œ ํŒŒ์‹ฑ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. isCmd(cmd)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ ํ† ํฐ์ด ๋ช…๋ น ๋ฌธ์ž์ธ์ง€ ํ™•์ธํ•˜๊ณ , ๋งž๋‹ค๋ฉด ์ด๋ฅผ lastCmd๋กœ ์„ค์ •ํ•˜๊ณ  i๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํ˜„์žฌ ํ† ํฐ์ด ์ˆซ์ž์ด๊ณ  lastCmd๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด ๋ช…๋ น์ด ๋ฐ˜๋ณต๋˜๋Š” ์ค‘ ์ด๋ฏ€๋กœ, cmd = lastCmd๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

        2. ๋ช…๋ น ์ข…๋ฅ˜์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ

          • ์‹๋ณ„๋œ cmd์— ๋”ฐ๋ผ ์„œ๋กœ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

            • (Z)์˜ ๊ฒฝ์šฐ : ์ด ๋ช…๋ น์˜ ๊ฒฝ์šฐ ์„œ๋ธŒํŒจ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ซ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. haSubpath = false๋ผ๋ฉด ๋‹ซ์„ ์„œ๋ธŒํŒจ์Šค๊ฐ€ ์—†๋Š” ๊ฒƒ ์ด๋ฏ€๋กœ ๋ฌด์‹œํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋ฉฐ, ์„œ๋ธŒํŒจ์Šค๊ฐ€ ์ง„ํ–‰์ค‘์ธ ์ค‘์ด๋ผ๋ฉด, emit("Z")๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ buf์— "Z"๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ์ ์„ ํ•ด๋‹น ์„œ๋ธŒํŒจ์Šค์˜ ์‹œ์ž‘์ ์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค (cx = sx; cy = sy;).
            • (M/m)์˜ ๊ฒฝ์šฐ : moveto ๋ช…๋ น์„ ๋งŒ๋‚˜๋ฉด ์ƒˆ๋กœ์šด ์„œ๋ธŒํŒจ์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. hasSubpath = true๋ผ๋ฉด flush()๋ฅผ ํ˜ธ์ถœํ•ด ์ด์ „ ์„œ๋ธŒํŒจ์Šค๋ฅผ ๋๋‚ธ ํ›„, ์ƒˆ ์„œ๋ธŒํŒจ์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ readNums(2)์„ ํ†ตํ•ด ๋‘ ์ˆซ์ž๋ฅผ ์ฝ์–ด ์ƒˆ๋กœ์šด ์ด๋™ ์ขŒํ‘œ(x,y)๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
          • ์ขŒํ‘œ๋ฅผ ์–ป์—ˆ๋‹ค๋ฉด, M(์ ˆ๋Œ€ ์ขŒํ‘œ ์ด๋™)๊ณผ m(์ƒ๋Œ€ ์ขŒํ‘œ ์ด๋™)์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

            • m์˜ ๊ฒฝ์šฐ : ํ˜„์žฌ์ (cx, cy)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์˜คํ”„์…‹์„ ์ ์šฉํ•ด ์ ˆ๋Œ€ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. mx = cx + x; my = cy + y๋กœ ์ƒˆ ์ ˆ๋Œ€ ์œ„์น˜๋ฅผ ๊ตฌํ•œ ๋’ค, ์ด๋ฅผ ์‹ค์ œ ์ด๋™ ๋ช…๋ น์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
            • M์˜ ๊ฒฝ์šฐ : ์ฝ์€ ์ขŒํ‘œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

          ์ดํ›„ emit("M", [mx, my])๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ์„œ๋ธŒ ํŒจ์Šค ์‹œ์ž‘์„ M ๋ช…๋ น์œผ๋กœ buf์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ƒˆ๋กœ์šด ์„œ๋ธŒํŒจ์Šค๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์œผ๋ฏ€๋กœ hasSubpath๋ฅผ true๋กœ ์„ค์ •ํ•˜๊ณ , ํ˜„์žฌ์  cx, cy๋ฅผ (mx, my)๋กœ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ sx, sy์— ์ด ์ขŒํ‘œ๋ฅผ ์ €์žฅํ•˜์—ฌ ์„œ๋ธŒํŒจ์Šค ์‹œ์ž‘์ ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

          • LineTo ์ฒ˜๋ฆฌ
            • moveto ๋ช…๋ น ๋’ค์— ์ถ”๊ฐ€ ์ขŒํ‘œ ์Œ๋“ค์ด ๋‚˜์—ด๋˜๋ฉด ์ž๋™์œผ๋กœ ์—ฐ์†๋œ ์ง์„  ๊ทธ๋ฆฌ๊ธฐ(line-to) ๋ช…๋ น๋“ค๋กœ ํ•ด์„๋ฉ๋‹ˆ๋‹ค.
            • ์ด๋ฅผ ์ฝ”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ฒซ ์ขŒํ‘œ ์Œ ์ฒ˜๋ฆฌ ์ดํ›„ ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ๋‹ค์Œ ๋„ํฐ์„ ํ™•์ธํ•˜์—ฌ ์ˆซ์ž๋ผ๋ฉด ๋™์ผ ์„œ๋ธŒํŒจ์Šค ๋‚ด์˜ ์ถ”๊ฐ€ ์„ ๊ทธ๋ฆฌ๊ธฐ๋กœ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.
            • ์ฒซ ์ขŒํ‘œ ์Œ ์ฒ˜๋ฆฌ์—์„œ ์›๋ณธ ๋ช…๋ น์ด m(์ƒ๋Œ€)์˜€๋‹ค๋ฉด, ์„  ๋ช…๋ น์€ l๋กœ ํŒ๋‹จํ•˜๊ณ , M(์ ˆ๋Œ€)์˜€๋‹ค๋ฉด ์„  ๋ช…๋ น์„ L๋กœ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.
            • moveto ๋ฐ LineTo ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด continue๋ฅผ ํ†ตํ•ด M/m ๋ถ„๊ธฐ๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
          • ๊ทธ์™ธ์˜ ๋ช…๋ น(L,H,V,C ๋“ฑ)
            • ๋‚˜๋จธ์ง€ ๊ทธ๋ฆฌ๊ธฐ ๋ช…๋ น์— ๋Œ€ํ•ด์„  ํ•ด๋‹น ๋ช…๋ น์ด ํ•„์š”๋กœ ํ•˜๋Š” ์ˆซ์ž ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ PARAMS์—์„œ ๊ตฌํ•œ ๋’ค, ๋‚ด๋ถ€ ๋ฐ˜๋ณต๋ฌธ์„ ํ†ตํ•ด ๋ช…๋ น๊ณผ ๊ด€๋ จ๋œ ์ˆซ์ž๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํ•˜๋‚˜์˜ ์ขŒํ‘œ ์„ธํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„์—” (cx,cy)๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.
            • ๊ฐ ์„ธํŠธ ์ฒ˜๋ฆฌ ํ›„์—๋Š” hasSubpath = true๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ฉ”์ธ ๋ฃจํ”„๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์ข…๋ฃŒ ํ›„์—๋Š” buf์— ๋‚จ์•„์žˆ๋Š” ์„œ๋ธŒ ํŒจ์Šค ๋ฐ์ดํ„ฐ๋ฅผ flush()๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•˜์—ฌ out์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    • ์ตœ์ข…์ ์œผ๋กœ ๊ฐ ์›์†Œ๊ฐ€ ๋…๋ฆฝ๋œ ์„œ๋ธŒํŒจ์Šค ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์ธ out ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด, ์ž…๋ ฅ dAttr๊ฐ€ "M0 0 L10 0 L10 10 Z M20 20 L30 30" ์˜€๋‹ค๋ฉด, ์ด ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์„œ๋ธŒํŒจ์Šค๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค: - ["M 0 0 L 10 0 L 10 10 Z", "M 20 20 L 30 30"]

    1. circleToPathLocal(cx,cr,y)

      • ์›์€ path๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ๋‘๊ฐœ์˜ ํ˜ธ๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค. svg path์˜ A(์›ํ˜ธ) ๋ช…๋ น์„ ์ด์šฉํ•˜์—ฌ ๋‘๊ฐœ์˜ ํ˜ธ๋กœ ์›์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. <circle>์š”์†Œ์˜ cx, cy, r ์†์„ฑ์„ ์ฝ์–ด ์ค‘์‹ฌ ์ขŒํ‘œ์™€ ๋ฐ˜์ง€๋ฆ„์„ ์–ป์Šต๋‹ˆ๋‹ค.
      • ์›์˜ ๊ฐ€์žฅ ์™ผ์ชฝ์ ์—์„œ ์‹œ์ž‘(M x0,y ํ˜•์‹, x0 = cx - r)ํ•˜์—ฌ ์šฐ์ธก์œผ๋กœ ๋ฐ˜์›์„ ๊ทธ๋ฆฌ๋Š” ์•„ํฌ ๋ช…๋ น A๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋‹ค์‹œ ์ขŒ์ธก์œผ๋กœ ๋Œ์•„์˜ค๋Š” ๋‘ ๋ฒˆ์งธ ์•„ํฌ ๋ช…๋ น์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋‹ซ๋Š” ์‹์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์— Z๋กœ ๊ฒฝ๋กœ๋ฅผ ๋‹ซ์•„ ์™„์ „ํ•œ ์›์„ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.
      • ์ด ๋ฐฉ์‹์œผ๋กœ ์›์„ SVG path์˜ A ๋ช…๋ น์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    2. ellipseToPathLocal(cx, cy, rx, ry)

      • ํƒ€์›์€ 4๊ฐœ์˜ ๋ฒ ์ง€์–ด ๊ณก์„ ์œผ๋กœ ๊ทผ์‚ฌํ•˜์—ฌ ๊ฒฝ๋กœ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      • ๊ตฌํ˜„์—์„œ ์‚ฌ์šฉ๋œ K = 0.5522...๋Š” ์›์ด๋‚˜ ํƒ€์›์„ 4๊ฐœ์˜ ๊ณก์„ ์œผ๋กœ ๊ทผ์‚ฌํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์นดํŒŒ(kappa) ์ƒ์ˆ˜๋กœ, ์ด ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ ์ง€์–ด ๊ณก์„ ์˜ ์ค‘์ ์ด ์‹ค์ œ ์›์— ๊ฑฐ์˜ ๊ทผ์ ‘ํ•˜๋„๋ก ์ œ์–ด์ ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

      • ์ด ํ•จ์ˆ˜๋Š” ์šฐ์„  ์ฃผ์–ด์ง„ rotation ๊ฐ’์„ ๊ณ ๋ คํ•ด ๋ฏธ๋ฆฌ ํšŒ์ „ ๋ณ€ํ™˜์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํƒ€์›์˜ 4๊ฐœ์˜ ์ฃผ์š” ์ ๊ณผ ๋ฒ ์ง€์–ด ์ œ์–ด ์ ๋„ ํšŒ์ „ํ•˜์—ฌ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

      • ๊ทธ๋Ÿฐ ๋’ค์—, ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. M ๋ช…๋ น์œผ๋กœ ์‹œ์ž‘ํ•˜์—ฌ left ์ ์œผ๋กœ ์ด๋™ํ•˜๊ณ , ์ด์–ด์„œ C ํ๋น… ๋ฒ ์ง€์–ด ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ top ์ ๊นŒ์ง€ ๊ณก์„ ์„ ๊ทธ๋ฆฌ๋„๋ก ์ œ์–ด์  c1, c2๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

      • ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์—ฐ์†๋œ 3๊ฐœ์˜ C ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ top->right, right->bottom, bottom->left๋กœ ์ด์–ด์ง€๋Š” ๊ณก์„ ๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์— Z๋กœ ๋‹ซ์•„์„œ ํ•˜๋‚˜์˜ ์—ฐ์†๋œ ํŒจ์Šค๋กœ ํƒ€์›์„ ๊ทผ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    3. rectToPathLocal(x, y, width, height, rx, ry)

      • ์‚ฌ๊ฐํ˜•์€ rx, ry(๋ชจ์„œ๋ฆฌ ๋ฐ˜๊ฒฝ)์— ๋”ฐ๋ผ ๋‘๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

      ๊ณตํ†ต ์ฒ˜๋ฆฌ

      • x, y, width, height, rx, ry ์†์„ฑ์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ rx, ry๊ฐ€ ์—†์œผ๋ฉด 0์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ํ•˜๋‚˜๋งŒ ์ง€์ •๋œ ๊ฒฝ์šฐ ๋‘ ๊ฐ’์„ ๋™์ผํ•˜๊ฒŒ ๋งž์ถฅ๋‹ˆ๋‹ค. ๋˜ํ•œ, rx > width / 2 ์ด๋ฉด width / 2๋กœ ์ œํ•œํ•˜๊ณ , ry > height / 2 ์ด๋ฉด height / 2๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

      ๋ชจ์„œ๋ฆฌ๊ฐ€ ๋‘ฅ๊ทผ ์‚ฌ๊ฐํ˜•(rx > 0 && ry > 0)

      • rx > 0 ์ด๊ณ  ry > 0 ์ธ ๊ฒฝ์šฐ, ๊ฐ ๋ชจ์„œ๋ฆฌ๋ฅผ ํƒ€์› 1/4 ํ˜ธ์— ๊ทผ์‚ฌํ•œ ๋ฒ ์ง€์–ด ๊ณก์„ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
      • ์›์˜ 1/4์„ ํ๋น… ๋ฒ ์ง€์–ด๋กœ ๊ทผ์‚ฌํ•˜๊ธฐ ์œ„ํ•ด K = 0.5522... ์ƒ์ˆ˜(์นดํŒŒ ์ƒ์ˆ˜)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ฐ ๋ชจ์„œ๋ฆฌ์— ๋Œ€ํ•ด ox = rx _ K, oy = ry _ K ๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
      • ์ง์„ (L)๊ณผ ํ๋น… ๋ฒ ์ง€์–ด(C) ๋ช…๋ น์„ ์กฐํ•ฉํ•˜์—ฌ ๋„ค ๋ชจ์„œ๋ฆฌ๋ฅผ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ๋„ค ๋ชจ์„œ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•œ ํ›„ Z ๋ช…๋ น์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค.

      ์ด ๊ฒฐ๊ณผ, ์›๋ž˜ rect์˜ ๋‘ฅ๊ทผ ๋ชจ์„œ๋ฆฌ๋ฅผ rx, ry ๋ฐ˜์ง€๋ฆ„์˜ ํƒ€์› ํ˜ธ์— ๊ทผ์ ‘ํ•œ path๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      ๋ชจ์„œ๋ฆฌ๊ฐ€ ์ง๊ฐ์ธ ์‚ฌ๊ฐํ˜•(rx <=1e-9 && ry <=1e-9)

      • M x,y๋กœ ์‹œ์ž‘ํ•œ ๋’ค, ์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ ๋„ค ๊ฐœ์˜ L ๋ช…๋ น์„ ์‚ฌ์šฉํ•ด ๊ผญ์ง“์ ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
        ๋งˆ์ง€๋ง‰์— Z ๋ช…๋ น์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ๋‹ซ์•„ ๋‹จ์ˆœ ์‚ฌ๊ฐํ˜• path๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    4. lineToPathLocal(x1, y1, x2, y2)

      • <line> ์š”์†Œ๋Š” ์‹œ์ž‘์  (x1, y1)๊ณผ ๋์  (x2, y2)์„ ๊ฐ€์ง€๋Š” ๋‹จ์ˆœ ์„ ๋ถ„์ž…๋‹ˆ๋‹ค.

      M x1,y1 โ†’ L x2,y2 ํ˜•ํƒœ์˜ path๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    5. polyToPathLocal(pointsStr, close)

      • <polygon>, <polyline> ์š”์†Œ์˜ points ์†์„ฑ์„ ํŒŒ์‹ฑํ•˜์—ฌ ์ขŒํ‘œ ๋ฐฐ์—ด์„ ์–ป์Šต๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ ์ ์„ M ๋ช…๋ น์œผ๋กœ ์„ค์ •ํ•˜๋ฉฐ, ์ดํ›„ ๊ฐ ์ ๋งˆ๋‹ค L ๋ช…๋ น์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ง์„ ์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์— close๊ฐ€ true์ด๋ฉด(<polygon>์˜ ๊ฒฝ์šฐ) Z๋ฅผ ๋ถ™์—ฌ ๋‹ซ๊ณ , false ์ด๋ฉด(<polyline>์˜ ๊ฒฝ์šฐ) ์—ด๋ฆฐ ์ฑ„๋กœ ๋‘ก๋‹ˆ๋‹ค.

      ๊ฒฐ๊ณผ์ ์œผ๋กœ polygon / polyline๋„ path ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

    ์œ„์˜ ๊ฐ ๋„ํ˜• ๋ณ€ํ™˜ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด SVG ๊ธฐ๋ณธ ๋„ํ˜• ์š”์†Œ๋“ค์ด ๋ชจ๋‘ ๊ฒฝ๋กœ ๋ฌธ์ž์—ด(path)๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์›๋ณธ์ด path์ธ ๊ฒฝ์šฐ์—๋Š” splitSubpathsํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋‰˜์–ด ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(path ์•ˆ์— M์ด ๋‘๋ฒˆ ์ด์ƒ ์žˆ๋Š” ๊ฒฝ์šฐ.)

  5. <use> ์š”์†Œ ์ฒ˜๋ฆฌ

    • svg์—์„œ๋Š” <use xlink:href="#id">์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์‚ฌ์ „์— ์ •์˜๋œ ๋„ํ˜•์„ ๋ณต์‚ฌํ•˜์—ฌ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • <use>๋Š” xlink:href ๋˜๋Š” ์ตœ๊ทผ href ์†์„ฑ์œผ๋กœ ์ฐธ์กฐ ๋Œ€์ƒ์˜ id๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ x, y ๋“ฑ์˜ ์†์„ฑ์œผ๋กœ ์œ„์น˜๋ฅผ ์กฐ์ •ํ•˜๊ฑฐ๋‚˜ ์ž์ฒด์ ์œผ๋กœ transform์„ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    • extractPathPointsFromSvg() ํ•จ์ˆ˜์—์„  resolveUseElement(useEl)๊ฐ€ ๊ทธ ์ฒ˜๋ฆฌ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋””.
    1. resolveUseElement(useEl) ํ•จ์ˆ˜

      • ์ด ํ•จ์ˆ˜๋Š” <use> ์š”์†Œ์˜ ์›๋ณธ ๋„ํ˜• + ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ๋ณ€ํ™˜์„ ๋ชจ๋‘ ํ•ด์„ํ•ด ํ•˜๋‚˜์˜ ์‹ค์ œ ๋„ํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•œ ๋’ค ๋ Œ๋”๋ง ๋Œ€์ƒ์— ํฌํ•จ์‹œํ‚ค๋Š” ๊ณผ์ •์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค.

      • <use>์˜ href ์†์„ฑ์—์„œ ์ฐธ์กฐ ๋Œ€์ƒ ์ถ”์ถœ

        • <use> ์š”์†Œ์˜ href ๋˜๋Š” xlink:href ๊ฐ’์„ ์ฝ์–ด #id ํ˜•ํƒœ์˜ ์ฐธ์กฐ ๋Œ€์ƒ id๋ฅผ ์ถ”์ถœํ•˜๊ณ , svgRoot.querySelector('#id')๋กœ ์›๋ณธ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

        • ์›๋ณธ ์š”์†Œ ์กด์žฌ ํ™•์ธ : ๋งŒ์•ฝ ์ฐธ์กฐ๋œ id์— ํ•ด๋‹น ์›๋ณธ ์š”์†Œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด, ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

      • <use>์š”์†Œ์˜ x, y ์†์„ฑ์„ ํ‰ํ–‰์ด๋™ ํ–‰๋ ฌ๋กœ ๋ณ€ํ™˜

        • <use> ์š”์†Œ์˜ x,y ์†์„ฑ์„ ์ฝ์–ด (x,y)๋กœ ์ด๋™์‹œํ‚ค๋Š” ํ‰ํ–‰์ด๋™ ํ–‰๋ ฌ T๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
      • ๋ณ€ํ™˜ ํ–‰๋ ฌ ์ˆ˜์ง‘

        • <use>๋กœ ์ธํ•ด ์ ์šฉ๋˜๋Š” ๋ชจ๋“  ๋ณ€ํ™˜์„ ๋‹ค์Œ ๋„ค๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค.
        ๊ตฌ๋ถ„ ์„ค๋ช…
        ๋ถ€๋ชจ ๊ทธ๋ฃน ๋ณ€ํ™˜ <use> ์š”์†Œ์˜ ์ƒ์œ„ <g> ์š”์†Œ๋“ค์— ์ ์šฉ๋œ transform์„ ๋ˆ„์ ํ•œ ๋ณ€ํ™˜ ํ–‰๋ ฌ
        <use> ์ž์ฒด ๋ณ€ํ™˜ <use> ์š”์†Œ์— ์ง์ ‘ ์ง€์ •๋œ transform ์†์„ฑ์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ณ€ํ™˜ ํ–‰๋ ฌ
        <use> ์œ„์น˜ ์ด๋™ <use> ์š”์†Œ์˜ x, y ์†์„ฑ์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ํ‰ํ–‰์ด๋™(translate) ํ–‰๋ ฌ
        ์›๋ณธ ์š”์†Œ ๋ณ€ํ™˜ <use>๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์›๋ณธ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ(ref)์— ์ ์šฉ๋œ transform ์†์„ฑ์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ณ€ํ™˜ ํ–‰๋ ฌ
      • ์ตœ์ข… ๋ณ€ํ™˜ ํ–‰๋ ฌ ํ•ฉ์„ฑ

        • ์ˆ˜์ง‘๋œ ๋ณ€ํ™˜ ํ–‰๋ ฌ์„ ๋ถ€๋ชจ -> <use> ์ž์ฒด ๋ณ€ํ™˜ -> <use> ์œ„์น˜ ์ด๋™ -> ์›๋ณธ ์š”์†Œ ๋ณ€ํ™˜ ์ˆœ์œผ๋กœ ์ ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ํ–‰๋ ฌ๋กœ ํ•ฉ์„ฑํ•ฉ๋‹ˆ๋‹ค.
      • <use> ํ•ด์„ ๊ฒฐ๊ณผ ๊ฐ์ฒด ์ƒ์„ฑ

        • ํ•ด์„๋œ <use> ์š”์†Œ์— ๋Œ€ํ•ด ๋‹ค์Œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
      • ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ๋Š” { element: ref, transform: M, tagName: ref.tagName.toLowerCase() } ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

    • ์š”์•ฝํ•˜๋ฉด, <use> ์š”์†Œ๋Š” ๋‚ด๋ถ€์—์„œ ์ฐธ์กฐ๋œ ๋„ํ˜•์„ ์ฐพ์•„ ๋ณต์ œํ•œ ๋’ค ์œ„์น˜/๋ณ€ํ™˜์„ ์ ์šฉํ•ด์ฃผ๋Š” ํ˜•ํƒœ๋กœ ๋‹ค๋ฃจ๋ฉฐ, ๊ทธ๋ ‡๊ฒŒ ๋ณ€ํ™˜๋œ ๋„ํ˜•์€ ์‹ค์ œ <path>๋‚˜ <circle> ๋“ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ดํ›„ ๊ณผ์ •(๊ฒฝ๋กœ ๋ณ€ํ™˜, ์ƒ˜ํ”Œ๋ง ๋“ฑ)์„ ๊ฑฐ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  6. ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ

    • SVG ๋‚ด๋ถ€์˜ ๊ฐ ๋„ํ˜• ์š”์†Œ๋“ค์„ ์ˆ˜์ง‘ํ•˜๊ณ , ๊ฐ ์š”์†Œ ๋ณ„๋กœ ๊ฒฝ๋กœ ์ •๋ณด๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ํฌ๊ฒŒ ๋‘๊ฐ€์ง€ ์š”์†Œ๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ, ์ง์ ‘์ ์ธ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ(path์™€ ๊ธฐ๋ณธ ๋„ํ˜•)์™€ <use>์ฐธ๊ณ  ์š”์†Œ ์ž…๋‹ˆ๋‹ค.
    • ๊ธฐ๋ณธ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ ์ฒ˜๋ฆฌ
      • svgRoot.querySelectorAll("path, circle, rect, ellipse, line, polygon, polyline")๋ฅผ ์ด์šฉํ•˜์—ฌ svg ๋‚ด ๋ชจ๋“  ๊ธฐ๋ณธ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
      • ์ด ๋•Œ, shouldRender(el)๋ฅผ ํ†ตํ•ด ๋ Œ๋”๋ง ๋Œ€์ƒ์ธ์ง€ ํ™•์ธํ•˜๊ณ , ๋งž๋‹ค๋ฉด allElements ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์ถ”๊ฐ€ ์‹œ์— ์š”์†Œ์˜ ์ •๋ณด๋„ ๊ฐ™์ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    allElements.push({
    element: el, // ์š”์†Œ
    transform: getAccumulatedTransformInclusive(el), // ๋ˆ„์  ๋ณ€ํ™˜ ํ–‰๋ ฌ
    tagName: el.tagName.toLowerCase(), // ํƒœ๊ทธ ๋ช…
    });
    • <use> ์š”์†Œ ์ถ”๊ฐ€
      • svgRoot.querySelectorAll("use")๋ฅผ ํ†ตํ•ด ๋ชจ๋“  <use>์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ shouldRender๋กœ ํ‘œ์‹œ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•œ ๋’ค, ํ‘œ์‹œ ๋Œ€์ƒ์ด๋ฉด ์œ„์—์„œ ์„ค๋ช…ํ•œ resolveUseElement(useEl)๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. resolveUseElement๊ฐ€ ์œ ํšจํ•œ ๊ฐ์ฒด(์ฐธ์กฐ ์„ฑ๊ณต)๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ์ด๋ฅผ allElements์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    ์ด ๊ณผ์ •๋“ค์„ ๊ฑฐ์น˜๋ฉด allElements ๋ฐฐ์—ด์—๋Š” SVG์— ์‹ค์ œ ๊ทธ๋ ค์งˆ ๋ชจ๋“  ๋„ํ˜• ์š”์†Œ๋“ค์ด ์ถ”๊ฐ€๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  7. ๊ฒฝ๋กœ ๊ธธ์ด ๊ณ„์‚ฐ

    • ๋„ํ˜•๋ณ„๋กœ ์–ป์€ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. allElements ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    ๊ฐ ๊ฒฝ๋กœ์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋Š” ์ด์œ ๋Š”, ์  ์ƒ˜ํ”Œ๋ง ๊ฐ„๊ฒฉ์„ ๊ฒฐ์ •ํ•˜๊ณ  ์ตœ์ ํ™” ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.

    • ๊ฐ์ฒด ๊ฐ’ ๊บผ๋‚ด๊ธฐ ๋ฐ ๋ฐฐ์—ด ์ดˆ๊ฐ€ํ™”

      • ๊ฐ์ฒด์—์„œ element, tagName, transform์„ ๊บผ๋ƒ…๋‹ˆ๋‹ค. ์ดํ›„ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ dList ๋ฐฐ์—ด๋„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ตœ์ข… ๊ฒฝ๋กœ ๊ฐ์ฒด๋ฅผ ๋‹ด์„ prepared ๋ฐฐ์—ด๋„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

      ์ดํ›„ ์š”์†Œ์˜ ์ข…๋ฅ˜๋ณ„๋กœ ๋ถ„๊ธฐํ•˜์—ฌ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

    • ์š”์†Œ ๋ณ„ ๋ถ„๊ธฐ

      • path ์ผ ๊ฒฝ์šฐ : ์ด๋ฏธ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์š”์†Œ๋กœ, ๋ฌธ์ž์—ด์„ ๊ฐ€์ ธ ์˜จ ๋’ค, splitSubpathsFixed()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•„์š” ์‹œ์— ์—ฌ๋Ÿฌ ํ•˜์œ„ ๊ฒฝ๋กœ๋กœ ๋ถ„ํ• ํ•ฉ๋‹ˆ๋‹ค. splitSubpathsFixed()์˜ ๊ฒฐ๊ณผ๋ฅผ dList ๋ฐฐ์—ด์— ๋‹ด์Šต๋‹ˆ๋‹ค.
      • circle์ธ ๊ฒฝ์šฐ : circleToPathLocal(cx, cy, r)์„ ํ˜ธ์ถœํ•˜์—ฌ ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ dList์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
      • ellipse์ธ ๊ฒฝ์šฐ : ellipseToPathLocal(cx, cy, rx, ry, rotation)์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ rotation ๊ฐ๋„๋Š” ํŠน๋ณ„ํžˆ ๊ณ„์‚ฐํ•˜๋Š”๋ฐ, transformMatrix๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ํ–‰๋ ฌ๋กœ๋ถ€ํ„ฐ ํšŒ์ „ ์„ฑ๋ถ„์„ ์ถ”์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ๋Š” ํ–‰๋ ฌ m์˜ a,b ๊ฐ’์„ ์ด์šฉํ•ด rotation = atan2(m.b, m.a) * (180/Math.PI)๋กœ ๊ฐ๋„๋ฅผ ์–ป๋Š”๋ฐ, ์ด๋Š” ํ–‰๋ ฌ์˜ ๋ณ€ํ˜•์ด ์ˆœ์ˆ˜ ํšŒ์ „/์Šค์ผ€์ผ ์กฐํ•ฉ์ผ ๋•Œ ๊ทธ ํšŒ์ „ ๊ฐ๋„๋ฅผ ๊ทผ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
      • rect์ธ ๊ฒฝ์šฐ : rectToPathLocal(x, y, width, height, rx, ry) ํ˜ธ์ถœ ๊ฒฐ๊ณผ ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ dList์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
      • line์ธ ๊ฒฝ์šฐ : lineToPathLocal(x1, y1, x2, y2) ๊ฒฐ๊ณผ ๋ฌธ์ž์—ด์„ ๋„ฃ์Šต๋‹ˆ๋‹ค.
      • polygon / polyline ์ธ ๊ฒฝ์šฐ : polyToPathLocal(points, true) / polyToPathLocal(points, false) ํ˜ธ์ถœํžˆ์—ฌ ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ dList์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์„œ dList์— ํ•œ ์š”์†Œ๋กœ๋ถ€ํ„ฐ ์œ ๋ž˜๋œ ํ•˜๋‚˜ ์ด์ƒ์˜ d ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
    • ๊ฒฝ๋กœ ๊ธธ์ด ์ธก์ •

      • dList๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ํ•˜๋‚˜์˜ ์ž„์‹œ <path> ์š”์†Œ pathEl๋ฅผ ์ƒ์„ฑํ•˜๊ณ  pathEl.setAttribute("d", dAttr);๋กœ ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
      • ๋งŒ์•ฝ ํ•ด๋‹น ์š”์†Œ์— transformMatrix๊ฐ€ ์žˆ๋‹ค๋ฉด ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ pathEl.getTotalLength()๋ฅผ ํ†ตํ•ด ์ „์ฒด ๊ธธ์ด๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๊ธธ์ด๋ฅผ ์–ป์—ˆ๋‹ค๋ฉด pathEl.getTotalLength()๋กœ ์ž„์‹œ path๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , prepared ๋ฆฌ์ŠคํŠธ์— ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. prepared.push({ dAttr, transformMatrix, length: L });

    ์ด์ œ prepared์— ๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ์™€ ๊ธธ์ด๊ฐ€ ๋ชจ์ด๊ฒŒ ๋˜๊ณ , ์ด ์ •๋ณด์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ์  ์ƒ˜ํ”Œ๋ง์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  8. ์  ์ƒ˜ํ”Œ๋ง

    • prepared์— ๋‹ด๊ธด ๊ฐ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ ์ ์„ ์ฐ์–ด points ๋ฐฐ์—ด์— ๋ˆ„์ ํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ๋ง ๋‹จ์œ„๋Š” opts์™€ ๊ฒฝ๋กœ์˜ ๊ธธ์ด์— ์˜ํ•ด ๊ฒฐ์ •๋˜๊ณ , ๊ฐ ๋„ํ˜•์˜ bridge ๋ถ€๋ถ„๋„ ํ•จ๊ป˜ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • ์ƒ˜ํ”Œ๋ง ๋ฃจํ”„ ์‹œ์ž‘

    • prepared ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ๊ฐ ํ•ญ๋ชฉ(item)์— ๋Œ€ํ•ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์šฐ์„  ์ž„์‹œ <path>์š”์†Œ pathEl๋ฅผ ์ƒ์„ฑํ•˜๊ณ  dAttr๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์ž„์‹œ svg์— ๋Œ€ํ•ด transformMatrix๊ฐ€ ์žˆ๋‹ค๋ฉด ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ tempSvg.appendChild(pathEl);๋กœ ์ž„์‹œ SVG DOM์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒ˜ํ”Œ๋ง ๊ฐ„๊ฒฉ ์„ค์ •

    • ์˜ต์…˜์œผ๋กœ sampleStep์ด ์ฃผ์–ด์กŒ๋‹ค๋ฉด, step = sampleStep์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. sampleStep์ด ์—†๋‹ค๋ฉด, ์ด ๊ฒฝ๋กœ์˜ ๊ธธ์ด๋ฅผ samplePerPath๋กœ ๋‚˜๋ˆˆ ๊ฐ’์œผ๋กœ step์„ ์ •ํ•ฉ๋‹ˆ๋‹ค.

    ์ด ๋•Œ, ์ด๋ ‡๊ฒŒ ๊ณ„์‚ฐํ•œ step์ด maxStepClamp๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ, step = maxStepClamp๋กœ ์ƒํ•œ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.(๋„ˆ๋ฌด ๊ฐ„๊ฒฉ์ด ์ปค์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€)

  • ์ตœ๋Œ€ ์  ์ˆ˜ ์ œํ•œ

    • ๊ฒฝ๋กœ๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์„œ step ๊ฐ„๊ฒฉ์œผ๋กœ ์ฐ์œผ๋ฉด ์  ๊ฐœ์ˆ˜๊ฐ€ maxSamplePerPath๋ฅผ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ, ๊ฐ„๊ฒฉ์„ ์กฐ๊ธˆ ๋Š˜๋ ค ์  ๊ฐœ์ˆ˜๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

    ์ด ๊ณผ์ •์œผ๋กœ ์ตœ์ข… step์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

  • ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์  ์ฐ๊ธฐ

    • ์ด์ œ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ, ๊ฒฝ๋กœ๋ฅผ ์‹œ์ž‘๋ถ€ํ„ฐ ๋๊นŒ์ง€ step ๊ฐ„๊ฒฉ์œผ๋กœ ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ์ขŒํ‘œ๋ฅผ ์ƒ˜ํ”Œ๋งํ•ฉ๋‹ˆ๋‹ค.
    • len์— step์„ ๋”ํ•ด๊ฐ€๋ฉด์„œ ๋ฃจํ”„๊ฐ€ ์ง„ํ–‰๋˜๋ฉฐ, pathEl.getPointAtLength(len)๋ฅผ ํ†ตํ•ด len ๊ฑฐ๋ฆฌ๋งŒํผ ๋–จ์–ด์ง„ ์ง€์ ์˜ ์ขŒํ‘œ๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ , isFirst๊ฐ€ true์ผ์‹œ, pen์„ 0, ์•„๋‹ ์‹œ pen์„ 1๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ localPoints์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.์ดํ›„ isFirst๋ฅผ false๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค

    ์ด๋กœ์จ, path ์ฒซ ์  ์ดํ›„๋Š” ๋ชจ๋‘ pen 1๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

    • ๋˜ํ•œ, ๋ฃจํ”„ ์ข…๋ฃŒ ํ›„, ๋ณ„๋„๋กœ pathEl.getPointAtLength(totalLength)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฒฝ๋กœ์˜ ๋งˆ์ง€๋ง‰ ์ ์„ ์–ป๊ณ , ์ด๋ฅผ localPoints์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ์ž„์‹œ path ์ œ๊ฑฐ

    • ์‚ฌ์šฉ์ด ๋๋‚œ pathEl์€ ๋‹ค์‹œ tempSvg.removeChild(pathEl)๋กœ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒฝ๋กœ ๊ฒน์นจ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.
  • ๋„ํ˜• ๊ฐ„ bridge ์ถ”๊ฐ€

    • ํ•œ ๋„ํ˜•์˜ ์ ์„ points์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „์—, ๋งŒ์•ฝ ์ด์ „ ๋„ํ˜•์˜ ๋งˆ์ง€๋ง‰ ์œ„์น˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ(lastGlobalPt๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ)
      ๊ทธ ์ ์—์„œ ํ˜„์žฌ ์ƒˆ ๊ฒฝ๋กœ์˜ ์ฒซ ์ ๊นŒ์ง€ ํŽœ์„ ๋“ค์–ด ์ด๋™ํ•˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€๋กœ ์ƒ˜ํ”Œ๋งํ•ฉ๋‹ˆ๋‹ค. bridge ์ƒ˜ํ”Œ๋ง ๋ฐ€๋„๋Š” ๊ธฐ๋ณธ step์— opts.bridgeScale๋ฅผ ๊ณฑํ•ด ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค. bridgeStep = step * bridgeScale` bridge ๊ตฌ๊ฐ„์€ ํŽœ์„ ๋“  ์ด๋™์ด๋ฏ€๋กœ, pen์€ 0์œผ๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ์  ๋ˆ„์  ๋ฐ lastGlobalPt ๊ฐฑ์‹ 

    • ์ด์ œ ๋ธŒ๋ฆฌ์ง€ ์ (๋งŒ์•ฝ ์žˆ๋‹ค๋ฉด)์ด points์— ์ถ”๊ฐ€๋œ ์ƒํƒœ์—์„œ, ํ˜„์žฌ ๋„ํ˜•์˜ ์‹ค์ œ ๊ฒฝ๋กœ ์ ๋“ค(localPoints ๋ฐฐ์—ด)์„ ์ˆœ์„œ๋Œ€๋กœ points ๋ฐฐ์—ด์— ์ด์–ด๋ถ™์ž…๋‹ˆ๋‹ค.
    • ์ดํ›„ lastGlobalPt๋ฅผ localPoints์˜ ๋งˆ์ง€๋ง‰ ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  prepared ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์œ„ ๊ณผ์ •์„ ๋งˆ์น˜๋ฉด, points ๋ฐฐ์—ด์—๋Š” SVG์˜ ๋ชจ๋“  ๋„ํ˜• ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ƒ์„ฑ๋œ ์ ์ด ์ˆœ์„œ๋Œ€๋กœ ๋‹ด๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    • ๋งˆ์ง€๋ง‰์œผ๋กœ tempSvg (์ž„์‹œ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ๋ณด์กฐ SVG ์š”์†Œ)๋ฅผ document.body.removeChild(tempSvg)๋กœ ์ œ๊ฑฐํ•˜์—ฌ, ํ™”๋ฉด์— ๋ณด์ด์ง€ ์•Š๊ฒŒ ์ƒ์„ฑํ–ˆ๋˜ ์š”์†Œ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  points ๋ฐฐ์—ด์„ returnํ•˜์—ฌ ํ•จ์ˆ˜ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.
  1. ์ถœ๋ ฅ ๊ฒฐ๊ณผ

    ์ด ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’ points๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ javascript ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

    [
       { x: Number, y: Number, pen: Number },
       { x: Number, y: Number, pen: Number },
       ...
    ]

    ์ด ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด, ์ขŒํ‘œ -> ๋กœ๋ด‡์˜ step ์ฆ๋ถ„๊ฐ’ ์œผ๋กœ ๋ฐ”๊พธ๋Š” ์ฒ˜๋ฆฌ๋ฅผ ๊ฑฐ์ฒ˜, ๋กœ๋ด‡์ด ์ด์šฉ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Clone this wiki locally