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 길이 구하기

layout, paint, composite

이번에는 브라우저가 화면을 만드는 과정을 봅니다.

드래그할 때 부드럽게 움직이는 에디터와 뚝뚝 끊기는 에디터의 차이는 대단한 철학에서 나오지 않습니다. 브라우저에게 매 프레임 어떤 일을 시키느냐에서 나옵니다.

브라우저는 대략 layout, paint, composite 단계를 거쳐 화면을 만듭니다. 이 셋을 구분하면 왜 transform 기반 이동이 편집 도구에 유리한지 감이 옵니다.

browser layout paint composite pipeline diagramlayoutpaintcompositeleft/top, widthrecalculate earlier stagestransform, opacitymove existing layerframe loop: read geometry -> compute -> write transform
layout, paint, composite는 서로 다른 비용을 가집니다. 드래그 중에는 transform으로 composite만 흔들고, commit 때 모델 값을 정리하는 흐름이 안정적입니다.

layout은 자리 계산이다

layout은 각 요소가 문서 안에서 어디에 놓이고 얼마나 큰지 계산하는 단계입니다.

width, height, left, top, font-size 같은 값은 layout에 영향을 줄 수 있습니다. 특히 일반 문서 흐름 안에서는 한 요소의 크기가 바뀌면 주변 요소도 다시 계산해야 합니다.

change width
-> layout
-> paint
-> composite

편집기에서 드래그 중 매 프레임 layout을 크게 건드리면 화면이 무거워질 수 있습니다.

paint는 픽셀 만들기다

paint는 배경, 테두리, 그림자, 텍스트 같은 시각 결과를 픽셀로 그리는 단계입니다. background, box-shadow, filter 같은 속성은 paint 비용에 영향을 줍니다.

composite는 이미 그린 레이어를 합친다

transform이나 opacity 변경은 많은 경우 composite 단계에서 처리될 수 있습니다. 이미 그려진 레이어를 이동하거나 투명도만 바꾸는 식입니다.

transform은 이미 계산된 box에 affine matrix를 적용한다.
animation frame마다 O(n)으로 만질 DOM 수를 제한해야 한다.

그래서 드래그 preview에는 transform: translate(...)가 잘 맞습니다.

transform: translate(24px, 12px);

사용자가 드래그하는 동안에는 transform으로 빠르게 보여주고, pointerup에서 모델 좌표를 commit합니다.

read와 write를 섞지 말자

DOM 측정과 스타일 쓰기를 마구 섞으면 forced reflow가 생길 수 있습니다.

read: getBoundingClientRect()
write: element.style.transform = ...
read again

브라우저가 “아니 방금 바꿨는데 또 물어본다고요?” 하면서 layout을 즉시 다시 계산하게 됩니다. 그래서 보통 한 프레임 안에서 read를 모으고, 계산하고, write를 모아서 처리합니다.

will-change는 미리 힌트를 줄 수 있지만, 모든 요소에 붙여두면 오히려 메모리를 낭비합니다. 필요한 순간에 제한적으로 써야 합니다. 마법 가루처럼 뿌리는 속성이 아닙니다.

데모에서 볼 것

데모에서는 left/top 이동과 transform 이동의 차이를 비교합니다.

오늘의 핵심은 렌더링 파이프라인을 존중하는 것입니다. 편집기는 매 프레임 빠르게 반응해야 하므로, 브라우저에게 가능한 한 적은 일을 시켜야 합니다. 착한 도구는 사용자를 편하게 하고, 착한 구현은 브라우저를 편하게 합니다.

Edit this page
최근 수정: 26. 5. 14. PM 5:45
Contributors: easylogic
Prev
stacking context와 합성