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ị
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ạ độ
100
là nĩ thiết lập một hệ trục toạ độ mới cho tất cả các thuộc tính khác và cho các
thành phần con của thành phần chứa tính ‘viewBox’.
3.12.7 Thuộc tính ‘preserveAspectRatio’
Trong một số trường hợp, khi sử dụng thuộc tính ‘viewBox’, người ta muốn các hình hiển thị trải rộng tồn khung nhìn khơng cần đảm bảo tỉ lệ cạnh của hình (hình hiển thị trong khung nhinh cĩ khi bị kéo dài hay thu hẹp theo một trục toạ độ). Trong một số trường hợp khác thì lại muốn các cạnh co dãn với cùng tỉ lệ để đảm bảo tỉ lệ cạnh của hình (hình mới đồng dạng với hình ngun thủy).
Thuộc tính ‘preserveAspectRatio= “[defer]<align>[<meetOrSlice>]”, chỉ áp dụng trong các thành phần thiết lập khung nhìn mới, thành phần ‘marker’, ‘pattern’, ‘view’, dùng để chỉ định cĩ cần co dãn tỉ lệ các chiều đồng nhất hay khơng. Thuộc tính ‘preserveAspectRatio’ chỉ dùng khi thuộc tính ‘viewBox’ được thiết lập, ngược lại thuộc tính này bị bỏ qua.
Đối với thành phần ‘image’, thuộc tính ‘preserveAspectRatio’ trên thành phần
‘image’ xác định cĩ cần bảo tồn tỉ lệ cạnh của ảnh được tham chiếu khi hiển thị
hay khơng.
Nếu giá trị của thuộc tính ‘preserveAspectRatio’ trên thành phần ‘image’ bắt
đầu với giá trị ‘defer’ thì giá trị của thuộc ‘preserveAspectRatio’ (nếu cĩ) trong nội
dung được tham chiếu sẽ được dùng . Nếu nội dung được tham chiếu khơng cĩ giá trị thuộc tính ‘preserveAspectRatio’ thì thuộc tính ‘preserveAspectRatio’ trên thành phần ‘image’ sẽ được xử lý bình thường – bỏ qua giá trị ‘defer’. Đối với các thành phần khác thành phần ‘image’ thì giá trị ‘defer’ trên thuộc tính ‘preserveAspectRatio’ sẽ bị bỏ qua.
Tham số <align> (canh lề) xác định cĩ cần đảm bảo tỉ lệ các chiều hay khơng, nếu nĩ thuộc tính được thiết lập thì phương thức canh lề được dùng khi tỉ lệ cạnh
trong thuộc tính ‘viewBox’ khơng khớp với tỉ lệ cạnh của khung nhìn. Tham số <align> phải là một trong các giá trị sau:
101
• none – khơng cần bảo tồn tỉ lệ cạnh. Nếu <align> nhận giá trị ‘none’ thì tuỳ chọn <meetOrSlice> sẽ bị bỏ qua.
• xMinYMin - Cần bảo tồn tỉ lệ cạnh.
o Giá trị <min-x> của ‘viewBox’ canh trùng với giá trị X nhỏ nhất của khung nhìn.
o Giá trị <min-y> của ‘viewBox’ canh trùng với giá trị Y nhỏ nhất của khung nhìn.
• xMidYMin-Cần bảo tồn tỉ lệ cạnh
o Giá trị X của điểm giữa của ‘viewBox’ canh trùng với giá trị X
điểm giữa của khung nhìn.
o Giá trị <min-y> của ‘viewBox’ canh trùng với giá trị Y nhỏ nhất của khung nhìn.
• xMaxYMin-Cần bảo tồn tỉ lệ cạnh
o Giá trị <min-x> + <width> của ‘viewBox’ canh trùng với giá trị X lớn nhất của khung nhìn.
o Giá trị <min-y> của ‘viewBox’ canh trùng với giá trị Y nhỏ nhất của khung nhìn.
• xMinYMid-Cần bảo tồn tỉ lệ cạnh
o Giá trị <min-x> của ‘viewBox’ canh trùng với giá trị X nhỏ nhất của khung nhìn.
o Giá trị Y điểm giữa của ‘viewBox’ canh trùng với giá trị Y điểm giữa của khung nhìn.
• xMidYMid-Cần bảo tồn tỉ lệ cạnh
o Giá trị X của điểm giữa của ‘viewBox’ canh trùng với giá trị X
102
o Giá trị Y điểm giữa của ‘viewBox’ canh trùng với giá trị Y điểm giữa của khung nhìn.
• xMaxYMid - Cần bảo tồn tỉ lệ cạnh.
o Giá trị <max-x> của ‘viewBox’ canh trùng với giá trị X lớn nhất của khung nhìn.
o Giá trị Y của điểm giữa của ‘viewBox’ canh trùng với giá trị Y của điểm giữa của khung nhìn.
• xMinYMax - Cần bảo tồn tỉ lệ cạnh.
o Giá trị <min-x> của ‘viewBox’ canh trùng với giá trị X nhỏ nhất của khung nhìn.
o Giá trị <min-y> + <height> của ‘viewBox’ canh trùng với giá trị Y lớn nhất của khung nhìn.
• xMidYMax - Cần bảo tồn tỉ lệ cạnh.
o Giá trị X của điểm giữa của ‘viewBox’ canh trùng với giá trị X của điểm giữa của khung nhìn.
o Giá trị <min-y> + <height> của ‘viewBox’ canh trùng với giá trị Y lớn nhất của khung nhìn.
• xMaxYMax - Cần bảo tồn tỉ lệ cạnh.
o Giá trị <min-x> + <width> của ‘viewBox’ canh trùng với giá trị X lớn nhất của khung nhìn.
o Giá trị <min-y> + <height> của ‘viewBox’ canh trùng với giá trị Y lớn nhất của khung nhìn.
Tham số <meetOrSlice> là tham số tuỳ chọn, nếu được cung cấp, nĩ sẽ được tách biệt với giá trị <align> bởi một hay nhiều khoảng trắng.
103
• meet (mặc định) :
o Bảo tồn tỉ lệ cạnh
o Tồn bộ ‘viewBox’ hiển thị trong khung nhìn
o ‘viewBox’ được dãn to hết mức cĩ thể trong khi vẫn đảm bảo
các ràng buộc khác.
Trong trường hợp này, nếu tỉ lệ cạnh của ảnh khơng khớp với khung nhìn, thì khung nhìn lớn hơn ‘viewBox’.
• slice:
o Bảo tồn tỉ lệ cạnh
o ‘viewBox’ sẽ chiếm tồn bộ khung nhìn
o ‘viewBox’ được co lại nhỏ nhất cĩ thể, trong khi vẫn đảm bảo
các ràng buộc khác
Trong trường hợp này, nếu tỉ lệ cạnh của ‘viewBox’ khơng khớp với tỉ lệ cạnh của khung nhìn thì một phần của ‘viewBox’ khơng hiển thị trong khung nhìn.
Ví dụ 1:
Ví dụ sau chứng minh các tùy chọn đối với thuộc tính ‘preserveAspectRatio’. <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ <!ENTITY Smile "
<rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
<g transform='translate(0, 5)'>
<circle cx='15' cy='15' r='10' fill='yellow'/> <circle cx='12' cy='12' r='1.5' fill='black'/> <circle cx='17' cy='12' r='1.5' fill='black'/>
<path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke- width='2'/>
</g> ">
104 height='29'
fill='none' stroke='blue'/>">
<!ENTITY Viewport2 "<rect x='.5' y='.5' width='29' height='59'
fill='none' stroke='blue'/>"> ]>
<svg width="450px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<desc>Example PreserveAspectRatio - illustrates preserveAspectRatio attribute</desc>
<rect x="1" y="1" width="448" height="298" fill="none" stroke="blue"/>
<g font-size="9">
<text x="10" y="30">SVG to fit</text>
<g transform="translate(20,40)">&Smile;</g> <text x="10" y="110">Viewport 1</text>
<g transform="translate(10,120)">&Viewport1;</g> <text x="10" y="180">Viewport 2</text>
<g transform="translate(20,190)">&Viewport2;</g> <g id="meet-group-1" transform="translate(100, 60)"> <text x="0" y="-30">--------------- meet ----------- ----</text> <g><text y="-10">xMin*</text>&Viewport1; <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40" width="50" height="30">&Smile;</svg></g> <g transform="translate(70,0)"><text y="- 10">xMid*</text>&Viewport1; <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40" width="50" height="30">&Smile;</svg></g> <g transform="translate(0,70)"><text y="- 10">xMax*</text>&Viewport1; <svg preserveAspectRatio="xMaxYMax meet"