Tìm hiểu về pathData của VectorDrawable trong Android

Bài viết được dịch và sửa từ: medium.com của tác giả Ali Muzaffar

Mở bất kỳ một file xml VectorDrawable nào bạn sẽ thấy một số ký tự khó hiểu trong thuộc tính pathData.

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:tint="#FF0000"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z" />
</vector>

Những người làm việc thường xuyên với paths có thể hiểu được nó và giải thích cho bạn biết nó vẽ cái gì. Còn những người không làm nhiều thì nó sẽ là một bí ẩn.

VectorDrawable là gì

VectorDrawable là một sự diễn tả bằng XML của Vector. Không giống như các định dạng hình ảnh phổ biến như Bitmap, JPEG, GIF và PNG, Vector không làm giảm chất lượng khi chúng được thu nhỏ lên hoặc xuống. Điều này làm cho việc dùng các hình ảnh với chất lượng hoặc kích thước khác nhau là không cần thiết, do đó giúp bạn giảm dung lượng file apk. Trên thực tế, VectorDrawables chứa các lệnh Path (cách vẽ đường và cung) và giống như các lệnh Path khi làm việc với Canvas, vẽ và kết xuất VectorDrawables là quá trình tiêu tốn thời gian và bộ nhớ, đó là lý do tại sao VectorDrawable, được sử dụng tốt nhất cho đồ họa phẳng đơn giản.

Tại sao phải hiểu những lệnh này? Tôi chỉ cần lấy từ SVG?

Nếu bạn muốn tạo hiệu ứng cho VectorDrawable, như mọi trào lưu ngày nay, một trong những yêu cầu là VectorDrawable mà bạn đang làm hiệu ứng đầu và cuối phải có lệnh hợp lý. Ngoài ra, bạn sẽ biết làm thế nào các lệnh này làm ảnh chuyển động/thay đổi để làm ảnh động. Và tất nhiên hiểu được ý nghĩa của các lệnh PathData có thể giúp ích rất nhiều như việc tự tạo ra VectorDrawable của riêng bạn,…

Hiểu về các lệnh trong pathData

Hãy để tôi bắt đầu bằng cách nói rằng cho dù bạn học các lệnh đường dẫn bao nhiêu, trừ khi bạn là một thiên tài, sẽ có giới hạn cho những gì bạn có thể hiểu. Các chương trình đồ họa vector không thực sự “clean code” và dễ đọc với con người. Sau khi các tệp đồ họa vector như SVG được chuyển qua trình tạo VectorDrawable của Android Studios, chúng trở nên gọn gàng và dễ đọc hơn, tuy nhiên, tôi đã nhận thấy rằng rất nhiều lệnh vẫn có thể phức tạp hơn nhiều so với những gì bạn cần. Tiếp đó, để hiểu các vòng tròn và vòng cung chỉ đòi hỏi bạn phải có nhiều trí tưởng tượng hoặc năng lực toán học tốt.

Cơ bản

Các lệnh đường dẫn cơ bản bao gồm bảng chữ cái theo sau là một hoặc nhiều số. Các số thường được phân tách bằng dấu phẩy nhưng đôi khi có thể là dấu cách. Ví dụ:

M100,100 L300,100 L200,300 z
//or
M 100 100 L 300 100 L 200 300 z
//or
M1100,100L300,100L200,300z

Bảng chữ cái có thể là chữ hoa hoặc chữ thường. Chữ hoa có nghĩa là vị trí tuyệt đối, chữ thường có nghĩa là vị trí tương đối.

Các lệnh

M hoặc m (X, Y) +

Moveto: Di chuyển con trỏ đến vị trí, chữ hoa là tuyệt đối, chữ thường là tương đối. Các lệnh Moveto được theo sau bởi tọa độ X, Y. Có thể có nhiều hơn một bộ tọa độ theo lệnh M, chúng được coi là các lệnh lineto ngầm.

Z hoặc z

closepath: Vẽ một đường từ vị trí hiện tại của con trỏ đến vị trí bắt đầu của đường dẫn. Không có bất kỳ tham số nào kèm theo.

L hoặc l (X, Y) +

Lineto: Vẽ một đường thẳng từ vị trí hiện tại đến vị trí được chỉ định bởi X, Y. Chữ hoa có nghĩa là tọa độ tuyệt đối, chữ thường có nghĩa là tọa độ tương đối. Bạn có thể có nhiều bộ tọa độ theo lệnh lineto. Nếu bạn muốn chỉ định nhiều hơn một bộ tọa độ, điều đó có nghĩa là bạn có thể tạo một đa tuyến (Nhiều đường liên tiếp).

H hoặc h (X) +

Horizontal Lineto: vẽ một đường ngang từ vị trí con trỏ hiện tại đến vị trí được chỉ định bởi X. Nếu có nhiều tọa độ X theo lệnh, điều này được coi là một đa tuyến. Tọa độ Y không thay đổi. Chữ hoa H là tọa độ tuyệt đối, chữ thường h là tọa độ tương đối.

V hoặc v (Y) +

Vertical Lineto: vẽ một đường thẳng đứng từ vị trí con trỏ hiện tại đến vị trí được chỉ định bởi Y. Nếu có nhiều tọa độ Y theo lệnh, điều này được coi là một đa tuyến. Tọa độ X không thay đổi. Uppercase V là tọa độ tuyệt đối, chữ thường v là tọa độ tương đối.

Với các lệnh cơ bản đã nêu, chúng ta cùng giải thích lệnh ở ví dụ trên:

M100,100 L300,100 L200,300 z

M100,100: Di chuyển con trỏ đến tọa độ tuyệt đối X = 100 Y = 100px.
L300,100: Vẽ một đường thẳng thành X = 300 Y = 100 (vị trí bắt đầu là 100.100).
L200.300: Vẽ một đường thẳng thành X = 200 Y = 300 (vị trí bắt đầu là 300.100).
z: Đóng đường dẫn, vẽ đường thẳng từ vị trí hiện tại đến 100.100. Khi bạn đóng đường dẫn tức là bạn vẽ một đường từ điểm cuối cùng về điểm đầu tiên. Bạn có thể loại bỏ điều này nếu bạn không cần đóng ví dụ như khi vẽ dấu cộng (+).

Nếu chúng ta đặt nó bên trong pathData của file XML VectorDrawable đơn giản, chúng ta có thể thấy kết quả:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    <!-- intrinsic size of the drawable -->
        android:width="400px"
        android:height="400px"
    <!-- size of the virtual canvas -->
        android:viewportWidth="400.0"
        android:viewportHeight="400.0">
    <path
        android:fillColor="#0000FF"
        android:strokeColor="#FFFFFF"
        android:strokeWidth="4"
        android:pathData="M100,100 L300,100 L200,300 z"/>
</vector>

Đến đây cơ bản các bạn đã hiểu về pathData và có thể tự tạo các VectorDrawable đơn giản. Còn một vài ví dụ ở cuôi bài viết gốc (xem link trên đầu) các bạn có thể tham khảo.