Đối với thành phần SVG ngồi cùng của nội dung SVG, tác nhân người dùng SVG xác định một hệ trục tọa độ khung nhìn (viewport coordinate system) ban đầu và một hệ trục toạđộ người dùng (user coordinate system) ban đầu. Gốc toạđộ của hai hệ trục toạđộ này trùng với gốc toạ độ của khung nhìn, và mỗi đơn vị trong hệ
trục toạ độ ban đầu bằng 1 “điểm ảnh” (pixel). Trong hầu hết các trường hợp, tài liệu SVG độc lập hay phân đoạn tài liệu SVG được nhúng trong một tài liệu XML cha, thì hệ trục toạđộ khung nhìn ban đầu cĩ gốc toạ độ nằm ở gĩc trái của khung nhìn với trục x hướng từ trái sang phải, trục y từ trên xuống.
Ví dụ 1:
Ví dụ một hệ trục toạ độ ban đầu với gốc toạ độ nằm ở gĩc trái và trục x hướng sang phải, trục y hướng từ trên xuống. Hệ trục toạđộ người dùng ban đầu cĩ mỗi đơn vị người dùng bằng một “pixel”.
88
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="300px" height="100px" version="1.1"
<xmlns="http://www.w3.org/2000/svg">
<desc>Example InitialCoords - SVG's initial coordinate system</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> Kết quả trên trình duyệt: 3.12.4 Các phép biến đổi hệ trục toạđộ Một hệ trục toạ độ người dùng mới (nghĩa là một hệ trục toạ độ hiện hiện tại mới – new current coordinate system ) cĩ thể được thiết lập bằng các phép biến đổi thơng qua thuộc tính ‘transform’ của thành phần vật chứa hay thành phần đồ họa, hay thơng qua thuộc tính ‘viewBox’ của thành phần ‘svg’, ‘symbol’, ‘marker’, ‘pattern’ và thành phần ‘view’. Thuộc tính ‘transform’ và ‘viewBox’ được áp dụng (biến đổi) cho các toạ độ và chiều dài trong hệ trục toạ độ người dùng của thành
89
phần chứa thuộc tính này và tất cả các thành phần con. Các phép đổi cĩ thể lồng nhau, lúc đĩ các phép biến đổi sẽđược cộng dồn lại.
Ví dụ 2:
Dưới đây là ví dụ về một tài liệu khơng cĩ phép biến đổi. Chuỗi văn bản được xác định trong hệ toạđộ ban đầu.
Kết quả trên trình duyệt:
Hình 3.18. Minh họa hiển thị khơng cĩ phép biến đổi
Ví dụ 3:
Thiết lập một hệ trục toạ độ người dùng bằng phép tịnh tiến transfrom= “translate(50,50)” trên thành phần ‘g’ thứ ba. Hệ trục toạđộ người dùng mới cĩ gốc <?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="400px" height="150px" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Example OrigCoordSys - Simple transformations: original picture</desc>
<g fill="none" stroke="black" stroke-width="3" >
<!-- Draw the axes of the original coordinate system --> <line x1="0" y1="1.5" x2="400" y2="1.5" />
<line x1="1.5" y1="0" x2="1.5" y2="150" /> </g>
<g>
<text x="30" y="30" font-size="20" font-family="Verdana" >
ABC (orig coord system)
</text>
</g> </svg>
90
toạ độ tại (50,50) trong hệ trục toạ độ nguyên thủy. Kết quả của phép biến đổi này là một toạ độ (30,30) trong hệ trục toạ độ người dùng mới được ánh xạ thành (80,80) trong hệ trục toạđộ nguyên thủy . Như vậy các toạđộđược tính tiến 50 đơn vị trên trục x và 50 đơn vị trên trục y.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="400px" height="150px" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Example NewCoordSys - New user coordinate system</desc>
<g fill="none" stroke="black" stroke-width="3" >
<!-- Draw the axes of the original coordinate system --> <line x1="0" y1="1.5" x2="400" y2="1.5" />
<line x1="1.5" y1="0" x2="1.5" y2="150" /> </g>
<g>
<text x="30" y="30" font-size="20" font-family="Verdana" >
ABC (orig coord system) </text>
</g>
<!-- Establish a new coordinate system, which is shifted (i.e., translated) from the initial coordinate
system by 50 user units along each axis. -->
<g transform="translate(50,50)">
<g fill="none" stroke="red" stroke-width="3" > <!-- Draw lines of length 50 user units along the axes of the new coordinate system --> <line x1="0" y1="0" x2="50" y2="0" stroke="red" /> <line x1="0" y1="0" x2="0" y2="50" />
</g>
<text x="30" y="30" font-size="20" font-family="Verdana" >
ABC (translated coord system) </text>
</g> </svg>
91 Kết quả trên trình duyệt:
Ví dụ 4:
Dùng phép biến đổi tỉ lệ (sclale) và quay (rotate), ví dụ sau định nghĩa hai hệ
trục toạđộ người dùng mới.
• Một hệ trục là kết quả của phép tịnh tiến 50 đơn vị theo trục x và 30
đơn vị theo trục y, và phép quay 30o
• Một hệ trục là kết quả của phép tịnh tiến 200 đơn vị theo trục x và 40
đơn vị theo trục y, và phép tỉ lệ 1.5
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="400px" height="120px" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Example RotateScale - Rotate and scale transforms</desc>
<g fill="none" stroke="black" stroke-width="3" >
<!-- Draw the axes of the original coordinate system --> <line x1="0" y1="1.5" x2="400" y2="1.5" />
<line x1="1.5" y1="0" x2="1.5" y2="120" /> </g>
<!-- Establish a new coordinate system whose origin is at (50,30)
in the initial coord. system and which is rotated by 30 degrees. -->
<g transform="translate(50,30)">
<g transform="rotate(30)">
<g fill="none" stroke="red" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
92
<text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" >
ABC (rotate) </text>
</g> </g>
<!-- Establish a new coordinate system whose origin is at (200,40)
in the initial coord. system and which is scaled by 1.5. -->
<g transform="translate(200,40)">
<g transform="scale(1.5)">
<g fill="none" stroke="red" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="20" font-family="Verdana" fill="blue" > ABC (scale) </text> </g> </g> </svg> Kết quả trên trình duyệt:
Hình 3.20. Minh họa phép quay và phép co giãn
Ví dụ 5:Định nghĩa hai hệ trục toạđộđược biến đổi xiên tương đối với hệ trục toạđộ nguyên thủy.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="400px" height="120px" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Example Skew - Show effects of skewX and skewY</desc>
<g fill="none" stroke="black" stroke-width="3" >
<!-- Draw the axes of the original coordinate system -- >
93
<line x1="0" y1="1.5" x2="400" y2="1.5" /> <line x1="1.5" y1="0" x2="1.5" y2="120" /> </g>
<!-- Establish a new coordinate system whose origin is at (30,30)
in the initial coord. system and which is skewed in X by 30 degrees. -->
<g transform="translate(30,30)"> <g transform="skewX(30)">
<g fill="none" stroke="red" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="20" font- family="Verdana" fill="blue" >
ABC (skewX) </text>
</g> </g>
<!-- Establish a new coordinate system whose origin is at (200,30)
in the initial coord. system and which is skewed in Y by 30 degrees. -->
<g transform="translate(200,30)"> <g transform="skewY(30)">
<g fill="none" stroke="red" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="20" font- family="Verdana" fill="blue" > ABC (skewY) </text> </g> </g> </svg> Kết quả trên trình duyệt:
94
Ví dụ 6: Các phép biến đổi lồng nhau.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="400px" height="150px" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<desc>Example Nested - Nested transformations</desc> <g fill="none" stroke="black" stroke-width="3" >
<!-- Draw the axes of the original coordinate system -->
<line x1="0" y1="1.5" x2="400" y2="1.5" /> <line x1="1.5" y1="0" x2="1.5" y2="150" /> </g>
<!-- First, a translate -->
<g transform="translate(50,90)">
<g fill="none" stroke="red" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="16" font- family="Verdana" >
....Translate(1) </text>
<!-- Second, a rotate --> <g transform="rotate(-45)">
<g fill="none" stroke="green" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="16" font- family="Verdana" >
....Rotate(2) </text>
<!-- Third, another translate --> <g transform="translate(130,160)">
<g fill="none" stroke="blue" stroke-width="3" > <line x1="0" y1="0" x2="50" y2="0" />
<line x1="0" y1="0" x2="0" y2="50" /> </g>
<text x="0" y="0" font-size="16" font- family="Verdana" > ....Translate(3) </text> </g> </g> </g> </svg>
95 Kết quả trên trình duyệt :
Hình 3.22 Minh họa phép các phép biến đổi lồng nhau
3.12.5 Thuộc tính ‘transform’
Thuộc tính ‘transform’ (biến đổi) là một <transform-list>” (danh sách các biến
đổi). Thuộc tính này dùng đểđịnh nghĩa một mảng các phép biến đổi, các phép biến
đổi sẽđược áp dụng theo trình tự cung cấp trong mảng. Các phép biến đổi riêng biệt
được phân nhau bởi khoảng trắng hoặc dấu phẩy (‘,’). Các phép biến đổi được định nghĩa trước là:
• matrix(<a><b><c><d><e><f>) được dùng đểđịnh nghĩa một phép biến
đổi bằng ma trận biến đổi. Các giá trị a,b,c,d,e,f là các phần tử của ma trận biến đổi affine 3x3:
• translate(<tx><[ty]>) được dùng để định nghĩa một phép tịnh tiến.Với tx độ dời theo trục x, ty là độ dời theo trục y. Nếu <ty> khơng được cung cấp thì được cho bằng 0.
• scale(<sx>[<sy>]) được dùng đểđịnh nghĩa một phép tỉ lệ. Với sx và sy là chỉ số co dãn theo trục x va trục y. Nếu trị tuyệt đối của sx và sy lớn hơn 1 thì phép biến đổi dùng để phĩng to hình, ngược lại thì thu nhỏ
96
• rotate(<rotate-angle>[<cx><y>]) được dùng để định nghĩa một phép quay quanh một điểm được cho trước <rotate-angle> độ. Nếu tham số
<cx> và <cy> khơng được cung cấp thì sẽ quay quanh gốc toạ độ của hệ trục toạ độ người dùng hiện tại. Phép biến đổi này tương đương ma trận [cos(a) sin(a) –sin(a) cos(a) 0 0].
Nếu tham số <cx> và <cy> được cung cấp thì sẽ quay quanh điểm (<cx>,<cy>). Phép biến đỏi này tương đương với dãy các biến đổi sau: translate(<cx>,<cy>) rotate(<rotate-angle>) translate(-<cx>,-cy>).
• skewX(<skew-angle>) chỉ định một phép biến đổi xiên dọc theo trục x.
• skewY(<skew-angle>) chỉ định một phép biến đổi xiên dọc theo trục y. Khi áp dụng mảng các phép biến đổi thì kết quả cũng giống như khi áp dụng các phép biến đổi riêng rẽ theo trình tự trong mảng.
Ví du 1:
Định nghĩa mảng các phép biến đổi:
<g transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)">
<!-- graphics elements go here --> </g> Cũng cĩ kết quả nhưđịnh nghĩa các phép biến đổi riêng biệt sau: <g transform="translate(-10,-20)"> <g transform="scale(2)"> <g transform="rotate(45)"> <g transform="translate(5,10)">
<!-- graphics elements go here --> </g>
</g> </g> </g>
Thuộc tính ‘transform’ được áp dụng trước khi xử lý bất kỳ toạ độ hay giá trị độ dài của thành phần chứa thuộc tính này. Ví dụ như trong thành phần sau.
97
<rect x="10" y="10" width="20" height="20" transform="scale(2)"/>
Các giá trị x, y, width, height được xử lý sau khi hệ trục toạ độ hiện tại được áp dụng phép biến đổi tỉ lệ scale(2). Thuộc tính ‘x’, ‘y’, ‘width’ và ‘height’ được tính theo hệ trục toạ độ người dùng mới. Do đĩ thành phần ‘rect’ sẽ tương đương với :
<g transform="scale(2)">
<rect x="10" y="10" width="20" height="20"/> </g>
3.12.6 Thuộc tính ‘viewBox’
Thuộc tính viewBox dùng để thiết lập một hệ trục toạ độ người dùng mới ,
được dùng khi muốn trải các hình ra cho vừa với thành phần vật chứa.
Áp dụng cho tất cả các thành phần cĩ khả thiết lập khung nhìn mới và các thành phần ‘marker’, ‘pattern’ và ‘view’ cĩ thuộc tính viewBox. Giá trị của thuộc tính ‘viewBox’ là một danh sách bốn số <min-x>, <min-y>, <width> và <height>,
được tách biệt nhau bởi khoảng trắng hoặc dấu phẩy, dùng để định nghĩa một hình chữ nhật trong hệ trục toạđộ người dùng sẽđược ánh xạ vào đường bao của khung nhìn được thiết lập bởi thành phần được cho.
Khi thuộc tính viewBox được thiết lập, tác nhân người dùng tựđộng phát sinh các ma trận biến đổi thích hợp để ánh xạ hình chữ nhật được chỉ định trong hệ toạ độ người dùng vào đường bao của khung nhìn.
Thuộc tính ‘viewBox’ thường được dùng với thuộc tính ‘preservAspectRatio’
để xác định gốc toạ độ cũng như giá trị mỗi đơn vị chiều dài của hệ trục toạ độ
98
Lưu ý là giá trị <width> và <height> của thuộc tính ‘viewBox’ khơng nhận giá trị âm. Nếu thiết lập giá trị âm sẽ gây ra lỗi, nếu thiết lập bằng “0” thì thành phần này khơng được hiển thị.
Ví dụ 1:
Ví dụ sau minh hoạ cách sử dụng thuộc tính ‘viewBox’ trong thành phần ‘svg’ ngồi cùng để trải nội dung SVG vừa khít với biên của khung nhìn.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="300px" height="200px" version="1.1"
viewBox="0 0 1500 1000" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<desc>Example ViewBox - uses the viewBox
attribute to automatically create an initial user coordinate
system which causes the graphic to scale to fit into the viewport no matter what size the viewport is.</desc>
<!-- This rectangle goes from (0,0) to (1500,1000) in user space.
Because of the viewBox attribute above,
the rectangle will end up filling the entire area reserved for the SVG content. -->
<rect x="0" y="0" width="1500" height="1000"
fill="yellow" stroke="blue" stroke-width="12" /> <!-- A large, red triangle -->
<path fill="red" d="M 750,100 L 250,900 L 1250,900 z"/> <!-- A text string that spans most of the viewport -->
<text x="100" y="600" font-size="200" font- family="Verdana" >
Stretch to fit </text>
</svg>
Kết quả trên trình duyệt (hình bên trái), hình bên phải là kết quả khi thay đổi
99 thuộc tính width="150px" height="200px".
Đểđạt được kết quả bên trái, với khung nhìn 300x200 px, tác nhân người dùng tự động chèn vào phép biến đổi tỉ lệ transform="scale(0.2)”, kết quả tương đương cĩ một khung nhìn kích thước 300x200 px và phép biến đổi tỉ lệ bổ sung như sau:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="300px" height="200px" version="1.1"
xmlns="http://www.w3.org/2000/svg"> <g transform="scale(0.2)">
<!-- Rest of document goes here --> </g>
</svg>
Để đạt được kết quả bên phải, với khung nhìn 150x200 px, tác nhân người dùng tựđộng chèn vào phép biến đổi tỉ lệtransform="scale(0.1 0.2)”, kết quả tương
đương cĩ một khung nhìn kích thước 150x200 px và phép biến đổi tỉ lệ bổ sung như
sau:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="150px" height="200px" version="1.1"
xmlns="http://www.w3.org/2000/svg"> <g transform="scale(0.1 0.2)">
<!-- Rest of document goes here --> </g>
</svg>
Trong một số trường hợp tác nhân người dùng cần cung cấp một phép tịnh tiến (translate) ngồi phép biến đổi tỉ lệ (sacle). Ví dụ, khi trong thành phần ‘svg’ ngồi cùng , thuộc tính ‘viewBox’ cĩ giá trị <min-x> hay <min-y> khác “0”.
Khơng giống thuộc tính ‘transform’, các phép biến đổi tựđộng được tạo bởi sự
cĩ mặt của thuộc tính ‘viewBox’ khơng ảnh hưởng đến thuộc tính ‘x’, ‘y’, ‘width’, ‘height’ (hay trong trường hợp thành phần ‘marker’, là thuộc tính ‘markerWidth’, ‘markerHeight’) trên thành phần chứa thuộc tính ‘viewBox’ đĩ. Do đĩ trong ví dụ
trên, thuộc tính ‘width’ và ‘height’ được tính theo đơn vị đo trong hệ trục toạ độ