8장: 좌표계, 변환 및 단위

8.1. 소개

모든 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 뷰포트는 캔버스 안에 내장되어 있으며, 캔버스는 모든 관련 차원에서 무한히 큰 그리기 영역입니다.

8.2. SVG 뷰포트의 등가 변환 계산하기

이 과정은 viewBox 속성의 min-x, min-y, width, height 값과, viewBox 속성이 정의된 요소의 위치 및 크기, 해당 요소의 preserveAspectRatio 속성 값을 변환 및 스케일로 변환하여 요소가 포함하는 콘텐츠에 적용합니다.

  1. vb-x, vb-y, vb-width, vb-height는 각각 viewBox 속성의 min-x, min-y, width, height 값이다.
  2. e-x, e-y, e-width, e-height는 각각 해당 요소의 위치와 크기이다.
  3. align은 preserveAspectRatio의 align 값이며, preserveAspectRatio가 정의되지 않은 경우 'xMidYMid'로 한다.
  4. meetOrSlice는 preserveAspectRatio의 meetOrSlice 값이며, preserveAspectRatio가 정의되지 않았거나 meetOrSlice 값이 없으면 'meet'로 한다.
  5. scale-xe-width/vb-width로 초기화한다.
  6. scale-ye-height/vb-height로 초기화한다.
  7. align이 'none'이 아니고 meetOrSlice가 'meet'이면, scale-xscale-y 중 큰 값을 작은 값으로 설정한다.
  8. 그렇지 않고 align이 'none'이 아니고 meetOrSlice가 'slice'이면 scale-xscale-y 중 작은 값을 큰 값으로 설정한다.
  9. translate-xe-x - (vb-x * scale-x)로 초기화한다.
  10. translate-ye-y - (vb-y * scale-y)로 초기화한다.
  11. align에 'xMid'가 포함되면 (e-width - vb-width * scale-x)/2를 translate-x에 더한다.
  12. align에 'xMax'가 포함되면 (e-width - vb-width * scale-x)를 translate-x에 더한다.
  13. align에 'yMid'가 포함되면 (e-height - vb-height * scale-y)/2를 translate-y에 더한다.
  14. align에 'yMax'가 포함되면 (e-height - vb-height * scale-y)를 translate-y에 더한다.

해당 요소가 포함하는 콘텐츠에 적용되는 변환은 translate(translate-x, translate-y) scale(scale-x, scale-y)로 주어집니다.

8.3. 초기 뷰포트

초기 뷰포트의 너비는 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>

8.4. 초기 좌표계

최상위 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 — SVG의 초기 좌표계

Example InitialCoords

이 예제를 SVG로 보기(SVG 지원 브라우저만)

8.5. ‘transform’ 속성

사용자 에이전트는 transform 속성과 표현 속성을 [css-transforms-1]에서 정의한 대로 지원해야 합니다.

8.6. ‘viewBox’ 속성

이름 초기값 애니메이션 가능
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>
예시 ViewBox
렌더링
SVG 뷰포트
width=300px,
height=200px
렌더링
SVG 뷰포트
width=150px,
height=200px
예시 ViewBox - 300 x 200에 맞춰 늘리기 예시 ViewBox - 150 x 200에 맞춰 늘리기

이 예제를 SVG로 보기 (SVG 지원 브라우저만)

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 요소의 경우 markerWidthmarkerHeight 속성)에는 영향을 주지 않습니다. 즉, 위의 예처럼 svg 요소가 widthheight 표현 속성, viewBox 속성을 가지고 있을 때, widthheightviewBox 변환이 적용되기 이전 좌표계의 값입니다. 반면 transform 속성처럼, 모든 다른 속성과 자손 요소에 대해서는 새로운 좌표계를 생성합니다.

8.7. ‘preserveAspectRatio’ 속성

이름 초기값 애니메이션 가능
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> 값 뒤에 하나 이상의 공백으로 구분되어야 하며 다음 문자열 중 하나여야 합니다:

예시 PreserveAspectRatiopreserveAspectRatio의 다양한 옵션을 보여줍니다. 이 예제는 최상위 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 — 사용 가능한 옵션 데모

예시 PreserveAspectRatio

8.8. 새로운 SVG 뷰포트 생성하기

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 뷰포트를 생성합니다:

역사적인 이유로, patternmarker 요소는 viewBox 속성을 받아들이지만 새로운 뷰포트를 생성하지 않습니다. clipPathmask 요소도 마찬가지입니다. 이들 요소의 콘텐츠 내에서의 백분율 길이는 그래픽 효과 영역의 크기에 비례하지 않습니다.

foreignObject 요소는 자식 콘텐츠에 대해 새로운 CSS 포함 블록을 생성합니다. video, audio, canvas 요소도 폴백 콘텐츠가 렌더링될 때 동일합니다. 이는 새로운 뷰포트와 유사한 효과를 가지며, 자식 콘텐츠의 레이아웃 범위를 초기화합니다. 하지만 foreignObject의 하위에 SVG 요소를 렌더링하려면 반드시 svg 요소가 SVG 문서 프래그먼트 및 SVG 뷰포트를 생성해야 합니다.

image 또는 iframe 요소는 참조된 문서에 대해 새로운 문서 뷰포트를 생성합니다. 참조된 문서가 SVG 파일이라면, 해당 문서는 자체 SVG 뷰포트를 생성합니다.

새로운 SVG 뷰포트가 추가적인 클리핑 경로도 생성하는지는 새로운 SVG 뷰포트를 생성하는 요소의 overflow 속성 값에 따라 결정됩니다.

8.9. 단위

SVG는 CSS 값과 단위 모듈 [css-values]의 공통 값 및 단위에 대한 설명과 정의를 따릅니다. 각 속성과 CSS 속성은 사용되는 구성 값 타입을 명확히 지정해야 합니다. CSS WG 또는 SVG WG에서 발행하는 후속 또는 확장 명세는 기본 데이터 타입을 확장하거나 새로운 데이터 타입을 추가할 수 있습니다.

<percentage> 값이 SVG 뷰포트 크기에 상대적인 경우:

예시 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 — 사용 가능한 옵션 데모

예시 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입니다. 하단 사각형은 백분율 단위로 지정된 값이 스케일될 때의 동작을 보여줍니다.

8.10. 경계 박스

경계 박스

요소의 경계 박스(bbox)는 해당 요소와 그 자손을 완전히 감싸는, 해당 요소의 사용자 좌표계 축에 정렬된 가장 꼭 맞는 사각형입니다.

요소에 대해 세 가지 종류의 경계 박스를 계산할 수 있습니다:

  1. 오브젝트 경계 박스는 요소의 기하학적 도형만을 포함하는 경계 박스입니다. 기본 도형의 경우 채워지는 영역입니다. 별도의 명시가 없는 한, "경계 박스"라는 용어는 이 오브젝트 경계 박스를 의미합니다.
  2. 스트로크 경계 박스는 요소의 기하학적 도형과 스트로크 도형을 포함하는 경계 박스입니다.
  3. 데코레이션 경계 박스는 요소의 기하학적 도형, 스트로크 도형, 마커까지 포함하는 경계 박스입니다.

요소의 opacity, visibility, fill, fill-opacity, fill-rule, stroke-dasharraystroke-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의 타입에 따라 다음과 같이 동작합니다:

a 도형
a 텍스트 콘텐츠 요소
텍스트 콘텐츠 요소 내부의 a 요소
  1. box를 (0, 0, 0, 0)으로 초기화한다.
  2. fill-shapeelement도형이면 등가 경로이고, 아니면 해당 요소 내 텍스트에 해당하는 각 글리프 셀을 포함하는 도형이다.
  3. fill이 true이면, boxfill-shapespace 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.

    fill, fill-opacityfill-rule 속성 값은 fill-shape에 영향을 주지 않는다.

  4. stroke가 true이고, 요소의 strokenone이 아닌 경우, boxbox와 요소의 스트로크 도형space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형의 합집합으로 설정한다(대시 패턴 없음으로 가정).

    stroke-opacity, stroke-dasharraystroke-dashoffset 값은 스트로크 도형 계산에 영향을 주지 않는다.

  5. markers가 true이면, 요소에 렌더링된 각 마커 marker에 대해:
    1. marker 요소의 marker 콘텐츠를 정의하는 각 자손 그래픽 요소 child에 대해:
      1. childmarker 내 상위 요소 중 'display: none'이거나, 조건 처리 속성이 실패하거나, a, g, svg, switch 요소가 아니면, 다음 자손 그래픽 요소로 넘어간다.
      2. 그렇지 않으면, boxboxchild를 요소, space를 좌표계, fill, stroke, markers를 true, clippedclipped로 하여 경계 박스 계산 알고리즘을 호출한 결과의 합집합으로 설정한다.
  6. clipped가 true이고, elementclip-path 값이 none이 아니면, boxbox와 클리핑 경로의 교집합을 space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.
  7. box를 반환한다.
컨테이너 요소
use
  1. box를 (0, 0, 0, 0)으로 초기화한다.
  2. parent는 컨테이너 요소이면 해당 요소, 아니면 use 요소의 shadow tree 루트이다.
  3. parent의 각 자손 그래픽 요소 child에 대해:
    1. child렌더링되지 않음이면 다음 자손 그래픽 요소로 넘어간다.
    2. 그렇지 않으면, boxboxchild를 요소로, space, fill, stroke, markers, clipped 값을 동일하게 하여 경계 박스 계산 알고리즘을 호출한 결과의 합집합으로 설정한다.
  4. clipped가 true이면:
    • elementclip-path 값이 none이 아니면, boxbox와 클리핑 경로의 교집합을 space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.
    • elementoverflow 속성이 적용되고 값이 visible이 아니면, boxbox와 요소의 overflow 경계의 교집합을 space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.
    • elementclip 속성이 적용되고 값이 auto가 아니면, boxboxclip으로 지정된 사각형의 교집합을 space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.
  5. box를 반환한다.
canvas
foreignObject
iframe
image
video
  1. boxspace 좌표계 내에서 해당 요소의 포지셔닝 사각형(‘x’, ‘y’, ‘width’, ‘height’ 기하 속성)으로 정의되는 가장 꼭 맞는 사각형으로 설정한다.

    이 알고리즘의 fill, stroke, markers 입력 인자는 이러한 요소의 경계 박스 반환값에 영향을 주지 않는다.

  2. clipped가 true이고 elementclip-path 값이 none이 아니면, boxbox와 클리핑 경로의 교집합을 space 좌표계 내에서 가장 꼭 맞게 감싸는 사각형으로 설정한다.
  3. box를 반환한다.

(0, 0, 0, 0) 값과 빈 도형을 가진 box의 합집합은 box입니다.

요소의 오브젝트 경계 박스, 스트로크 경계 박스 또는 장식 경계 박스는 위의 경계 박스 계산 알고리즘을 다음 인수로 호출한 결과입니다: element는 해당 요소 자체, space는 요소의 사용자 좌표계, fill은 true, stroke스트로크 경계 박스 또는 장식 경계 박스를 계산할 때 true, 그렇지 않으면 false, markers장식 경계 박스를 계산할 때 true, 그렇지 않으면 false, clipped는 false입니다.

8.11. 오브젝트 경계 박스 단위

다음 요소들은 지정된 속성을 해당 요소에 '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가 지정된 경우, 해당 효과(예: 그라디언트 또는 필터)는 무시됩니다.

8.12. SVG 콘텐츠의 고유 크기 속성

CSS로 포맷된 호스트 문서에 SVG를 포함할 수 있도록 하려면 구체적인 객체 크기를 계산해야 합니다. 구체적인 객체 크기는 CSS Images 3 [css-images-3]에서 정의된 기본 크기 알고리즘을 사용하여 다음 입력값으로 계산해야 합니다:

명시된 크기svg 요소의 widthheight 크기 속성의 사용 값에서 결정해야 합니다.

고유 치수 역시 widthheight 크기 속성에서 결정해야 합니다. 만약 widthheight 중 하나가 지정되지 않았다면, 사용 값은 초기값 'auto'입니다. 'auto' 및 백분율 길이는 고유 너비고유 높이를 결정하는 데 사용하면 안 됩니다.

비트맵 이미지 포맷의 경우 고유 치수는 이미지 파일에 고정되어 있고, 호스트 문서에서 필요한 만큼 이미지 크기를 지정하여 스케일합니다. SVG는 본질적으로 확장 가능하므로, 고유 너비고유 높이명시된 크기의 너비와 높이로 맞춥니다. 따라서 길이로 지정할 경우 svg 요소의 widthheight 크기 속성이 SVG 이미지의 고유 치수와 호스트 문서에 SVG 이미지를 배치할 때 사용하는 명시된 크기를 결정합니다.

고유 종횡비는 다음 알고리즘을 사용하여 계산해야 합니다. 알고리즘이 null을 반환하면 고유 종횡비가 없습니다.

  1. svg 요소의 widthheight 크기 속성이 모두 절대값이면:
    1. width / height를 반환
  2. SVG View가 활성화되어 있으면:
    1. viewbox를 활성 SVG View에서 정의된 viewbox로 지정
    2. viewbox.width / viewbox.height 반환
  3. svg 요소의 viewBox가 올바르게 지정되어 있으면:
    1. viewboxsvg 요소의 viewBox 속성에서 정의된 viewbox로 지정
    2. viewbox.width / viewbox.height 반환
  4. null 반환

이 섹션에서 정의하는 동작은 CSS에 특화되어 있지만, 다른 호스트 컨텍스트로도 적용할 수 있습니다. 모든 호스트 컨텍스트에서, 고유 종횡비가 있을 경우 SVG 뷰포트 크기를 지정할 때 반드시 이를 존중해야 합니다.

예시:

예시: 고유 종횡비 1
<svg xmlns="http://www.w3.org/2000/svg"
     width="10cm" height="5cm">
  ...
</svg>

이 예시에서 SVG 뷰포트의 고유 종횡비는 2:1입니다. 고유 너비는 10cm이고 고유 높이는 5cm입니다.

예시: 고유 종횡비 2
<svg xmlns="http://www.w3.org/2000/svg"
     width="100%" height="50%" viewBox="0 0 200 200">
  ...
</svg>

이 예시에서 최상위 SVG 뷰포트의 고유 종횡비는 1:1입니다. 이 경우의 종횡비 계산은 한 방향만 제한된 포함 블록 내에 오브젝트를 임베드할 수 있게 해줍니다.

예시: 고유 종횡비 3
<svg xmlns="http://www.w3.org/2000/svg"
     width="10cm" viewBox="0 0 200 200">
  ...
</svg>

이 경우 고유 종횡비는 1:1입니다.

예시: 고유 종횡비 4
<svg xmlns="http://www.w3.org/2000/svg"
     width="75%" height="10cm" viewBox="0 0 200 200">
  ...
</svg>

이 예시에서 고유 종횡비는 1:1입니다.

새로운 auto 값에 대한 예시를 더 추가해야 할까요? 예를 들어 David Vest가 제공한 예시 등.

8.13. 벡터 효과

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-effectnon-scaling-strokenone 이외의 값들은 구현이 부족해 SVG 2에서 제외될 위험이 있습니다. 구현자들이 현재 명세대로 구현하는 실용성에 대해 피드백을 주시기 바랍니다. 구현 기간 중 의견을 요청합니다.

이름: vector-effect
값: none | [ non-scaling-stroke | non-scaling-size | non-rotation | fixed-position ]+ [ viewport | screen ]?
초기값: none
적용 대상: 그래픽 요소use
상속: 아니오
백분율: N/A
미디어: 시각적
계산된 값: 지정된 값 그대로
애니메이션 가능:
none
벡터 효과를 적용하지 않음을 지정합니다. 즉, SVG 1.1에서의 기본 렌더링 동작을 사용합니다. 이는 도형의 기하를 지정된 페인트로 채우고, 외곽선을 지정된 페인트로 그리는 방식입니다.
non-scaling-stroke
페인팅의 벡터 효과에 대해서는 이 설명을 참고하세요.
non-scaling-size
이 효과는 다음 특징을 가진 제한된 변환을 통해 해당 요소와 자손에 대해 특수 사용자 좌표계를 지정합니다. CTM이 호스트 좌표 공간에서 변경되어도 사용자 좌표계의 스케일은 변하지 않습니다. 단, 회전과 기울임(shear) 억제는 지정하지 않으며, 사용자 좌표계의 위치 고정도 지정하지 않습니다. non-scaling-size는 사용자 좌표계의 스케일 억제 특성을 가지므로 non-scaling-stroke 특성도 포함합니다. 변환 수식과 예시 동작은 다음 장에서 설명합니다.
non-rotation
이 효과는 다음 특징을 가진 제한된 변환을 통해 해당 요소와 자손에 대해 특수 사용자 좌표계를 지정합니다. CTM이 호스트 좌표 공간에서 변경되어도 사용자 좌표계의 회전과 기울임이 억제됩니다. 단, 스케일 억제는 지정하지 않으며, 사용자 좌표계의 위치 고정도 지정하지 않습니다. 변환 수식과 예시 동작은 다음 장에서 설명합니다.
fixed-position
이 효과는 다음 특징을 가진 제한된 변환을 통해 해당 요소와 자손에 대해 특수 사용자 좌표계를 지정합니다. CTM이 호스트 좌표 공간에서 변경되어도 사용자 좌표계의 위치가 고정됩니다. 단, 회전, 기울임, 스케일 억제는 지정하지 않습니다. fixed-position 효과가 있고 transform 속성이 있을 경우, 해당 속성은 이 효과에 사용됩니다. transform 행렬의 이동 성분 ef는 고정된 사용자 좌표계의 원점을 이동하는 데 사용됩니다. 변환 수식과 예시 동작은 다음 장에서 설명합니다.

이 값들은 나열할 수 있습니다. 즉, 이러한 특징을 동시에 가지는 효과를 지정할 수 있습니다.

아래 두 값은 위에서 언급한 값들을 지원하는 역할을 합니다. 제한된 변환의 호스트 좌표 공간을 표시하며, 특히 중첩된 뷰포트 좌표계(중첩된 콘텐츠나 중첩 svg 요소 등)에 속하는 요소에서 효과적입니다. 지정하지 않은 경우 초기값은 viewport입니다.

viewport
즉시 뷰포트 좌표계를 호스트 좌표 공간으로 지정합니다. 해당 요소가 중첩된 뷰포트 좌표계에 속하는 경우, 벡터 효과는 해당 요소가 직접 속한 뷰포트 좌표계에 적용됩니다. 즉, 벡터 효과는 상위 CTM의 변경에는 적용되지 않습니다.
screen
콘텐츠의 좌표계를 사용자 에이전트가 즉시 제어하는 좌표계로 지정합니다. 즉, 사용자 에이전트가 갖는 "스크린"입니다. (SVGT1.2에서는 "스크린 좌표 공간") 해당 요소가 중첩된 뷰포트 좌표계에 속해 있어도, 이 벡터 효과는 모든 계층의 CTM 변경에 항상 적용됩니다. SVG 구현체가 CSS 호환 px 단위를 지원하는 사용자 에이전트의 일부라면, 이는 루트 콘텐츠의 CSS 픽셀 좌표계입니다. 일반적으로 장치의 실제 픽셀(도트)과 CSS 픽셀은 사용자 에이전트의 줌 기능이나 dpi 변화로 인해 항상 동일하지 않습니다. (해상도 [CSS Values and Units Module Level 3] 참고) 따라서 이 값은 해당 장치 좌표계로의 제한된 변환을 지정하지 않습니다.

참고: 향후 SVG 버전에서는 장치 좌표계를 지정하는 방법이 추가될 수 있습니다.

8.13.1. 벡터 효과 계산하기

이 섹션에서는 non-scaling-stroke처럼 명확한 동작을 제외하고, 벡터 효과의 동작을 명확히 하기 위한 값의 조합에 따른 변환 수식 목록을 보여줍니다.

vector-effect 속성은 3D 렌더링 컨텍스트에서 수행되는 변환에는 영향을 주지 않습니다.

사용자 좌표계에서 뷰포트 좌표계로의 일반 좌표 변환 수식은 다음과 같습니다.

...
<circle vector-effect="veValue" transform="translate(xo yo)" cx="xf" cy="yf" r=".."/>

위와 같이 vector-effect가 요소에 추가되면, 사용자 좌표에서 디바이스 좌표로의 변환 수식이 다음과 같이 변경됩니다. 여기서 xfyf는 해당 요소 및 자손의 사용자 좌표이고, xoyo는 해당 요소의 transform 속성 행렬 요소 ef입니다. 또한 |det(CTM)|CTM의 행렬식의 절댓값입니다. 이 값이 0이 되고 non-scaling-size가 지정된 경우, vector-effect는 무효로 처리되어 none으로 간주됩니다.

det CTM = a ctm d ctm - b ctm c ctm
veValue 수식
non-scaling-size
x viewport y viewport 1 = CTM 0 0 1 + CTM det CTM 1 0 0 0 1 0 0 0 0 x f y f 1
non-rotation
x viewport y viewport 1 = CTM 0 0 1 + det CTM 1 0 0 0 1 0 0 0 0 x f y f 1
non-scaling-size non-rotation
x viewport y viewport 1 = CTM 0 0 1 + 1 0 0 0 1 0 0 0 0 x f y f 1
fixed-position
x viewport y viewport 1 = x o y o 1 + CTM 1 0 0 0 1 0 0 0 0 x f y f 1
fixed-position non-scaling-size
x viewport y viewport 1 = x o y o 1 + CTM det CTM 1 0 0 0 1 0 0 0 0 x f y f 1
fixed-position non-rotation
x viewport y viewport 1 = x o y o 1 + det CTM 1 0 0 0 1 0 0 0 0 x f y f 1
fixed-position non-scaling-size non-rotation
x viewport y viewport 1 = x o y o 1 + 1 0 0 0 1 0 0 0 0 x f y f 1

8.13.2. 중첩 뷰포트 좌표계의 벡터 효과 계산하기

아래는 벡터 효과 없이 중첩된 뷰포트 좌표계에 대한 일반 좌표 변환 수식입니다. xviewport(UA)yviewport(UA)사용자 에이전트가 직접 제어하는 좌표입니다. CTMthis는 대상 그래픽의 사용자 좌표계에서 해당 그래픽이 속한 뷰포트 좌표계로의 CTM 변환 행렬을 의미합니다. CTMparent는 앞서 언급한 뷰포트 좌표계에서 부모의 뷰포트 좌표계로의 CTM 변환 행렬입니다. 그리고 CTMroot는 최상위(UA) 뷰포트 좌표계에 대한 CTM입니다.

x viewport(UA) y viewport(UA) 1 = CTM root ... CTM parent CTM this x userspace y userspace 1

앞 절의 7가지 수식을 중첩된 뷰포트 좌표계에 적용할 때, vector-effect의 추가 값으로 viewport 또는 screen이 지정되었는지에 따라 수식의 적용 방식이 다음과 같이 달라집니다.

viewport 값이 지정된 경우, 사용자 에이전트는 앞 장의 7가지 수식 중 하나와 아래의 수식을 조합하여 좌표를 계산합니다.

x viewport ( UA ) y viewport ( UA ) 1 = CTM root ... CTM parent x viewport y viewport 1 CTM = CTM this

screen 값이 지정된 경우, 사용자 에이전트는 앞 장의 7가지 수식 중 하나와 아래의 수식을 조합하여 좌표를 계산합니다.

x viewport ( UA ) y viewport ( UA ) 1 = x viewport y viewport 1 CTM = CTM root ... CTM parent CTM this

8.13.3. 벡터 효과 예시

아래는 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 변경 후
벡터 효과가 나타나기 전 모습 non-scaling-size 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 non-rotation 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 non-scaling-size non-rotation 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 fixed-position 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 non-scaling-size fixed-position 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 non-rotation fixed-position 벡터 효과 이미지
<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 변경 후
벡터 효과가 나타나기 전 모습 non-scaling-size non-rotation fixed-position 벡터 효과 이미지
<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"/>

8.14. DOM 인터페이스

8.14.1. SVGTransform 인터페이스

SVGTransform 인터페이스는 <transform-function> 값들을 표현하는 데 사용됩니다. 이 값들은 transform 속성과 그 표현 속성 ‘transform’, gradientTransform, patternTransform 등에서 나타납니다. SVGTransform은 변환 리스트에서 하나의 구성 요소를 나타내며, 예를 들면 scale(…) 또는 matrix(…) 값 하나를 의미합니다.

SVGTransform 객체는 읽기 전용으로 지정될 수 있습니다. 읽기 전용으로 지정된 객체를 수정하려고 하면 아래에 설명한 것처럼 예외가 발생합니다.

SVGTransform 객체는 특정 요소와 연결될 수 있습니다. 연결된 요소는 객체가 reflect할 때 어느 요소의 ‘transform’ 표현 속성을 갱신할지 결정하는 데 사용됩니다. 별도로 설명하지 않는 한, SVGTransform 객체는 어떤 요소에도 연결되어 있지 않습니다.

모든 SVGTransform 객체는 두 가지 모드 중 하나로 동작합니다. 다음과 같습니다:

  1. 표현 속성 값의 일부를 반영 (baseVal 멤버의 메서드를 통해 노출되는 SVGAnimatedTransformList의 경우),
  2. 분리됨, SVGTransform 객체가 createSVGTransform 또는 createSVGTransformFromMatrix로 생성된 경우입니다.

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에 정의된 숫자 변환 타입 상수는 SVGTransformvalue 타입을 나타내는 데 사용됩니다. 각 상수의 의미는 다음과 같습니다:

상수 의미
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에서 지원하는 변환 타입에 대해 새로운 상수 값은 도입하지 않습니다. 다른 타입의 변환이 지원되고 사용될 경우 SVGTransformSVG_TRANSFORM_UNKNOWN 타입을 사용합니다. 다른 변환 타입에서 SVGTransform의 속성이 어떻게 동작하는지에 대한 자세한 내용은 아래를 참고하세요.

type IDL 속성은 SVGTransformvalue가 어떤 변환 항목 타입인지 나타냅니다. type을 가져올 때 다음 단계가 실행됩니다:

  1. SVGTransformvaluematrix(…), translate(…), scale(…), rotate(…), skewX(…) 또는 skewY(…) 함수이면, 위의 변환 타입 테이블에서 해당 상수 값을 반환합니다.
  2. 그렇지 않으면 SVG_TRANSFORM_UNKNOWN을 반환합니다.

    예를 들어 scaleX(…) 또는 translate3d(…) 변환의 경우 SVG_TRANSFORM_UNKNOWN이 반환됩니다.

matrix IDL 속성은 변환을 4x4 동차 행렬로 나타내며, 가져올 때 SVGTransformmatrix object를 반환합니다. matrix object가 처음 생성될 때, SVGTransform의 변환 함수 value에 맞게 값이 설정되며, SVGTransform을 반영하도록 설정됩니다.

다양한 변환 함수 타입이 특정 행렬 값에 어떻게 대응하는지에 대한 설명은 CSS Transforms 명세를 참고하세요.

angle IDL 속성은 rotate(…), skewX(…), skewY(…) 변환 함수의 각도 파라미터를 나타냅니다. 가져올 때 다음 단계가 실행됩니다:

  1. SVGTransform 객체의 valuerotate(…), skewX(…), skewY(…) 함수이면, 해당 각도 인수를 도(degree) 단위로 반환합니다.
  2. 그 외의 경우 0을 반환합니다.

setMatrix 메서드는 SVGTransform을 주어진 행렬 값으로 설정합니다. setMatrix(matrix)가 호출되면 다음 단계가 실행됩니다:

  1. SVGTransform 객체가 읽기 전용이면 예외 NoModificationAllowedError를 발생시킵니다.
  2. matrixis2d 메서드를 통해 true를 반환한다면, SVGTransform 객체의 valuematrix(…) 값으로 설정합니다.
  3. 그 외의 경우 SVGTransform 객체의 valuematrix3d(…) 값으로 설정합니다.
  4. matrix의 행렬 구성 요소 값을 SVGTransform 객체의 matrix object에 복사합니다.
  5. SVGTransform 객체가 표현 속성 값의 일부를 반영하는 경우, 반영되는 속성을 재직렬화합니다.

setTranslate, setScale, setRotate, setSkewX, setSkewY 메서드는 SVGTransform을 새로운 변환 함수 값으로 설정합니다. 이들 메서드 중 하나가 호출되면 다음 단계가 실행됩니다:

  1. SVGTransform 객체가 읽기 전용이면 예외 NoModificationAllowedError를 발생시킵니다.
  2. 호출된 메서드에 따라 SVGTransform 객체의 value를 새로운 변환 함수 값으로 설정합니다:
    setTranslate(tx, ty)
    새로운 변환 함수 값은 translate(tx, ty)
    setScale(sx, sy)
    새로운 변환 함수 값은 scale(sx, sy)
    setRotate(angle, cx, cy)
    새로운 변환 함수 값은 rotate(angle, cx, cy)
    setSkewX(angle)
    새로운 변환 함수 값은 skewX(angle)
    setSkewY(angle)
    새로운 변환 함수 값은 skewY(angle)
  3. SVGTransform 객체의 matrix object 구성 요소를 새 변환 함수 value에 맞게 설정합니다.
  4. SVGTransform 객체가 표현 속성 값의 일부를 반영하는 경우, 반영되는 속성을 재직렬화합니다.

이 명세는 DOMMatrix 객체의 동작에 대해 Geometry Interfaces 명세에서 설명한 것 이상으로 추가 요구사항을 부여합니다. 이를 통해 변환 값을 가지는 표현 속성에 반영할 수 있습니다.

모든 DOMMatrix 객체는 두 가지 모드 중 하나로 동작합니다. 다음과 같습니다:

  1. SVGTransform을 반영 (matrix IDL 속성을 통해 노출됨), 또는
  2. 분리됨, 생성자 또는 createSVGMatrix로 생성된 DOMMatrix 객체의 경우입니다.

DOMMatrix읽기 전용으로 지정될 수 있습니다. 읽기 전용 객체를 수정하려고 하면 내부 값을 갱신하는 대신 예외가 발생합니다. 읽기 전용 DOMMatrix의 IDL 속성에 값을 할당하거나, 변경 가능한 변환 메서드를 호출하면 NoModificationAllowedError 예외가 발생합니다.

이 내용은 읽기-쓰기 DOMMatrix 인터페이스에만 적용됩니다. DOMMatrixReadOnly 인터페이스는 transform을 반영하는 데 사용되지 않으며, 이미 수정 시 예외를 발생시킵니다.

쓰기 가능한 DOMMatrix의 IDL 속성에 값을 할당하거나 변경 가능한 변환 메서드를 호출하면, 내부 행렬 값을 갱신한 후 다음 단계가 실행됩니다:

  1. DOMMatrixSVGTransform을 반영하는 경우, 다음을 수행합니다:
    1. DOMMatrixis2d 메서드에서 true를 반환하면, SVGTransform 객체의 value를 해당 행렬과 같은 matrix(…) 값으로 설정합니다.
    2. 그 외의 경우 SVGTransform 객체의 value를 해당 행렬과 같은 matrix3d(…) 값으로 설정합니다.
    3. SVGTransform 객체가 표현 속성 값의 일부를 반영하면, 그 속성을 재직렬화합니다.

8.14.2. SVGTransformList 인터페이스

SVGTransformList 인터페이스는 리스트 인터페이스로, 각 요소는 SVGTransform 객체입니다. SVGTransformListtransform 속성의 값(즉, <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) 메서드가 호출되면, 다음 단계를 진행합니다:

  1. transform을 새로 생성된 SVGTransform 객체로 만들며, 이는 detached 상태입니다.
  2. transform에서 setMatrix 메서드를 matrix 인수로 호출할 때의 절차를 따릅니다.
  3. transform을 반환합니다.

consolidate 메서드는 변환 리스트를 단일 변환 함수로 동등하게 변환하는 데 사용됩니다. consolidate()가 호출되면, 다음 단계를 진행합니다:

  1. SVGTransformList 객체가 읽기 전용이면, NoModificationAllowedError 예외를 발생시킵니다.
  2. 리스트가 비어 있으면 null을 반환합니다.
  3. 리스트의 모든 요소를 Detach 후 제거합니다.
  4. transform을 새로 생성된 SVGTransform 객체로 만듭니다.
  5. 단위 행렬(identity matrix)에서 시작하여, 리스트에 있는 각 SVGTransformmatrix object 값을 순서대로 후행곱(post-multiply)하여 얻은 행렬을 matrix로 합니다.
  6. transformmatrix object의 구성 요소를 matrix의 값으로 설정합니다.
  7. transformmatrix objectis2d에서 true를 반환하면, transformvaluematrix object와 동일한 행렬을 나타내는 matrix(…) 값으로 설정합니다.
  8. 그 외의 경우 transformvaluematrix object와 동일한 행렬을 나타내는 matrix3d(…) 값으로 설정합니다.
  9. transform을 이 SVGTransformListAttach합니다.
  10. 리스트에 transform을 추가합니다.
  11. 리스트가 표현 속성을 reflect하면, 그 속성을 재직렬화합니다.
  12. transform을 반환합니다.

SVGLengthList의 나머지 인터페이스 멤버의 동작은 리스트 인터페이스에서 정의됩니다.

8.14.3. SVGAnimatedTransformList 인터페이스

SVGAnimatedTransformList 객체는 reflect를 통해 transform 속성과 그 표현 속성을 반영하는 데 사용됩니다. (요소에 따라 ‘transform’, gradientTransform, patternTransform 중 하나)

[Exposed=Window]
interface SVGAnimatedTransformList {
  [SameObject] readonly attribute SVGTransformList baseVal;
  [SameObject] readonly attribute SVGTransformList animVal;
};

baseValanimVal IDL 속성은 반영된 표현 속성의 값을 나타냅니다. baseVal 또는 animVal을 가져오면, 주어진 표현 속성을 반영하는 SVGTransformList 객체가 반환됩니다.

8.14.4. SVGPreserveAspectRatio 인터페이스

SVGPreserveAspectRatio 인터페이스는 preserveAspectRatio 속성의 값을 표현하는 데 사용됩니다.

SVGPreserveAspectRatio 객체는 읽기 전용으로 지정될 수 있습니다. 읽기 전용 객체를 수정하려고 하면 아래에 설명된 대로 예외가 발생합니다.

모든 SVGPreserveAspectRatio 객체는 reflectpreserveAspectRatio 속성의 기본 값을 반영합니다 (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 값의 정렬 키워드 부분을 나타냅니다. 가져올 때 다음 단계를 실행합니다:

  1. valuepreserveAspectRatio 속성의 기본 값을 반영하도록 합니다. value는 속성의 현재 애니메이션되지 않은 값입니다 (속성이 없거나 유효하지 않으면 초기 값 사용).
  2. value에 있는 정렬 키워드에 대해 위의 정렬 상수 테이블에 지정된 상수 값을 반환합니다.

align을 설정하면 다음 단계를 실행합니다:

  1. SVGPreserveAspectRatio읽기 전용이면 NoModificationAllowedError 예외를 발생시킵니다.
  2. valueSVG_PRESERVEASPECTRATIO_UNKNOWN 이거나 위의 정렬 키워드 테이블에 해당 항목이 없으면 반환합니다.
  3. value에 대해 위의 정렬 키워드 테이블에서 해당하는 키워드를 string으로 지정합니다.
  4. string에 U+0020 스페이스 하나를 추가합니다.
  5. meetOrSlice 멤버에서 반환될 값을 meet or slice로 지정합니다.
  6. meet or slice에 대해 위의 meet-or-slice 키워드 테이블에서 해당하는 키워드를 string에 추가합니다.
  7. 반영된 preserveAspectRatio 속성을 string으로 설정합니다.

meetOrSlice IDL 속성은 preserveAspectRatio 값의 meet-or-slice 키워드 부분을 나타냅니다. 가져올 때 다음 단계를 실행합니다:

  1. valuepreserveAspectRatio 값으로 지정하며, value는 해당 속성의 기본 값을 반영합니다. value는 속성의 현재 애니메이션되지 않은 값입니다.
  2. meet-or-slice 값이 value에 없으면 SVG_MEETORSLICE_MEET을 반환합니다.
  3. 그 외의 경우 meet-or-slice 값이 있으면, value에 있는 meet-or-slice 키워드에 대해 위의 meet-or-slice 상수 테이블에 지정된 상수 값을 반환합니다.

meetOrSlice를 설정하면 다음 단계를 실행합니다:

  1. SVGPreserveAspectRatio읽기 전용이면 NoModificationAllowedError 예외를 발생시킵니다.
  2. valueSVG_MEETORSLICE_UNKNOWN 이거나 위의 meet-or-slice 키워드 테이블에 해당 항목이 없으면 반환합니다.
  3. align 멤버에서 반환될 값을 align으로 지정합니다.
  4. align에 대해 위의 정렬 키워드 테이블에서 해당하는 키워드를 string으로 지정합니다.
  5. string에 U+0020 스페이스 하나를 추가합니다.
  6. value에 대해 위의 meet-or-slice 키워드 테이블에서 해당하는 키워드를 string에 추가합니다.
  7. 반영된 preserveAspectRatio 속성을 string으로 설정합니다.

8.14.5. SVGAnimatedPreserveAspectRatio 인터페이스

SVGAnimatedPreserveAspectRatio 객체는 preserveAspectRatio 속성을 reflect하는 데 사용됩니다.

[Exposed=Window]
interface SVGAnimatedPreserveAspectRatio {
  [SameObject] readonly attribute SVGPreserveAspectRatio baseVal;
  [SameObject] readonly attribute SVGPreserveAspectRatio animVal;
};

baseValanimVal IDL 속성은 반영된 preserveAspectRatio 속성의 현재 애니메이션되지 않은 값을 나타냅니다. baseVal 또는 animVal을 가져올 때, SVGPreserveAspectRatio 객체가 반환되며, 해당 객체가 기본값을 반영합니다. 이 기본값은 preserveAspectRatio 속성의 기본값이며, 객체가 반영하는 IDL 속성 타입이 SVGAnimatedPreserveAspectRatio인 경우, 그 객체가 얻어진 SVG 요소의 값을 반영합니다.