SVG Graphics Geometry
Guide
css-matrix
Guide
css-matrix
  • Part 0. SVG 기초

    • SVG란 무엇인가
    • viewBox와 user space
    • transform attribute와 matrix
    • SVG 문서 구조와 기본 도형
  • Part 1. Path grammar

    • path d 명령어 — M, L, Z
    • H, V — 축 정렬 직선
    • C — cubic Bézier
    • Q — quadratic Bézier
    • S, T — smooth continuation
    • A — elliptical arc
    • path bounding box
  • Part 2. Stroke geometry

    • 점에서 stroke까지의 거리
    • join, cap, miter limit
    • stroke align과 outline 개념
    • miter length 공식
  • Part 3. Fill rules

    • nonzero vs evenodd
    • fill hit testing
  • Part 4. Path sampling

    • flatten tolerance
    • path length
    • point at length와 tangent
  • Part 5. Paint servers

    • linearGradient 좌표
    • clipPath와 mask 개념
  • Part 6. Path editor capstone

    • path handle 모델
    • handle hit testing
    • handle drag로 segment 갱신
    • mini path editor — SVG round-trip
  • Part 7. Fill & winding deep dive

    • winding vs ray casting
    • compound path — 여러 subpath
    • self-intersection
    • path boolean
    • fill vs stroke hit 우선순위
    • scanline parity
  • Part 8. Pattern & gradient

    • radialGradient
    • pattern tile
    • gradientUnits와 spreadMethod
  • Part 9. SVG filter & Figma effects

    • Figma DROP_SHADOW → SVG filter
    • filter chain 개요
    • blur · offset · merge
    • inner shadow
    • layer blur vs background blur
    • Figma effect 매핑표 전체
  • Part 10. Figma ↔ SVG bridge

    • vector network vs path d
    • fill · stroke export
    • boolean operations export
    • mask · clip export
  • Part 11. Icon design

    • pixel grid · optical alignment
    • fill vs stroke icons
    • symbol · sprite · currentColor
    • path simplification
  • Appendix A. SVG in CSS

    • currentColor · CSS theming
    • sprite data URI
    • SVG optimization pipeline
  • Appendix B. Engine extras

    • dash offset animation
    • adaptive flatten
    • arc → cubic 변환
    • multi-subpath editing
  • Part 12. Foundations primer

    • capability map
    • coordinate stack
  • Part 13. Figma ↔ SVG (deep)

    • Figma paint gap map
    • radial · angular gradient export
    • image · pattern fill
    • stroke align export
    • blend mode · layer opacity
  • Part 14. SVG spec breadth

    • markers — 화살표와 dash 끝
    • text · textPath
    • paint-order · opacity · filters
    • arc flatten 통합
  • Part 15. Curve calculus

    • de Casteljau subdivision
    • flatness와 chord error
    • 곡률 κ와 법선
    • arc center parameterization
    • G¹ smooth — S와 T
    • shoelace signed area
  • Part 16. Intersection & proximity

    • segment intersection
    • line ∩ cubic · curve ∩ curve
    • closest point on curve
  • Part 17. Offset curves

    • normal offset sampling
    • offset cusps
  • Part 18. Transform algebra

    • affine inverse & decompose
    • transform path vs group
  • Part 19. Rational curves

    • circle as cubic — κ constant
    • rational curves & exact arcs
  • Part 20. Tessellation & pixels

    • convex triangulation · ear clipping
    • evenodd parity → pixels
  • Part 21. Compositing math

    • Gaussian blur kernel
    • Porter–Duff & premultiplied α
  • Part 22. Math topic map

    • SVG 수학 주제 지도
  • Part 23. SVG animation

    • SMIL — animate 속성
    • SMIL — animateTransform
    • SMIL — animateMotion
    • stroke dash draw-on
    • CSS offset-path motion
    • path morph
    • JS motion along path
  • Part 24. Motion precision

    • uniform speed along path
    • cubic–cubic intersection
    • SVGPathElement length API
    • SMIL keyTimes & keySplines
    • degree elevation Q→C
  • Part 25. GPU mesh & WAAPI

    • triangulation with holes
    • WAAPI + SVG attributes
    • evenodd fill + triangle mesh

fill vs stroke hit 우선순위

같은 포인터에서 fill inside이면서 stroke band(중심선 ± width/2) 안에 들어갈 수 있습니다. SVG DOM은 “무엇이 위에 그려졌는지”만 알려 줄 뿐, 편집기가 무엇을 선택할지는 앱 정책입니다.

두 판정을 분리해서 계산

Fill — winding

import { classifyPointInPath, parsePathD } from "svg-matrix-core";

const segments = parsePathD(d);
const { inside: fillHit } = classifyPointInPath(pointer, segments, "nonzero", {
  stepsPerCurve: 24
});

014 — nonzero / evenodd는 제품 설정.

Stroke — 최단 거리

정확한 방법 (004, 076):

import { closestPointOnCubic, distancePointToSegment } from "svg-matrix-core";

let minD = Infinity;
for (const seg of segments) {
  if (seg.type === "L") {
    minD = Math.min(minD, distancePointToSegment(pointer, seg.from, seg.to).distance);
  }
  if (seg.type === "C") {
    const r = closestPointOnCubic(pointer, seg.from, seg.cp1, seg.cp2, seg.to, { samples: 48 });
    minD = Math.min(minD, r.distance);
  }
}
const strokeHit = minD <= strokeWidth / 2;

이 레슨 데모는 설명 단순화를 위해 flattenPathSegments polyline에 distancePointToSegment를 씁니다 — 얇은 S곡선에서 fill/stroke 판정이 004와 약간 어긋날 수 있습니다. 편집기 코드는 cubic 전용 closest를 쓰세요.

우선순위 테이블 (일반적)

1. handle     (가장 작은 타겟, 편집 의도가 명확)
2. stroke     (선 잡기 — 많은 도구가 fill보다 우선)
3. fill       (면 선택·이동)
4. none
import { listPathHandles, hitTestPathHandles, classifyPointInPath } from "svg-matrix-core";

function pickTarget(pointer, segments, strokeWidth, hitRadius = 12) {
  const handles = listPathHandles(segments);
  const handleHit = hitTestPathHandles(pointer, handles, hitRadius);
  if (handleHit) return { kind: "handle", handle: handleHit };

  const strokeHit = /* closest loop, § 위 */;
  if (strokeHit) return { kind: "stroke", distance: minD };

  const fillHit = classifyPointInPath(pointer, segments, "nonzero").inside;
  if (fillHit) return { kind: "fill" };

  return { kind: "none" };
}

주의: hitTestPathHandles(point, handles, radius) — segments가 아니라 handles 배열 (022).

helper stroke width (004)

반경용도
visible strokeWidth렌더
hitWidth (더 두껍게)잡기 쉬운 tolerance

우선순위 판정에 어느 값을 쓸지 제품 스펙으로 고정하세요. “보이는 선은 얇은데 잡히는 영역은 넓다”는 의도적 UX입니다.

z-order · 여러 path

겹친 path가 여러 개면:

  1. 위에서부터 hit test
  2. 각 path에 pickTarget
  3. 첫 hit 또는 가장 작은 area path

이 강의 데모는 path 하나만 다룹니다.

데모에서 볼 것

  1. strokeWidth 슬라이더 — band 두께 변경
  2. readout — fill hit=… stroke hit=… min distance=…
  3. editor picks: stroke — 둘 다 true일 때 stroke 우선 (데모 정책)
  4. fill만 있는 중앙 vs stroke band만 걸리는 가장자리

vs SVG pointer-events

pointer-events: stroke / fill / visibleStroke는 브라우저 hit를 제한합니다. 편집기는 보통 canvas/SVG 위에 직접 svg-matrix-core hit를 돌려 layer·handle·snap을 한꺼번에 제어합니다 (056, 079).

Core API

판정함수
fillclassifyPointInPath, pointInPath
strokeclosestPointOnCubic, distancePointToSegment
handlelistPathHandles, hitTestPathHandles
flatten (데모만)flattenPathSegments

데모: mountHitPriorityDemo — lesson-app.js

관련

  • 004 stroke hit · 015 fill hit · 022 handle hit · 024 editor

오늘의 핵심

hit testing = 기하 함수 + 우선순위 테이블. fill과 stroke를 한 함수에 섞지 말고, 정책을 명시적으로 적용하세요.

최근 수정: 26. 5. 17. PM 4:35
Contributors: jinho.park.s3, Cursor
Prev
path boolean
Next
scanline parity