모든 SVG 콘텐츠는 SVG 뷰포트 내부에 그려집니다. 각각의 SVG 뷰포트는 크기(너비, 높이)와 원점으로 특징지어지는 그리기 영역을 정의하며, 원점은 추상적인 사용자 단위로 측정됩니다.
SVG 뷰포트라는 용어는 CSS에서 사용되는 "viewport" 용어와는 다릅니다.
초기 뷰포트는 최상위 SVG 뷰포트로, 포함 환경(예: 웹 브라우저의 CSS 픽셀)이 사용하는 좌표계와 사용자 단위 사이의 매핑을 설정합니다. 초기 뷰포트의 설정에 대한 자세한 설명은 초기 뷰포트에서 확인할 수 있습니다.
SVG 뷰포트는 오직 요소에 의해 생성됩니다. 어떤 요소가 뷰포트를 생성하는지에 대한 정보는 새로운 SVG 뷰포트 생성하기를 참고하십시오.
각 SVG 뷰포트는 뷰포트 좌표계와 사용자 좌표계를 생성하며, 초기에 동일합니다. 뷰포트 요소에 ‘viewBox’를 제공하면 사용자 좌표계가 뷰포트 좌표계에 대해 변환됩니다. 자세한 내용은 ‘viewBox’ 속성에서 설명합니다. 뷰포트의 자식 요소는 사용자 좌표계를 추가로 수정할 수 있으며, 예를 들면 transform 속성을 지정하는 방식입니다.
SVG 뷰포트는 중첩될 수 있습니다. 백분율 단위는 가장 가까운 상위 SVG 뷰포트의 너비와 높이를 기준으로 해석됩니다. 따라서 SVG 뷰포트를 중첩하면 백분율 단위의 의미를 재정의하고 특정 사각형 영역에 그래픽을 "맞추기" 위한 새로운 참조 사각형을 제공할 수 있습니다.
SVG 뷰포트의 너비, 높이 및 원점은 SVG 뷰포트를 생성하는 SVG 문서 프래그먼트와 그 프래그먼트의 부모(실제 또는 암시적) 사이의 협상 과정에 의해 설정됩니다. 이 협상 과정에 대한 설명은 새로운 SVG 뷰포트 생성하기를 참고하십시오.
기본적으로, 중첩된 SVG 뷰포트의 뷰포트 좌표계는 부모 요소의 로컬 좌표계와 동일하며, SVG 뷰포트 요소의 원점만큼 평행이동됩니다. 하지만 SVG 뷰포트 요소에 transform 속성이 있으면 부모 요소의 사용자 좌표계에 대해 뷰포트 좌표계가 수정됩니다.
추상적으로, 모든 SVG 뷰포트는 캔버스 안에 내장되어 있으며, 캔버스는 모든 관련 차원에서 무한히 큰 그리기 영역입니다.
이 과정은 viewBox 속성의 min-x, min-y, width, height 값과, viewBox 속성이 정의된 요소의 위치 및 크기, 해당 요소의 preserveAspectRatio 속성 값을 변환 및 스케일로 변환하여 요소가 포함하는 콘텐츠에 적용합니다.
해당 요소가 포함하는 콘텐츠에 적용되는 변환은 translate(translate-x, translate-y) scale(scale-x, scale-y)로 주어집니다.
초기 뷰포트의 너비는 width 표현 속성이 최상위 svg 요소에 지정된 값이어야 합니다. 단, 다음 조건을 모두 만족하는 경우는 예외입니다:
이 조건을 모두 만족하는 경우, 뷰포트의 너비는 위치 지정 속성에 의해 결정되어야 합니다.
마찬가지로, 참조하는 요소 또는 최상위 svg 요소에 뷰포트의 높이를 결정할 수 있는 위치 지정 속성이 지정되어 있다면, 해당 위치 지정 속성이 뷰포트의 높이를 결정해야 합니다. 그렇지 않으면, 초기 뷰포트의 높이는 height 표현 속성이 최상위 svg 요소에 지정된 값이어야 합니다.
width 또는 height 표현 속성이 최상위 svg 요소에 사용자 단위로 지정되어 있다면(즉, 단위 식별자가 제공되지 않은 경우), 해당 값은 동일한 수의 "px" 단위와 동일한 것으로 간주합니다(자세한 내용은 단위 참조).
다음 예제에서는 SVG 그래픽이 부모 XML 문서 내에 인라인으로 임베드되어 있으며, CSS 레이아웃 규칙으로 포맷팅됩니다. 최상위 svg 요소에 CSS 위치 지정 속성이 제공되지 않았으므로 width="100px"와 height="200px" 속성이 초기 뷰포트의 크기를 결정합니다:
<?xml version="1.0" standalone="yes"?> <parent xmlns="http://some.url"> <!-- SVG graphic --> <svg xmlns='http://www.w3.org/2000/svg' width="100px" height="200px"> <path d="M100,100 Q200,400,300,100"/> <!-- rest of SVG graphic would go here --> </svg> </parent>
최상위 svg 요소에 대해, SVG 사용자 에이전트는 초기 뷰포트 좌표계와 초기 사용자 좌표계를 결정해야 하며, 두 좌표계는 동일해야 합니다. 두 좌표계의 원점은 SVG 뷰포트의 원점에 있어야 하며, 초기 좌표계의 한 단위는 SVG 뷰포트 내에서 CSS 2.1 px ([CSS2], section 4.3.2)와 같아야 합니다. 독립 SVG 문서와, 부모 문서의 레이아웃이 CSS [CSS2]로 결정되는 경우 참조 또는 인라인으로 부모 문서 내에 임베드된 SVG 문서 프래그먼트에서는 초기 뷰포트 좌표계(따라서 초기 사용자 좌표계)는 뷰포트의 좌상단에 원점이 있고, x축은 오른쪽으로, y축은 아래쪽으로 향하며, 텍스트는 "수직" 방향으로 렌더링되어야 합니다. 즉, 로마자와 아시아 문자(전각 한자 등)는 글리프의 윗부분이 위쪽, 오른쪽 부분이 오른쪽을 향하게 렌더링되어야 합니다.
SVG 구현체가 CSS 2.1 호환 px 단위로 문서를 스타일링하는 사용자 에이전트의 일부인 경우, SVG 사용자 에이전트는 px 단위의 실제 세계 크기를 다른 스타일링 연산과 일치하도록 초기값을 설정해야 하며, 그렇지 않으면 환경에서 px 단위의 크기를 결정할 수 있다면 해당 값을 사용해야 합니다. 그렇지 않을 경우 적절한 px 단위 크기를 선택해야 합니다. 모든 경우에 px 단위의 크기는 CSS 2.1에서 설명하는 규칙 ([CSS2], section 4.3.2)에 따라야 합니다.
Example InitialCoords 아래는 초기 좌표계의 원점이 좌상단에 있고, x축은 오른쪽, y축은 아래쪽을 가리키는 것을 보여줍니다. 초기 사용자 좌표계에서 한 사용자 단위는 부모(명시적 또는 암시적) 사용자 에이전트의 "픽셀"과 같습니다.
<?xml version="1.0" standalone="no"?> <svg width="300px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg"> <desc>Example InitialCoords - SVG의 초기 좌표계</desc> <g fill="none" stroke="black" stroke-width="3" > <line x1="0" y1="1.5" x2="300" y2="1.5" /> <line x1="1.5" y1="0" x2="1.5" y2="100" /> </g> <g fill="red" stroke="none" > <rect x="0" y="0" width="3" height="3" /> <rect x="297" y="0" width="3" height="3" /> <rect x="0" y="97" width="3" height="3" /> </g> <g font-size="14" font-family="Verdana" > <text x="10" y="20">(0,0)</text> <text x="240" y="20">(300,0)</text> <text x="10" y="90">(0,100)</text> </g> </svg>
Example InitialCoords
사용자 에이전트는 transform 속성과 표현 속성을 [css-transforms-1]에서 정의한 대로 지원해야 합니다.
이름 | 값 | 초기값 | 애니메이션 가능 |
---|---|---|---|
viewBox | [<min-x>,? <min-y>,? <width>,? <height>] | 지정되지 않은 것처럼 취급. | 예 |
<min-x>, <min-y>, <width>, <height> = <number>
‘svg’
요소의 transform은 ‘viewBox’ 속성 때문에 약간 특별합니다.
transform은 ‘svg’에 해당
transform이 설정된 부모 요소가 있다고 가정하고 적용되어야 합니다.
결의: transform 속성은 개념적으로 'svg' 요소의 바깥에
적용되며, 표현 속성과 스타일 속성의 시각적 결과에는 차이가 없음.
‘viewBox’ 속성은 ‘preserveAspectRatio’ 속성과 함께 SVG 뷰포트를 특정 컨테이너 요소에 맞게 늘릴 수 있는 기능을 제공합니다.
‘viewBox’ 속성의 값은 네 개의 숫자 <min-x>, <min-y>, <width>, <height>로 이루어진 리스트이며, 공백 또는 쉼표로 구분됩니다. 이 숫자들은 사용자 공간에서의 사각형을 지정하며, 해당 요소가 생성한 SVG 뷰포트의 경계에 맞게 매핑됩니다. 이때 ‘preserveAspectRatio’ 속성을 고려합니다. ‘viewBox’ 속성이 존재하면 SVG 뷰포트의 등가 변환 계산하기에서 설명한 대로 뷰포트 좌표계에 변환이 적용됩니다.
<width> 또는 <height>에 음수 값이 있으면 오류이며 ‘viewBox’ 속성이 무효화됩니다. 값이 0이면 해당 요소의 렌더링이 비활성화됩니다.
예시 ViewBox는 최상위 svg 요소에 ‘viewBox’ 속성을 사용하여 SVG 콘텐츠가 SVG 뷰포트 경계에 맞게 늘어나도록 지정하는 방법을 보여줍니다.
<?xml version="1.0" standalone="no"?> <svg width="300px" height="200px" viewBox="0 0 1500 1000" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg"> <desc>예시 ViewBox - viewBox 속성을 사용하여 초기 사용자 좌표계를 자동으로 생성하고, 그래픽이 SVG 뷰포트 크기에 관계없이 그 안에 맞게 스케일되도록 함.</desc> <!-- 이 사각형은 사용자 좌표계에서 (0,0)에서 (1500,1000)까지 그려집니다. 위의 viewBox 속성 때문에, 이 사각형은 SVG 콘텐츠에 할당된 전체 영역을 채웁니다. --> <rect x="0" y="0" width="1500" height="1000" fill="yellow" stroke="blue" stroke-width="12" /> <!-- 큰 빨간 삼각형 --> <path fill="red" d="M 750,100 L 250,900 L 1250,900 z"/> <!-- SVG 뷰포트 대부분을 차지하는 텍스트 문자열 --> <text x="100" y="600" font-size="200" font-family="Verdana" > Stretch to fit </text> </svg>
렌더링 SVG 뷰포트 width=300px, height=200px |
렌더링 SVG 뷰포트 width=150px, height=200px |
|
---|---|---|
![]() |
![]() |
‘viewBox’ 속성의 효과는 사용자 에이전트가 사용자 좌표계에서 지정된 사각형을 지정된 영역(종종 SVG 뷰포트)에 맞게 매핑하는 적절한 변환 행렬을 자동으로 제공한다는 것입니다. 왼쪽 예시에서 SVG 뷰포트 크기가 300 x 200 픽셀일 때, 사용자 에이전트는 X와 Y를 모두 0.2로 스케일하는 변환을 자동으로 삽입해야 합니다. 이 효과는 다음과 같이 300px x 200px 크기의 SVG 뷰포트와 아래의 보조 변환을 문서에 넣는 것과 같습니다:
<?xml version="1.0" standalone="no"?> <svg width="300px" height="200px" xmlns="http://www.w3.org/2000/svg"> <g transform="scale(0.2)"> <!-- 나머지 문서 --> </g> </svg>
오른쪽 예시처럼 SVG 뷰포트 크기가 150 x 200 픽셀일 때는, 사용자 에이전트가 X는 0.1, Y는 0.2로 스케일하는 변환을 자동으로 삽입해야 합니다. 이 효과는 150px x 200px 크기의 SVG 뷰포트와 아래와 같은 보조 변환을 문서에 넣는 것과 같습니다:
<?xml version="1.0" standalone="no"?> <svg width="150px" height="200px" xmlns="http://www.w3.org/2000/svg"> <g transform="scale(0.1 0.2)"> <!-- 나머지 문서 --> </g> </svg>
일부 경우에는 사용자 에이전트가 scale 변환 외에 translate 변환도 제공해야 할 수 있습니다. 예를 들어 최상위 svg 요소에서는 ‘viewBox’ 속성의 <min-x> 또는 <min-y> 값이 0이 아닐 경우 translate 변환이 필요합니다.
transform (또는 ‘patternTransform’) 과 ‘viewBox’가 동시에 요소에 적용되면 새로운 좌표계가 두 개 생성됩니다. transform은 요소의 첫 번째 새로운 좌표계를 설정하며, ‘viewBox’ 는 해당 요소의 모든 자손에 대해 두 번째 좌표계를 설정합니다. 첫 번째 좌표계는 두 번째 좌표계에 후행 곱(post-multiplied)됩니다.
transform 속성과 달리, ‘viewBox’에 의해 생성된 자동 변환은 해당 요소의 ‘x’, ‘y’, ‘width’, ‘height’ 속성(또는 ‘marker’ 요소의 경우 ‘markerWidth’ 및 ‘markerHeight’ 속성)에는 영향을 주지 않습니다. 즉, 위의 예처럼 ‘svg’ 요소가 width와 height 표현 속성, ‘viewBox’ 속성을 가지고 있을 때, width와 height는 ‘viewBox’ 변환이 적용되기 이전 좌표계의 값입니다. 반면 transform 속성처럼, 모든 다른 속성과 자손 요소에 대해서는 새로운 좌표계를 생성합니다.
이름 | 값 | 초기값 | 애니메이션 가능 |
---|---|---|---|
preserveAspectRatio | <align> <meetOrSlice>? | xMidYMid meet | 예 |
<align> = none | xMinYMin | xMidYMin | xMaxYMin | xMinYMid | xMidYMid | xMaxYMid | xMinYMax | xMidYMax | xMaxYMax
<meetOrSlice> = meet | slice
균일 스케일링을 강제할지 여부를 나타냅니다. 새로운 SVG 뷰포트를 생성하는 모든 요소(자세한 내용은 SVG 뷰포트를 생성하는 요소 참고)에 적용되며, ‘image’, ‘marker’, ‘pattern’, ‘view’ 요소에도 적용됩니다.
일부 경우(일반적으로 ‘viewBox’ 속성을 사용할 때)는 그래픽을 전체 SVG 뷰포트에 맞게 비균일하게 늘리는 것이 바람직할 수 있습니다. 다른 경우에는 그래픽의 종횡비를 유지하기 위해 균일 스케일링을 사용하는 것이 필요할 수 있습니다.
새로운 SVG 뷰포트를 생성하는 요소(자세한 내용은 SVG 뷰포트를 생성하는 요소 참고), ‘marker’, ‘pattern’, ‘view’ 요소에 대해서는, 동일한 요소에 ‘viewBox’ 값이 제공된 경우에만 ‘preserveAspectRatio’가 적용됩니다. 해당 요소에 ‘viewBox’ 속성이 지정되지 않으면 ‘preserveAspectRatio’는 무시됩니다.
‘image’ 요소의 경우 ‘preserveAspectRatio’는 참조된 이미지를 기준 사각형에 어떻게 맞출지와, 참조 이미지의 종횡비를 현재 사용자 좌표계 기준으로 유지할지 여부를 나타냅니다.
<align> 파라미터는 균일 스케일링을 강제할지 여부와, ‘viewBox’의 종횡비가 SVG 뷰포트의 종횡비와 맞지 않을 경우 사용할 정렬 방식을 나타냅니다. <align> 파라미터는 반드시 다음 문자열 중 하나여야 합니다:
<meetOrSlice> 파라미터는 선택 사항이며, 제공되는 경우 <align> 값 뒤에 하나 이상의 공백으로 구분되어야 하며 다음 문자열 중 하나여야 합니다:
meet (기본값) - 그래픽을 다음과 같이 스케일링합니다:
이 경우 그래픽의 종횡비가 SVG 뷰포트와 맞지 않으면, SVG 뷰포트의 일부가 ‘viewBox’ 경계를 벗어날 수 있습니다(즉, ‘viewBox’가 그릴 영역이 SVG 뷰포트보다 작아집니다).
slice - 그래픽을 다음과 같이 스케일링합니다:
이 경우 ‘viewBox’의 종횡비가 SVG 뷰포트와 맞지 않으면, ‘viewBox’의 일부가 SVG 뷰포트 경계를 벗어날 수 있습니다(즉, ‘viewBox’가 그릴 영역이 SVG 뷰포트보다 커집니다).
예시 PreserveAspectRatio 는 ‘preserveAspectRatio’의 다양한 옵션을 보여줍니다. 이 예제는 최상위 svg 요소 내부에 ‘svg’ 하위 요소를 임베드하여 여러 새로운 SVG 뷰포트를 생성합니다(자세한 내용은 새로운 SVG 뷰포트 생성하기 참고).
<svg width="450px" height="300px" xmlns="http://www.w3.org/2000/svg"> <desc>예시 PreserveAspectRatio - preserveAspectRatio 속성 사용 예시</desc> <style type="text/css"> text { font-size: 9; } rect { fill: none; stroke: blue; } </style> <defs> <g id="smile"> <rect x='.5' y='.5' width='29' height='39' style="fill:black;stroke:red"/> <circle cx='15' cy='20' r='10' fill='yellow'/> <circle cx='12' cy='17' r='1.5' fill='black'/> <circle cx='17' cy='17' r='1.5' fill='black'/> <path d='M 10 24 A 8 8 0 0 0 20 24' stroke='black' stroke-width='2'/> </g> </defs> <rect x="1" y="1" width="448" height="298"/> <text x="10" y="30">SVG 맞추기</text> <g transform="translate(20,40)"><use href="#smile" /></g> <text x="10" y="110">뷰포트 1</text> <g transform="translate(10,120)"><rect x='.5' y='.5' width='49' height='29'/></g> <text x="10" y="180">뷰포트 2</text> <g transform="translate(20,190)"><rect x='.5' y='.5' width='29' height='59'/></g> <g id="meet-group-1" transform="translate(100, 60)"> <text x="0" y="-30">--------------- meet ---------------</text> <g> <text y="-10">xMin*</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> <g transform="translate(70,0)"> <text y="-10">xMid*</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> <g transform="translate(0,70)"> <text y="-10">xMax*</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> </g> <g id="meet-group-2" transform="translate(250, 60)"> <text x="0" y="-30">---------- meet ----------</text> <g> <text y="-10">*YMin</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> <g transform="translate(50, 0)"> <text y="-10">*YMid</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> <g transform="translate(100, 0)"> <text y="-10">*YMax</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> </g> <g id="slice-group-1" transform="translate(100, 220)"> <text x="0" y="-30">---------- slice ----------</text> <g> <text y="-10">xMin*</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> <g transform="translate(50,0)"> <text y="-10">xMid*</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> <g transform="translate(100,0)"> <text y="-10">xMax*</text> <rect x='.5' y='.5' width='29' height='59'/> <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40" width="30" height="60"> <use href="#smile" /> </svg> </g> </g> <g id="slice-group-2" transform="translate(250, 220)"> <text x="0" y="-30">--------------- slice ---------------</text> <g> <text y="-10">*YMin</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> <g transform="translate(70,0)"> <text y="-10">*YMid</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> <g transform="translate(140,0)"> <text y="-10">*YMax</text> <rect x='.5' y='.5' width='49' height='29'/> <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40" width="50" height="30"> <use href="#smile" /> </svg> </g> </g> </svg>
예시 PreserveAspectRatio
SVG 콘텐츠 내부에 ‘svg’ 요소를 포함하면 그 안에 포함된 모든 그래픽이 그려지는 새로운 SVG 뷰포트가 생성됩니다. 이는 암묵적으로 새로운 뷰포트 좌표계와 새로운 사용자 좌표계를 모두 설정합니다. 또한, 새로운 SVG 뷰포트가 생성되므로 백분율 단위의 의미도 새롭게 정의됩니다(단위 참고).
새로운 SVG 뷰포트의 경계는 새로운 SVG 뷰포트를 생성하는 요소(예: ‘svg’ 요소)의 ‘x’, ‘y’, ‘width’, ‘height’ 속성으로 정의됩니다. 새로운 뷰포트 좌표계와 새로운 사용자 좌표계는 모두 (‘x’, ‘y’)에 원점을 가지며, ‘x’와 ‘y’는 해당 SVG 뷰포트를 생성하는 요소의 해당 속성 값입니다. 새로운 뷰포트 좌표계와 새로운 사용자 좌표계의 방향은 SVG 뷰포트를 생성하는 요소의 현재 사용자 좌표계의 방향과 동일합니다. 새로운 뷰포트 좌표계와 새로운 사용자 좌표계에서의 단위 하나는 SVG 뷰포트를 생성하는 요소의 현재 사용자 좌표계에서의 단위 하나와 같은 크기입니다.
예시:
<?xml version="1.0" standalone="no"?> <svg width="4in" height="3in" xmlns="http://www.w3.org/2000/svg"> <desc>이 SVG 그림은 또 하나의 SVG를 포함하여 새로운 SVG 뷰포트를 생성합니다. </desc> <!-- 아래의 구문은 새로운 SVG 뷰포트를 생성하며, SVG 그림 B를 해당 SVG 뷰포트에 렌더링합니다. --> <svg x="25%" y="25%" width="50%" height="50%"> <!-- 그림 B가 여기에 들어갑니다 --> </svg> </svg>
새로운 SVG 뷰포트 생성에 대한 자세한 예시는 예시 PreserveAspectRatio를 참고하세요.
다음 요소들이 새로운 SVG 뷰포트를 생성합니다:
역사적인 이유로, ‘pattern’ 및 ‘marker’ 요소는 ‘viewBox’ 속성을 받아들이지만 새로운 뷰포트를 생성하지 않습니다. ‘clipPath’나 ‘mask’ 요소도 마찬가지입니다. 이들 요소의 콘텐츠 내에서의 백분율 길이는 그래픽 효과 영역의 크기에 비례하지 않습니다.
‘foreignObject’ 요소는 자식 콘텐츠에 대해 새로운 CSS 포함 블록을 생성합니다. ‘video’, ‘audio’, ‘canvas’ 요소도 폴백 콘텐츠가 렌더링될 때 동일합니다. 이는 새로운 뷰포트와 유사한 효과를 가지며, 자식 콘텐츠의 레이아웃 범위를 초기화합니다. 하지만 ‘foreignObject’의 하위에 SVG 요소를 렌더링하려면 반드시 ‘svg’ 요소가 SVG 문서 프래그먼트 및 SVG 뷰포트를 생성해야 합니다.
‘image’ 또는 ‘iframe’ 요소는 참조된 문서에 대해 새로운 문서 뷰포트를 생성합니다. 참조된 문서가 SVG 파일이라면, 해당 문서는 자체 SVG 뷰포트를 생성합니다.
새로운 SVG 뷰포트가 추가적인 클리핑 경로도 생성하는지는 새로운 SVG 뷰포트를 생성하는 요소의 overflow 속성 값에 따라 결정됩니다.
SVG는 CSS 값과 단위 모듈 [css-values]의 공통 값 및 단위에 대한 설명과 정의를 따릅니다. 각 속성과 CSS 속성은 사용되는 구성 값 타입을 명확히 지정해야 합니다. CSS WG 또는 SVG WG에서 발행하는 후속 또는 확장 명세는 기본 데이터 타입을 확장하거나 새로운 데이터 타입을 추가할 수 있습니다.
<percentage> 값이 SVG 뷰포트 크기에 상대적인 경우:
sqrt((width)**2 + (height)**2)/sqrt(2)
로 계산합니다.
예시 Units는 다양한 단위 타입에 대한 처리 규칙을 보여줍니다.
<?xml version="1.0" standalone="no"?> <svg width="400px" height="200px" viewBox="0 0 4000 2000" xmlns="http://www.w3.org/2000/svg"> <title>예시 Units</title> <desc>다양한 단위 옵션 예시</desc> <!-- 그림의 프레임 --> <rect x="5" y="5" width="3990" height="1990" fill="none" stroke="blue" stroke-width="10"/> <g fill="blue" stroke="red" font-family="Verdana" font-size="150"> <!-- 절대 단위 지정 --> <g transform="translate(400,0)"> <text x="-50" y="300" fill="black" stroke="none">Abs. units:</text> <rect x="0" y="400" width="4in" height="2in" stroke-width=".4in"/> <rect x="0" y="750" width="384" height="192" stroke-width="38.4"/> <g transform="scale(2)"> <rect x="0" y="600" width="4in" height="2in" stroke-width=".4in"/> </g> </g> <!-- 상대 단위 지정 --> <g transform="translate(1600,0)"> <text x="-50" y="300" fill="black" stroke="none">Rel. units:</text> <rect x="0" y="400" width="2.5em" height="1.25em" stroke-width=".25em"/> <rect x="0" y="750" width="375" height="187.5" stroke-width="37.5"/> <g transform="scale(2)"> <rect x="0" y="600" width="2.5em" height="1.25em" stroke-width=".25em"/> </g> </g> <!-- 백분율 --> <g transform="translate(2800,0)"> <text x="-50" y="300" fill="black" stroke="none">Percentages:</text> <rect x="0" y="400" width="10%" height="10%" stroke-width="1%"/> <rect x="0" y="750" width="400" height="200" stroke-width="31.62"/> <g transform="scale(2)"> <rect x="0" y="600" width="10%" height="10%" stroke-width="1%"/> </g> </g> </g> </svg>
예시 Units
왼쪽의 세 사각형은 절대 단위 식별자 중 "in"(인치) 단위 사용을 보여줍니다. CSS는 1인치를 96픽셀로 정의합니다. 따라서 맨 위 사각형은 인치 단위로 지정되었고, 중간 사각형은 사용자 단위로 지정되어 각각의 인치에 대해 96 사용자 단위가 일치하므로 크기가 같습니다. 하단 사각형은 인치 단위로 지정된 값이 스케일될 때의 동작을 보여줍니다.
중앙의 세 사각형은 상대 단위 식별자 중 "em" 단위 사용을 보여줍니다. font-size 속성이 최상위 ‘g’ 요소에 150으로 설정되어 있으므로, 각 "em" 단위는 150 사용자 단위와 같습니다. 맨 위 사각형은 "em" 단위로 지정되었고, 중간 사각형은 사용자 단위로 지정되어 각각의 "em" 단위에 대해 150 사용자 단위가 일치하므로 크기가 같습니다. 하단 사각형은 "em" 단위로 지정된 값이 스케일될 때의 동작을 보여줍니다.
오른쪽의 세 사각형은 백분율 사용을 보여줍니다. SVG 뷰포트 요소의 사용자 좌표계에서 SVG 뷰포트의 너비와 높이는 각각 4000, 2000입니다. 이는 ‘viewBox’ 속성 처리를 통해
사용자 좌표계가 변환되었기 때문입니다. 맨 위 사각형은 백분율 단위로 지정되었고, 중간 사각형은 동등한 사용자 단위로 지정되어 크기가 같습니다. 특히 중간 사각형의 stroke-width 속성은 sqrt((actual-width)**2 +
(actual-height)**2) / sqrt(2)
의 1%로 설정되어 있으며, 이 경우 .01*sqrt(4000*4000+2000*2000)/sqrt(2) 또는 31.62입니다. 하단
사각형은 백분율 단위로 지정된 값이 스케일될 때의 동작을 보여줍니다.
요소의 경계 박스(bbox)는 해당 요소와 그 자손을 완전히 감싸는, 해당 요소의 사용자 좌표계 축에 정렬된 가장 꼭 맞는 사각형입니다.
요소에 대해 세 가지 종류의 경계 박스를 계산할 수 있습니다:
요소의 opacity, visibility, fill, fill-opacity, fill-rule, stroke-dasharray 및 stroke-dashoffset 속성 값은 경계 박스에 영향을 주지 않습니다.
곡선 도형의 경우, 경계 박스는 곡선의 끝점뿐만 아니라 곡선의 모든 부분을 감싸야 합니다. 곡선의 제어점(예: 큐빅 베지어의 두 번째 좌표쌍)이 곡선의 선상에 정의되지 않은 경우, 해당 제어점은 경계 박스 크기에 영향을 주지 않아야 합니다(제어점이 도형 내부나 곡선 근처에 위치하면 박스 내에 포함될 수 있음). 예를 들어, 곡선 가장자리의 바깥쪽에 더 멀리 위치한 제어점은 경계 박스 계산에서 제외해야 합니다.
경로 'M20,50 L35,100 H120 V50 Q70,10 20,50' 는 연한 파란색으로 표시됨. 왼쪽에는 해당 경로의 올바른 오브젝트 경계 박스가 나타나 있습니다. 곡선의 맨 위 제어점은 포함되지 않지만, 파란색 도형의 모든 부분(제어점의 볼록 껍질 바깥 부분도 포함)이 포함됨을 알 수 있습니다.
요소가 렌더링 트리에 속하지 않더라도(예: 'display: none'이거나 ‘defs’ 요소 내에 있거나, ‘symbol’ 요소처럼 일반적으로 렌더링되지 않거나, 현재 문서 트리에 존재하지 않는 경우) 여전히 경계 박스를 가집니다. 해당 요소에 getBBox를 호출하면, 요소가 렌더링되는 경우와 동일한 사각형이 반환됩니다. 하지만 렌더링 트리에 속하지 않는 요소는 상위 요소의 경계 박스에는 영향을 주지 않습니다.
다음 예제는 여러 요소를 정의합니다. 각 ID가 있는 요소의 예상 오브젝트 경계 박스는 아래와 같습니다.
<svg xmlns="http://www.w3.org/2000/svg"> <title>경계 박스 계산</title> <desc>컨텍스트에 따라 경계 박스 결과가 달라지는 요소 예시.</desc> <defs id="defs-1"> <rect id="rect-1" x="20" y="20" width="40" height="40" fill="blue" /> </defs> <g id="group-1"> <use id="use-1" href="#rect-1" x="10" y="10" /> <g id="group-2" display="none"> <rect id="rect-2" x="10" y="10" width="100" height="100" fill="red" /> </g> </g> </svg>
요소 ID | 경계 박스 결과 |
---|---|
"defs-1 " |
{0, 0, 0, 0} |
"rect-1 " |
{20, 20, 40, 40} |
"group-1 " |
{30, 30, 40, 40} |
"use-1 " |
{30, 30, 40, 40} |
"group-2 " |
{10, 10, 100, 100} |
"rect-2 " |
{10, 10, 100, 100} |
텍스트 콘텐츠 요소의 경우, 경계 박스 계산을 위해 각 글리프를 별도의 그래픽 요소로 처리해야 합니다. 모든 글리프가 전체 글리프 셀을 차지하는 것으로 계산해야 합니다. 전체 글리프 셀은 수평 텍스트의 경우 수평 어드밴스와 EM 박스 높이가 같아야 하며, 세로로 옆으로 배치된 텍스트의 경우 EM 박스 너비와 수평 어드밴스가 같아야 합니다. 기타 세로 텍스트의 경우 EM 박스 너비와 세로 어드밴스가 같거나, 폰트에 세로 어드밴스가 정의되어 있지 않을 경우 EM 박스 높이와 같아야 합니다. 예를 들어, 수평 텍스트의 경우 각 글리프가 폰트의 전체 상승 및 하강 값을 차지하는 것으로 계산해야 합니다.
선언적 또는 스크립트 애니메이션은 요소의 도형, 크기, 위치를 변경할 수 있으므로, 경계 박스는 변경될 수 있습니다. 따라서 요소의 경계 박스는 스크립트 호출이나 선언적/링킹 문법에 의해 요청된 시점의 현재 요소 값을 반영해야 합니다.
너비 또는 높이가 0인 요소(예: 수직 또는 수평선, ‘rect’ 요소에서 width 또는 height가 0인 경우)도 경계 박스를 가지며, 양의 값이 있는 차원만큼의 값을 가지거나, 양의 차원이 없으면 너비와 높이가 '0'이 됩니다. 마찬가지로 ‘path’ 요소의 서브패스 구간이 너비와 높이가 0이라도 해당 요소의 기하정보에 포함되어 경계 박스에 반영되어야 합니다.
위치가 명시되지 않은 요소(예: ‘path’ 요소에서 d 속성 값이 none인 경우)는 경계 박스 계산 시 (0,0) 위치로 취급합니다.
DOM 객체가 SVGGraphicsElement에서 파생되지 않은 요소(예: 그라디언트 요소)는 경계 박스를 가지지 않으며, 경계 박스를 요청할 인터페이스도 없습니다.
렌더링 트리 내의, 아직 리소스가 해석되지 않은 리소스를 참조하는 요소도, 속성에 지정된 위치와 크기 또는 해당 속성이
지정되지 않은 경우 초기값에 따라 정의된 경계 박스를 가져야 합니다. 예를 들어
<use href="#bad" x="10" y="10"/>
요소는 x와 y가 10이고, 너비와 높이가 0인 경계 박스를 갖게 됩니다.
아래 알고리즘은 주어진 요소에 대해 경계 박스를 계산하는 방법을 정의합니다. 알고리즘의 입력값은 다음과 같습니다:
경계 박스 계산 알고리즘은 element의 타입에 따라 다음과 같이 동작합니다:
fill, fill-opacity 및 fill-rule 속성 값은 fill-shape에 영향을 주지 않는다.
stroke-opacity, stroke-dasharray 및 stroke-dashoffset 값은 스트로크 도형 계산에 영향을 주지 않는다.
(0, 0, 0, 0) 값과 빈 도형을 가진 box의 합집합은 box입니다.
요소의 오브젝트 경계 박스, 스트로크 경계 박스 또는 장식 경계 박스는 위의 경계 박스 계산 알고리즘을 다음 인수로 호출한 결과입니다: element는 해당 요소 자체, space는 요소의 사용자 좌표계, fill은 true, stroke는 스트로크 경계 박스 또는 장식 경계 박스를 계산할 때 true, 그렇지 않으면 false, markers는 장식 경계 박스를 계산할 때 true, 그렇지 않으면 false, clipped는 false입니다.
다음 요소들은 지정된 속성을 해당 요소에 'objectBoundingBox'로 설정함으로써 좌표값과 길이를 오브젝트 경계 박스의 분수(또는 경우에 따라 백분율)로 표현할 수 있는 옵션을 제공합니다:
요소 | 속성 | 효과 |
---|---|---|
‘linearGradient’ | ‘gradientUnits’ | 그라디언트 벡터를 지정하는 속성(‘x1’, ‘y1’, ‘x2’, ‘y2’)가 그라디언트가 적용되는 요소의 경계 박스에 대한 분수 또는 백분율로 표현됨을 나타냅니다. |
‘radialGradient’ | ‘gradientUnits’ | 중심(‘cx’, ‘cy’), 반지름(‘r’), 포커스(‘fx’, ‘fy’)를 지정하는 속성이 그라디언트가 적용되는 요소의 경계 박스에 대한 분수 또는 백분율로 표현됨을 나타냅니다. |
‘pattern’ | ‘patternUnits’ | 패턴 타일링을 정의하는 속성(‘x’, ‘y’, ‘width’, ‘height’)가 패턴이 적용되는 요소의 경계 박스를 기준으로 설정됨을 나타냅니다. |
‘pattern’ | ‘patternContentUnits’ | 패턴의 내용에 대한 사용자 좌표계가 패턴이 적용되는 요소의 경계 박스를 기준으로 설정됨을 나타냅니다. |
‘clipPath’ | ‘clipPathUnits’ | ‘clipPath’ 요소의 내용에 대한 사용자 좌표계가 클리핑 패스가 적용되는 요소의 경계 박스를 기준으로 설정됨을 나타냅니다. |
‘mask’ | ‘maskUnits’ | 마스킹 영역을 정의하는 속성(‘x’, ‘y’, ‘width’, ‘height’)가 마스크가 적용되는 요소의 경계 박스를 기준으로 설정됨을 나타냅니다. |
‘mask’ | ‘maskContentUnits’ | ‘mask’ 요소의 내용에 대한 사용자 좌표계가 마스크가 적용되는 요소의 경계 박스를 기준으로 설정됨을 나타냅니다. |
‘filter’ | ‘filterUnits’ | 필터 효과 영역(‘x’, ‘y’, ‘width’, ‘height’)를 정의하는 속성이 필터가 적용되는 요소의 경계 박스에 대한 분수 또는 백분율로 표현됨을 나타냅니다. |
‘filter’ | ‘primitiveUnits’ | 필터 프리미티브 내의 다양한 길이 값이 필터가 적용되는 요소의 경계 박스에 대한 분수 또는 백분율로 표현됨을 나타냅니다. |
이후 논의에서 적용 요소란 해당 효과가 적용되는 요소를 의미합니다. 그라디언트와 패턴의 경우 적용 요소는 해당 그라디언트나 패턴을 fill 또는 stroke 속성으로 참조하는 그래픽 요소입니다. (텍스트 요소 관련 특수 규칙은 오브젝트 경계 박스 단위와 텍스트 요소 설명 참조.) 클리핑 패스, 마스크, 필터의 경우 적용 요소는 컨테이너 요소 또는 그래픽 요소가 될 수 있습니다.
키워드 objectBoundingBox를 사용할 때, 효과는 중첩된 변환 행렬 목록에 보조 변환 행렬이 삽입되어 새로운 사용자 좌표계를 만드는 것과 같습니다.
먼저, (minx,miny), (maxx,maxy) 좌표는 적용 요소의 오브젝트 경계 박스의 확장에 의해 결정됩니다.
그 다음, 새로운 사용자 좌표계에서 (0,0) 좌표는 적용 요소의 사용자 좌표계에서 타이트 경계 박스의 (minx,miny) 꼭짓점에 매핑되고, (1,1) 좌표는 타이트 경계 박스의 (maxx,maxy) 꼭짓점에 매핑됩니다. 대부분의 상황에서 다음 변환 행렬이 올바른 효과를 생성합니다:
[ (maxx-minx) 0 0 (maxy-miny) minx miny ]
그라디언트 벡터, 패턴 타일, 필터 영역, 마스킹 영역을 정의하는 속성에 백분율이 사용될 때, 백분율은 해당 소수값과 동일한 값을 의미합니다(예: 50%는 0.5와 동일). ‘pattern’, ‘clipPath’, ‘mask’, ‘filter’ 요소의 내용 내에서 백분율이 사용되면, 해당 값은 단위에서 정의한 백분율 처리 규칙에 따라 처리됩니다.
오브젝트 경계 박스 단위로 표현된 값에는 임의의 숫자를 지정할 수 있습니다. 즉, 0보다 작은 분수나 1보다 큰 분수, 0%보다 작은 백분율이나 100%보다 큰 백분율도 지정할 수 있습니다.
적용 요소의 기하가 너비 또는 높이가 없는 경우(예: 수평 또는 수직 선), objectBoundingBox 키워드는 사용하지 않아야 합니다. 선의 stroke가 0이 아닌 경우 실제 두께가 보일 수 있지만, 스트로크 너비는 경계 박스 계산에 무시되므로 해당 기하에 너비 또는 높이가 없는 경우입니다. 적용 요소의 기하에 너비 또는 높이가 없고 objectBoundingBox가 지정된 경우, 해당 효과(예: 그라디언트 또는 필터)는 무시됩니다.
CSS로 포맷된 호스트 문서에 SVG를 포함할 수 있도록 하려면 구체적인 객체 크기를 계산해야 합니다. 구체적인 객체 크기는 CSS Images 3 [css-images-3]에서 정의된 기본 크기 알고리즘을 사용하여 다음 입력값으로 계산해야 합니다:
명시된 크기는 ‘svg’ 요소의 width 및 height 크기 속성의 사용 값에서 결정해야 합니다.
고유 치수 역시 width 및 height 크기 속성에서 결정해야 합니다. 만약 width나 height 중 하나가 지정되지 않았다면, 사용 값은 초기값 'auto'입니다. 'auto' 및 백분율 길이는 고유 너비나 고유 높이를 결정하는 데 사용하면 안 됩니다.
비트맵 이미지 포맷의 경우 고유 치수는 이미지 파일에 고정되어 있고, 호스트 문서에서 필요한 만큼 이미지 크기를 지정하여 스케일합니다. SVG는 본질적으로 확장 가능하므로, 고유 너비와 고유 높이를 명시된 크기의 너비와 높이로 맞춥니다. 따라서 길이로 지정할 경우 ‘svg’ 요소의 width 및 height 크기 속성이 SVG 이미지의 고유 치수와 호스트 문서에 SVG 이미지를 배치할 때 사용하는 명시된 크기를 결정합니다.
고유 종횡비는 다음 알고리즘을 사용하여 계산해야 합니다. 알고리즘이 null을 반환하면 고유 종횡비가 없습니다.
이 섹션에서 정의하는 동작은 CSS에 특화되어 있지만, 다른 호스트 컨텍스트로도 적용할 수 있습니다. 모든 호스트 컨텍스트에서, 고유 종횡비가 있을 경우 SVG 뷰포트 크기를 지정할 때 반드시 이를 존중해야 합니다.
예시:
<svg xmlns="http://www.w3.org/2000/svg" width="10cm" height="5cm"> ... </svg>
이 예시에서 SVG 뷰포트의 고유 종횡비는 2:1입니다. 고유 너비는 10cm이고 고유 높이는 5cm입니다.
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50%" viewBox="0 0 200 200"> ... </svg>
이 예시에서 최상위 SVG 뷰포트의 고유 종횡비는 1:1입니다. 이 경우의 종횡비 계산은 한 방향만 제한된 포함 블록 내에 오브젝트를 임베드할 수 있게 해줍니다.
<svg xmlns="http://www.w3.org/2000/svg" width="10cm" viewBox="0 0 200 200"> ... </svg>
이 경우 고유 종횡비는 1:1입니다.
<svg xmlns="http://www.w3.org/2000/svg" width="75%" height="10cm" viewBox="0 0 200 200"> ... </svg>
이 예시에서 고유 종횡비는 1:1입니다.
새로운 auto 값에 대한 예시를 더 추가해야 할까요? 예를 들어 David Vest가 제공한 예시 등.
SVG 2 요구사항: | SVG 2는 SVG 1.2 Tiny를 기반으로 제한된 변환 기능을 가질 것입니다. |
---|---|
결의: | 벡터 효과 확장 제안서를 SVG 2 명세에 추가함. |
목적: | 비스케일(확대/축소되지 않는) 오브젝트의 일부 또는 전체 등 비스케일 기능 포함 |
책임자: | Satoru Takagi (ACTION-3619) |
때로는 오브젝트의 외곽선이 원래의 두께를 유지하도록 하거나, 오브젝트의 위치가 어떤 변환을 적용해도 고정되도록 하는 것이 중요할 수 있습니다. 예를 들어, 도로를 나타내는 2px 너비의 선이 있는 지도에서는 사용자가 지도를 확대해도 도로가 2px 너비를 유지하는 것이 중요하며, 그래픽 차트의 안내 노트처럼 팬(이동)이 가능한 경우에도 그렇습니다.
이러한 특수 좌표 변환 및 그래픽 효과를 제공하기 위해 SVG Tiny 1.2에서는 vector-effect 속성이 도입되었습니다. SVG Tiny 1.2에서는 비스케일 스트로크 동작만 도입했지만, 이 버전에서는 더 다양한 추가 효과를 제공합니다. 또한 이러한 효과는 조합하여 지정할 수 있어 더욱 다양한 효과를 보여줍니다. 앞으로의 SVG 버전에서는 이 속성을 통해 더욱 강력한 벡터 효과를 제공할 수 있습니다.
vector-effect의 non-scaling-stroke 및 none 이외의 값들은 구현이 부족해 SVG 2에서 제외될 위험이 있습니다. 구현자들이 현재 명세대로 구현하는 실용성에 대해 피드백을 주시기 바랍니다. 구현 기간 중 의견을 요청합니다.
이름: | vector-effect |
---|---|
값: | none | [ non-scaling-stroke | non-scaling-size | non-rotation | fixed-position ]+ [ viewport | screen ]? |
초기값: | none |
적용 대상: | 그래픽 요소 및 ‘use’ |
상속: | 아니오 |
백분율: | N/A |
미디어: | 시각적 |
계산된 값: | 지정된 값 그대로 |
애니메이션 가능: | 예 |
이 값들은 나열할 수 있습니다. 즉, 이러한 특징을 동시에 가지는 효과를 지정할 수 있습니다.
아래 두 값은 위에서 언급한 값들을 지원하는 역할을 합니다. 제한된 변환의 호스트 좌표 공간을 표시하며, 특히 중첩된 뷰포트 좌표계(중첩된 콘텐츠나 중첩 ‘svg’ 요소 등)에 속하는 요소에서 효과적입니다. 지정하지 않은 경우 초기값은 viewport입니다.
참고: 향후 SVG 버전에서는 장치 좌표계를 지정하는 방법이 추가될 수 있습니다.
이 섹션에서는 non-scaling-stroke처럼 명확한 동작을 제외하고, 벡터 효과의 동작을 명확히 하기 위한 값의 조합에 따른 변환 수식 목록을 보여줍니다.
vector-effect 속성은 3D 렌더링 컨텍스트에서 수행되는 변환에는 영향을 주지 않습니다.
사용자 좌표계에서 뷰포트 좌표계로의 일반 좌표 변환 수식은 다음과 같습니다.
<circle vector-effect="veValue" transform="translate(xo yo)" cx="xf" cy="yf" r=".."/>
위와 같이 vector-effect가 요소에 추가되면, 사용자 좌표에서 디바이스 좌표로의 변환 수식이 다음과 같이 변경됩니다. 여기서 xf와 yf는 해당 요소 및 자손의 사용자 좌표이고, xo와 yo는 해당 요소의 transform 속성 행렬 요소 e와 f입니다. 또한 |det(CTM)|는 CTM의 행렬식의 절댓값입니다. 이 값이 0이 되고 non-scaling-size가 지정된 경우, vector-effect는 무효로 처리되어 none으로 간주됩니다.
veValue | 수식 |
---|---|
non-scaling-size |
|
non-rotation |
|
non-scaling-size non-rotation |
|
fixed-position |
|
fixed-position non-scaling-size |
|
fixed-position non-rotation |
|
fixed-position non-scaling-size non-rotation |
|
아래는 벡터 효과 없이 중첩된 뷰포트 좌표계에 대한 일반 좌표 변환 수식입니다. xviewport(UA)와 yviewport(UA)는 사용자 에이전트가 직접 제어하는 좌표입니다. CTMthis는 대상 그래픽의 사용자 좌표계에서 해당 그래픽이 속한 뷰포트 좌표계로의 CTM 변환 행렬을 의미합니다. CTMparent는 앞서 언급한 뷰포트 좌표계에서 부모의 뷰포트 좌표계로의 CTM 변환 행렬입니다. 그리고 CTMroot는 최상위(UA) 뷰포트 좌표계에 대한 CTM입니다.
앞 절의 7가지 수식을 중첩된 뷰포트 좌표계에 적용할 때, vector-effect의 추가 값으로 viewport 또는 screen이 지정되었는지에 따라 수식의 적용 방식이 다음과 같이 달라집니다.
viewport 값이 지정된 경우, 사용자 에이전트는 앞 장의 7가지 수식 중 하나와 아래의 수식을 조합하여 좌표를 계산합니다.
screen 값이 지정된 경우, 사용자 에이전트는 앞 장의 7가지 수식 중 하나와 아래의 수식을 조합하여 좌표를 계산합니다.
아래는 non-scaling-stroke vector-effect의 예시입니다.
<?xml version="1.0"?> <svg xmlns="http://www.w3.org/2000/svg" width="6cm" height="4cm" viewBox="0 0 600 400" viewport-fill="rgb(255,150,200)"> <desc>non-scaling stroke 예시</desc> <rect x="1" y="1" width="598" height="398" fill="none" stroke="black"/> <g transform="scale(9,1)"> <line stroke="black" stroke-width="5" x1="10" y1="50" x2="10" y2="350"/> <line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5" x1="32" y1="50" x2="32" y2="350"/> <line vector-effect="none" stroke="black" stroke-width="5" x1="55" y1="50" x2="55" y2="350"/> </g> </svg>
아래는 none vector-effect (벡터 효과 없음) 예시입니다.
CTM 변경 전 | CTM 변경 후 |
소스 코드
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50,-50,500,500" height="500" width="500"> <rect x="-50" y="-50" width="500" height="500" stroke="orange" stroke-width="3" fill="none"/> <!-- 중첩 사용자 좌표계는 이 transform 속성에 의해 변환됨 --> <g transform="matrix(2.1169438081370817,0.3576047954311102,-0.3576047954311102,1.4700998667618626,0,0) translate(-50,-50)"> <svg viewBox="-50,-50,500,500" height="500" width="500"> <!-- 이 svg의 기본 사용자 좌표계에 그래프 종이 그리기 --> <g stroke="green" stroke-width="1" fill="none"> <circle cx="0" cy="0" r="10"/> <circle cx="150" cy="150" r="7"/> <path fill="green" stroke="none" d="M0,-3 L30,-3 25,-10 50,0 25,10 30,3 0,3z"/> <line x1="-100" y1="-100" x2="600" y2="-100" stroke-dasharray="5,5"/> <line x1="-100" y1="000" x2="600" y2="000"/> <line x1="-100" y1="100" x2="600" y2="100" stroke-dasharray="5,5"/> <line x1="-100" y1="200" x2="600" y2="200" stroke-dasharray="5,5"/> <line x1="-100" y1="300" x2="600" y2="300" stroke-dasharray="5,5"/> <line x1="-100" y1="400" x2="600" y2="400" stroke-dasharray="5,5"/> <line x1="-100" y1="500" x2="600" y2="500" stroke-dasharray="5,5"/> <line y1="-100" x1="-100" y2="600" x2="-100" stroke-dasharray="5,5"/> <line y1="-100" x1="000" y2="600" x2="000"/> <line y1="-100" x1="100" y2="600" x2="100" stroke-dasharray="5,5"/> <line y1="-100" x1="200" y2="600" x2="200" stroke-dasharray="5,5"/> <line y1="-100" x1="300" y2="600" x2="300" stroke-dasharray="5,5"/> <line y1="-100" x1="400" y2="600" x2="400" stroke-dasharray="5,5"/> <line y1="-100" x1="500" y2="600" x2="500" stroke-dasharray="5,5"/> </g> <!-- 벡터 효과가 있는 도형 --> <!-- 이 도형의 중첩 사용자 좌표계 원점에 두꺼운 빨간색 오른쪽 화살표와 작은 사각형 --> <path id="ve" vector-effect="none" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/> </svg> </g> </svg>
아래는 non-scaling-size 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-scaling-size" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 non-rotation 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-rotation" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 non-scaling-size non-rotation 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-scaling-size non-rotation" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 fixed-position 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 non-scaling-size fixed-position 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-scaling-size fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 non-rotation fixed-position 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-rotation fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
아래는 non-scaling-size non-rotation fixed-position 예시입니다.
CTM 변경 전 | CTM 변경 후 |
<path id="ve" vector-effect="non-scaling-size non-rotation fixed-position" stroke="red" stroke-width="3" fill="none" transform="matrix(1,0,0,1,150,150)" d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
SVGTransform 인터페이스는 <transform-function> 값들을 표현하는 데 사용됩니다. 이 값들은 transform 속성과 그 표현 속성 ‘transform’, ‘gradientTransform’, ‘patternTransform’ 등에서 나타납니다. SVGTransform은 변환 리스트에서 하나의 구성 요소를 나타내며, 예를 들면 scale(…) 또는 matrix(…) 값 하나를 의미합니다.
SVGTransform 객체는 읽기 전용으로 지정될 수 있습니다. 읽기 전용으로 지정된 객체를 수정하려고 하면 아래에 설명한 것처럼 예외가 발생합니다.
SVGTransform 객체는 특정 요소와 연결될 수 있습니다. 연결된 요소는 객체가 reflect할 때 어느 요소의 ‘transform’ 표현 속성을 갱신할지 결정하는 데 사용됩니다. 별도로 설명하지 않는 한, SVGTransform 객체는 어떤 요소에도 연결되어 있지 않습니다.
모든 SVGTransform 객체는 두 가지 모드 중 하나로 동작합니다. 다음과 같습니다:
SVGTransform 객체는 내부적으로 <transform-function> 값을 유지하며, 이것을 value라고 합니다. 또한 DOMMatrix 객체도 유지하며, 이를 matrix object라고 합니다. 이는 matrix IDL 속성에서 반환되는 객체입니다. SVGTransform 객체의 matrix object는 항상 value와 동기화됩니다.
[Exposed=Window] interface SVGTransform { // Transform Types const unsigned short SVG_TRANSFORM_UNKNOWN = 0; const unsigned short SVG_TRANSFORM_MATRIX = 1; const unsigned short SVG_TRANSFORM_TRANSLATE = 2; const unsigned short SVG_TRANSFORM_SCALE = 3; const unsigned short SVG_TRANSFORM_ROTATE = 4; const unsigned short SVG_TRANSFORM_SKEWX = 5; const unsigned short SVG_TRANSFORM_SKEWY = 6; readonly attribute unsigned short type; [SameObject] readonly attribute DOMMatrix matrix; readonly attribute float angle; void setMatrix(DOMMatrixReadOnly matrix); void setTranslate(float tx, float ty); void setScale(float sx, float sy); void setRotate(float angle, float cx, float cy); void setSkewX(float angle); void setSkewY(float angle); };
SVGTransform에 정의된 숫자 변환 타입 상수는 SVGTransform의 value 타입을 나타내는 데 사용됩니다. 각 상수의 의미는 다음과 같습니다:
상수 | 의미 |
---|---|
SVG_TRANSFORM_MATRIX | matrix(…) 값입니다. |
SVG_TRANSFORM_TRANSLATE | translate(…) 값입니다. |
SVG_TRANSFORM_SCALE | scale(…) 값입니다. |
SVG_TRANSFORM_ROTATE | rotate(…) 값입니다. |
SVG_TRANSFORM_SKEWX | skewX(…) 값입니다. |
SVG_TRANSFORM_SKEWY | skewY(…) 값입니다. |
SVG_TRANSFORM_UNKNOWN | 그 밖의 변환 유형 값입니다. |
숫자 변환 타입 상수를 사용하는 것은 안티패턴이며, SVGTransform에서 지원하는 변환 타입에 대해 새로운 상수 값은 도입하지 않습니다. 다른 타입의 변환이 지원되고 사용될 경우 SVGTransform은 SVG_TRANSFORM_UNKNOWN 타입을 사용합니다. 다른 변환 타입에서 SVGTransform의 속성이 어떻게 동작하는지에 대한 자세한 내용은 아래를 참고하세요.
type IDL 속성은 SVGTransform의 value가 어떤 변환 항목 타입인지 나타냅니다. type을 가져올 때 다음 단계가 실행됩니다:
예를 들어 scaleX(…) 또는 translate3d(…) 변환의 경우 SVG_TRANSFORM_UNKNOWN이 반환됩니다.
matrix IDL 속성은 변환을 4x4 동차 행렬로 나타내며, 가져올 때 SVGTransform의 matrix object를 반환합니다. matrix object가 처음 생성될 때, SVGTransform의 변환 함수 value에 맞게 값이 설정되며, SVGTransform을 반영하도록 설정됩니다.
다양한 변환 함수 타입이 특정 행렬 값에 어떻게 대응하는지에 대한 설명은 CSS Transforms 명세를 참고하세요.
angle IDL 속성은 rotate(…), skewX(…), skewY(…) 변환 함수의 각도 파라미터를 나타냅니다. 가져올 때 다음 단계가 실행됩니다:
setMatrix 메서드는 SVGTransform을 주어진 행렬 값으로 설정합니다. setMatrix(matrix)가 호출되면 다음 단계가 실행됩니다:
setTranslate, setScale, setRotate, setSkewX, setSkewY 메서드는 SVGTransform을 새로운 변환 함수 값으로 설정합니다. 이들 메서드 중 하나가 호출되면 다음 단계가 실행됩니다:
이 명세는 DOMMatrix 객체의 동작에 대해 Geometry Interfaces 명세에서 설명한 것 이상으로 추가 요구사항을 부여합니다. 이를 통해 변환 값을 가지는 표현 속성에 반영할 수 있습니다.
모든 DOMMatrix 객체는 두 가지 모드 중 하나로 동작합니다. 다음과 같습니다:
DOMMatrix는 읽기 전용으로 지정될 수 있습니다. 읽기 전용 객체를 수정하려고 하면 내부 값을 갱신하는 대신 예외가 발생합니다. 읽기 전용 DOMMatrix의 IDL 속성에 값을 할당하거나, 변경 가능한 변환 메서드를 호출하면 NoModificationAllowedError 예외가 발생합니다.
이 내용은 읽기-쓰기 DOMMatrix 인터페이스에만 적용됩니다. DOMMatrixReadOnly 인터페이스는 transform을 반영하는 데 사용되지 않으며, 이미 수정 시 예외를 발생시킵니다.
쓰기 가능한 DOMMatrix의 IDL 속성에 값을 할당하거나 변경 가능한 변환 메서드를 호출하면, 내부 행렬 값을 갱신한 후 다음 단계가 실행됩니다:
SVGTransformList 인터페이스는 리스트 인터페이스로, 각 요소는 SVGTransform 객체입니다. SVGTransformList는 transform 속성의 값(즉, <transform-list> 또는 키워드 none)을 표현합니다.
[Exposed=Window] interface SVGTransformList { readonly attribute unsigned long length; readonly attribute unsigned long numberOfItems; void clear(); SVGTransform initialize(SVGTransform newItem); getter SVGTransform getItem(unsigned long index); SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index); SVGTransform replaceItem(SVGTransform newItem, unsigned long index); SVGTransform removeItem(unsigned long index); SVGTransform appendItem(SVGTransform newItem); setter void (unsigned long index, SVGTransform newItem); // 다른 리스트 인터페이스에는 없는 추가 메서드. SVGTransform createSVGTransformFromMatrix(DOMMatrixReadOnly matrix); SVGTransform? consolidate(); };
createSVGTransformFromMatrix 메서드는 행렬 객체로부터 새로운 SVGTransform 객체를 생성하는 데 사용됩니다. createSVGTransformFromMatrix(matrix) 메서드가 호출되면, 다음 단계를 진행합니다:
consolidate 메서드는 변환 리스트를 단일 변환 함수로 동등하게 변환하는 데 사용됩니다. consolidate()가 호출되면, 다음 단계를 진행합니다:
SVGLengthList의 나머지 인터페이스 멤버의 동작은 리스트 인터페이스에서 정의됩니다.
SVGAnimatedTransformList 객체는 reflect를 통해 transform 속성과 그 표현 속성을 반영하는 데 사용됩니다. (요소에 따라 ‘transform’, ‘gradientTransform’, ‘patternTransform’ 중 하나)
[Exposed=Window] interface SVGAnimatedTransformList { [SameObject] readonly attribute SVGTransformList baseVal; [SameObject] readonly attribute SVGTransformList animVal; };
baseVal과 animVal IDL 속성은 반영된 표현 속성의 값을 나타냅니다. baseVal 또는 animVal을 가져오면, 주어진 표현 속성을 반영하는 SVGTransformList 객체가 반환됩니다.
SVGPreserveAspectRatio 인터페이스는 ‘preserveAspectRatio’ 속성의 값을 표현하는 데 사용됩니다.
SVGPreserveAspectRatio 객체는 읽기 전용으로 지정될 수 있습니다. 읽기 전용 객체를 수정하려고 하면 아래에 설명된 대로 예외가 발생합니다.
모든 SVGPreserveAspectRatio 객체는 reflect된 ‘preserveAspectRatio’ 속성의 기본 값을 반영합니다 (baseVal 또는 animVal 멤버의 메서드를 통해 노출되는 SVGAnimatedPreserveAspectRatio에서).
[Exposed=Window] interface SVGPreserveAspectRatio { // 정렬 타입 const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0; const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1; const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2; const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3; const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4; const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMID = 5; const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMID = 6; const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMID = 7; const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMAX = 8; const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9; const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10; // Meet-or-slice 타입 const unsigned short SVG_MEETORSLICE_UNKNOWN = 0; const unsigned short SVG_MEETORSLICE_MEET = 1; const unsigned short SVG_MEETORSLICE_SLICE = 2; attribute unsigned short align; attribute unsigned short meetOrSlice; };
SVGPreserveAspectRatio에 정의된 숫자 정렬 타입 상수는 ‘preserveAspectRatio’ 속성이 가질 수 있는 정렬 키워드 값을 나타냅니다. 각 상수의 의미는 다음과 같습니다:
상수 | 의미 |
---|---|
SVG_PRESERVEASPECTRATIO_NONE | none 키워드. |
SVG_PRESERVEASPECTRATIO_XMINYMIN | xMinYMin 키워드. |
SVG_PRESERVEASPECTRATIO_XMIDYMIN | xMidYMin 키워드. |
SVG_PRESERVEASPECTRATIO_XMAXYMIN | xMaxYMin 키워드. |
SVG_PRESERVEASPECTRATIO_XMINYMID | xMinYMid 키워드. |
SVG_PRESERVEASPECTRATIO_XMIDYMID | xMidYMid 키워드. |
SVG_PRESERVEASPECTRATIO_XMAXYMID | xMaxYMid 키워드. |
SVG_PRESERVEASPECTRATIO_XMINYMAX | xMinYMax 키워드. |
SVG_PRESERVEASPECTRATIO_XMIDYMAX | xMidYMax 키워드. |
SVG_PRESERVEASPECTRATIO_XMAXYMAX | xMaxYMax 키워드. |
SVG_PRESERVEASPECTRATIO_UNKNOWN | 그 밖의 값. |
마찬가지로, SVGPreserveAspectRatio에 정의된 숫자 meet-or-slice 타입 상수는 ‘preserveAspectRatio’ 속성이 가질 수 있는 meet-or-slice 키워드 값을 나타냅니다. 각 상수의 의미는 다음과 같습니다:
상수 | 의미 |
---|---|
SVG_MEETORSLICE_MEET | meet 키워드. |
SVG_MEETORSLICE_SLICE | slice 키워드. |
SVG_MEETORSLICE_UNKNOWN | 그 밖의 값. |
align IDL 속성은 ‘preserveAspectRatio’ 값의 정렬 키워드 부분을 나타냅니다. 가져올 때 다음 단계를 실행합니다:
align을 설정하면 다음 단계를 실행합니다:
meetOrSlice IDL 속성은 ‘preserveAspectRatio’ 값의 meet-or-slice 키워드 부분을 나타냅니다. 가져올 때 다음 단계를 실행합니다:
meetOrSlice를 설정하면 다음 단계를 실행합니다:
SVGAnimatedPreserveAspectRatio 객체는 ‘preserveAspectRatio’ 속성을 reflect하는 데 사용됩니다.
[Exposed=Window] interface SVGAnimatedPreserveAspectRatio { [SameObject] readonly attribute SVGPreserveAspectRatio baseVal; [SameObject] readonly attribute SVGPreserveAspectRatio animVal; };
baseVal 및 animVal IDL 속성은 반영된 ‘preserveAspectRatio’ 속성의 현재 애니메이션되지 않은 값을 나타냅니다. baseVal 또는 animVal을 가져올 때, SVGPreserveAspectRatio 객체가 반환되며, 해당 객체가 기본값을 반영합니다. 이 기본값은 ‘preserveAspectRatio’ 속성의 기본값이며, 객체가 반영하는 IDL 속성 타입이 SVGAnimatedPreserveAspectRatio인 경우, 그 객체가 얻어진 SVG 요소의 값을 반영합니다.