CSS Graphics Geometry
Guide
Reference
GitHub
Guide
Reference
GitHub
  • Part 0. Math foundations

    • 좌표계와 CSS pixel
    • 점, 벡터, 거리와 기본 용어
    • 각도, 라디안, atan2
  • Part 1. Transform linear algebra

    • translate, scale, rotate
    • CSS matrix(a,b,c,d,e,f)
    • 변환 순서와 transform-origin
    • local, world, screen 좌표계
    • inverse matrix와 포인터 입력
    • 좌표와 transform 디버깅
  • Part 2. Infinite canvas math and architecture

    • viewport와 camera 모델
    • cursor anchored zoom
    • ruler와 tick 계산
    • 주기 함수와 grid step
    • content, overlay, controls layer
    • scene graph와 nested transform
  • Part 3. Editor tool math

    • Pointer Events와 드래그
    • DOMRect와 getBoundingClientRect
    • hit testing과 bounding box
    • selection rectangle과 marquee
    • selection bounds와 handles
    • resize와 rotation handle
    • snapping과 smart guides
    • group, frame, clipping
  • Part 4. CSS graphics properties as math

    • CSS box로 도형 만들기
    • clip-path, radius, shadow
    • 선형보간과 linear-gradient
    • 거리 함수와 radial/conic-gradient
    • stacking context와 합성
    • layout, paint, composite
  • Part 5. Editor state and persistence

    • 레이어 모델과 z-index
    • 이동, 복제, 삭제, 잠금
    • undo/redo command model
    • JSON export/import
  • Part 6. SVG overlay and vector editing

    • SVG viewBox와 좌표계
    • getScreenCTM과 inverse
    • SVG pointer-events와 stroke hit testing
    • cubic bezier path editing
    • mask, clipPath, marker
  • Part 7. Figma to CSS translation

    • Figma node와 CSS DOM 모델
    • Frame constraints와 Auto Layout
    • Fills, strokes, effects를 CSS로
    • Vector와 text 변환
    • gradient 밖의 CSS 수학
    • Figma gradient를 CSS gradient로 변환하기
    • 수학이 필요한 Figma to CSS 속성들
    • Figma VectorNetwork 정리
  • Appendix A. Canvas renderer transition

    • Canvas로 넘어가는 기준
  • Appendix B. Motion and timing

    • 모션 수학과 timing 함수
    • Keyframe timeline 엔진
    • Motion path 수학
    • Bezier curve 길이 구하기

각도, 라디안, atan2

이번에는 각도입니다. 그래픽 에디터에서 각도는 회전 핸들, 방향 표시, path tangent, 축 계산까지 여기저기 얼굴을 내밉니다.

각도는 사실 방향 벡터를 숫자 하나로 압축한 것입니다.

“중심에서 봤을 때 포인터가 어느 방향에 있나요?”

이 질문에 답하는 순간 회전 도구가 시작됩니다. 자, 이제 원을 한 바퀴 돌아봅시다. 어지러우면 잠깐 쉬어도 됩니다.

브라우저 수학 함수는 라디안을 좋아한다

CSS에서는 45deg, 0.25turn, 0.785rad처럼 여러 단위를 쓸 수 있습니다. 그런데 JavaScript의 Math.sin, Math.cos, Math.atan2는 라디안을 씁니다.

degree = radian * 180 / PI
radian = degree * PI / 180

초보자 입장에서는 “왜 둘이 통일을 안 했나요?” 싶습니다. 맞습니다. 우리도 마음이 편하진 않습니다. 하지만 변환식은 짧으니 너무 미워하진 맙시다.

atan2는 방향을 각도로 바꾼다

중심점이 (cx, cy)이고 포인터가 (x, y)에 있다면, 중심에서 포인터로 향하는 벡터는 이렇습니다.

v = (x - cx, y - cy)

이 벡터의 각도는 atan2로 구합니다.

theta = atan2(y - cy, x - cx)

atan2가 좋은 이유는 사분면을 보존한다는 점입니다. 그냥 atan(y / x)로 계산하면 오른쪽 위와 왼쪽 아래를 헷갈릴 수 있습니다. 회전 핸들이 갑자기 반대로 튀면 사용자는 도구를 의심하고, 우리는 수학을 의심하게 됩니다. 그러니 atan2를 씁시다.

회전은 각도 차이다

회전 핸들을 잡는 순간의 각도를 startAngle, 현재 포인터의 각도를 currentAngle이라고 하겠습니다.

deltaAngle = currentAngle - startAngle
newRotation = originalRotation + deltaAngle

편집기의 회전 도구는 거의 이 구조입니다. 물론 실제 구현에서는 360도 경계 처리가 필요합니다. 359deg에서 1deg로 넘어갈 때 차이를 -358deg로 보면 안 됩니다. 사용자는 2도 움직였는데 오브젝트가 갑자기 큰절을 하면 곤란하니까요.

회전 행렬도 같은 이야기다

점을 원점 기준으로 theta만큼 회전하면 이렇게 됩니다.

rotated = (
  x * cos(theta) - y * sin(theta),
  x * sin(theta) + y * cos(theta)
)

지금 당장은 외우지 않아도 됩니다. 중요한 것은 cos와 sin이 회전된 x축과 y축을 만들어낸다는 감각입니다. 뒤에서 CSS matrix를 볼 때 이 공식이 다시 정장을 입고 등장합니다.

각도는 나중에 여러 곳에서 다시 나온다

지금은 CSS 속성보다 수학 구조에 집중하겠습니다. 중심에서 포인터로 향하는 벡터를 만들고, 그 벡터를 atan2로 각도로 바꾸는 구조만 잡아두면 됩니다.

이 구조는 뒤에서 회전 핸들, path tangent, 그리고 각도를 이용하는 CSS 그래픽 속성을 볼 때 다시 등장합니다. 수학 개념이 먼저, 응용은 나중입니다. 오늘은 욕심내지 맙시다.

데모에서 볼 것

데모에서는 회전 핸들을 움직이며 atan2로 얻은 각도와 CSS rotate() 값이 같은 의미인지 비교합니다.

오늘의 요지는 단순합니다. 중심을 정하고, 중심에서 포인터로 가는 벡터를 만들고, 그 벡터를 각도로 바꿉니다. 회전 도구가 괜히 신비로운 척하지만, 속은 꽤 솔직합니다.

Edit this page
최근 수정: 26. 5. 14. PM 5:45
Contributors: easylogic
Prev
점, 벡터, 거리와 기본 용어