PerfectVector
Bởi Irene Kim

Đo độ dài đường dẫn SVG mà không nhầm tỷ lệ

Đo đường dẫn SVG theo đơn vị người dùng trong trình duyệt, xét biến đổi và kích thước danh nghĩa, phân biệt tổng đường bao với pathLength hoặc hành trình máy.

11 phút đọc
Trên trang này

Để đo đường dẫn SVG, gọi getTotalLength() trên phần tử hình học rồi xác định hệ tọa độ đứng sau con số. Trình duyệt trả độ dài theo đơn vị người dùng. Con số đó không tự động là độ dài hiển thị, số đo milimét hoặc quãng đường máy di chuyển.

Ví dụ, đường chéo gốc của chúng tôi dài 50 đơn vị người dùng. Co giãn đồng đều tăng gấp đôi độ dài trong không gian gốc lên 100, còn chỉ co giãn theo ngang làm độ dài khoảng 72,111. Kết quả API cục bộ vẫn là 50 trong cả hai trường hợp. Các số đó trả lời những câu hỏi đo khác nhau.

Đo đoạn đã biết trước khi đo hình

Bạn cần SVG có hình học truy cập được và trình duyệt chạy SVG nội tuyến cùng JavaScript. Làm trên bản sao hình. Quyết định cần hình học cục bộ, hình học đã biến đổi hay độ dài ở kích thước vật lý cụ thể trước khi ghi kết quả.

Đường dẫn lưu tuyến bằng các lệnh như di chuyển, đường thẳng, đường cong và đóng. Đơn vị người dùng thuộc hệ tọa độ SVG đó; đừng đổi tên thành pixel hay milimét khi chưa kiểm tra ánh xạ. Tài liệu getTotalLength() của MDN định nghĩa kết quả là độ dài đường dẫn do trình duyệt tính theo đơn vị người dùng.

Ví dụ HTML đầy đủ này đo đoạn thẳng. Lưu thành tệp HTML và mở trong trình duyệt:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>SVG length control</title>
<svg width="240" height="240" viewBox="0 0 120 120">
  <path id="route" d="M10 10 L40 50"
        fill="none" stroke="black" />
</svg>
<pre id="result"></pre>
<script>
  const route = document.querySelector("#route");
  document.querySelector("#result").textContent =
    route.getTotalLength() + " local user units";
</script>
</html>

Thay đổi ngang là 30 và dọc là 40 nên độ dài dự kiến là sqrt(30² + 40²) = 50. Kết quả hiển thị cho bạn mẫu kiểm soát đã biết trước khi tin đường cong phức tạp hoặc biểu tượng đã nhập. Khung nhìn 240 pixel không biến kết quả cục bộ đó thành 100 đơn vị người dùng.

Trong mẫu trình duyệt, chúng tôi nêu dung sai 0,01 đơn vị người dùng. Mẫu một phần tư đường tròn bán kính 10 có độ dài giải tích 5π, khoảng 15,708. Trình duyệt thử nghiệm báo Chrome 155 và trả khoảng 15,7102, trong dung sai đó. Trình duyệt tính độ dài cong bằng số, nên giữ độ chính xác hữu ích và so sánh với dung sai phù hợp thay vì đòi chữ số thập phân cuối giống nhau ở mọi triển khai.

Tách độ dài cục bộ và sau biến đổi

Hai mẫu tiếp theo giữ cùng d="M10 10 L40 50" và thêm biến đổi:

Đoạn gốcĐộ dài API cục bộĐộ dài sau biến đổi đã nêu theo đơn vị người dùng SVG gốc
Không biến đổi5050
scale(2)50100
scale(2 1)50Khoảng 72,111

Co giãn đồng đều nhân mọi hướng với cùng độ lớn, nên nhân độ dài cục bộ với 2 đúng cho dòng thứ hai. Co giãn không đều xử lý hướng khác nhau. Trong dòng thứ ba, đoạn đã đổi đi ngang 60 đơn vị và xuống 40: sqrt(60² + 40²), không phải 50 × 2.

Đặc tả hệ tọa độ SVG giải thích cách biến đổi và ánh xạ viewBox tạo hệ tọa độ. Nêu tên không gian đích. Độ dài theo đơn vị người dùng SVG gốc vẫn khác pixel CSS trong khung nhìn.

Với đoạn thẳng đã biết này, chúng tôi ánh xạ hai đầu vào không gian người dùng SVG gốc:

const root = route.ownerSVGElement;
const relative = root.getCTM().inverse().multiply(route.getCTM());
const a = new DOMPoint(10, 10).matrixTransform(relative);
const b = new DOMPoint(40, 50).matrixTransform(relative);
const transformedLength = Math.hypot(b.x - a.x, b.y - a.y);

Ma trận gốc nghịch đảo bỏ ánh xạ khung nhìn của gốc; ma trận tương đối giữ biến đổi của đường dẫn vào không gian người dùng gốc. Đoạn mã giả định SVG đã gắn vào tài liệu, ma trận khả nghịch và đúng đoạn thẳng ở trên. Các đầu mút được biết từ nguồn đường dẫn đó.

Với đường cong, khoảng cách hai đầu chỉ là dây cung. Để đo đường cong có biến đổi tổng quát, chuyển hình học vào hệ tọa độ đích rồi đo hình học đó, hoặc dùng xấp xỉ số có kiểm soát giữ các đường bao riêng. Đừng dùng công thức hai đầu này cho tuyến cong hoặc nhân hình biến đổi không đều với một hệ số tỷ lệ đoán.

Các mẫu đo thực tế trong trình duyệt thể hiện co giãn đều và không đều, biểu tượng hai đường bao, độ dài cục bộ và phép tính milimét danh nghĩa
Hình học gốc tự tạo với kết quả trực tiếp từ trình duyệt. Độ dài cục bộ, độ dài biến đổi trong không gian gốc và milimét danh nghĩa tính toán được gắn nhãn riêng. Không thể hiện thử nghiệm ứng dụng đích hay sản xuất vật lý.

Chỉ đổi sang milimét sau khi cố định ánh xạ

Tài liệu biểu tượng gốc khai báo width="50mm", height="50mm" và viewBox="0 0 100 100". Với ánh xạ đồng đều dự định, đó là 0,5 mm mỗi đơn vị người dùng. Chiều rộng ngoài biểu tượng trải 80 đơn vị, nên chiều rộng danh nghĩa là 40 mm.

Hai đường bao có tổng độ dài 380 đơn vị người dùng. Ở tỷ lệ khai báo đó:

50 mm / 100 user units = 0.5 mm per user unit
380 user units × 0.5 mm per user unit = 190 mm of contours

Đây là tính toán từ kích thước tự đặt. Chúng tôi không đo vật đã in, xác minh màn hình bằng thước hay thử kích thước nhập của trình biên tập. CSS có thể ghi đè khung nhìn SVG và nơi nhận có thể đổi tỷ lệ hình. Xác nhận kích thước giao trong nơi nhận đó trước khi coi phép tính danh nghĩa là số đo sản xuất.

Chiều rộng toàn tài liệu cũng khác chiều rộng hình bên trong. Nếu thay vào đó chỉ đặt chiều rộng ngoài biểu tượng thành 50 mm, chiều rộng 80 đơn vị cho hệ số khác: 50 / 80 = 0.625 mm per unit. Cùng 380 đơn vị lúc đó đại diện 237,5 mm đường bao. Ghi lại chiều rộng nào được đặt; dùng hướng dẫn hộp bao SVG khi cần kiểm tra phạm vi trước.

pathLength hiệu chuẩn khoảng cách mà không đổi cỡ hình

Chúng tôi cũng tạo bản sao đoạn 50 đơn vị gốc với pathLength="1". Kết quả getTotalLength() vẫn 50. Thuộc tính không đổi hai đầu hoặc biến độ dài hình học thành một đơn vị.

Đặc tả API hình học SVG loại rõ pathLength khỏi kết quả tính. Tài liệu pathLength của MDN mô tả việc hiệu chuẩn hành vi khoảng cách dọc đường dẫn, gồm nét đứt. Nó hữu ích khi tạo hiệu ứng với khoảng cách chuẩn hóa, không thay việc đo tuyến nền.

Với hiệu ứng vẽ hiện dần, theo hướng dẫn hoạt ảnh nét SVG. Tách giá trị gạch đã hiệu chuẩn khỏi độ dài hình học ghi khi kiểm tra hình.

Cộng đường bao mà không biến tổng thành hành trình máy

Biểu tượng của chúng tôi có biên ngoài và lỗ hình thoi. Đường dẫn phức hợp gốc lưu cả hai đường bao kín:

<path fill-rule="evenodd"
      d="M10 10 H90 V60 L50 90 L10 60 Z
         M50 25 L65 45 L50 65 L35 45 Z" />

Đường bao ngoài đo 280 đơn vị, đường trong 100. Đường phức hợp trả 380; đo hai đường bao như phần tử đường dẫn riêng rồi cộng cũng trả 380. Đặc tả đường dẫn SVG phân biệt đường con mới với đoạn thẳng và đoạn đóng. Di chuyển tới lỗ không thêm đoạn nối được vẽ giữa hai đường bao.

Tổng đó mô tả hình học được lưu đã chọn. Nét dày được đồ có thể có hai tuyến biên; đường trùng có thể cộng hình học lần nữa; biểu tượng có thể có đường bao trong nhỏ mà bạn không định xử lý. Đo đúng đối tượng và đường bao bạn muốn, kiểm tra trước khi diễn giải tổng.

Hành trình máy là kết quả riêng. Công việc có thể có di chuyển giữa đường bao, lựa chọn thứ tự, nhiều lượt hoặc thay đổi đường dẫn riêng của nơi nhận. Tổng trình duyệt không xác lập điều nào trong số đó. Nó cũng không cho thời gian cắt, lượng vật liệu tiêu thụ hay kết quả máy thành công. Nếu cần một tuyến tâm từ bản quét, hướng dẫn SVG một nét đề cập nhiệm vụ tái dựng khác đó.

Ghi phép đo cùng các giả định

  1. Xác định hình học được chọn và kiểm tra có nhiều đường bao hoặc bản trùng không.
  2. Đo mẫu kiểm soát đã biết và các đường chọn theo đơn vị người dùng cục bộ.
  3. Ghi biến đổi và không gian tọa độ cần cho kết quả.
  4. Xác lập kích thước tài liệu hoặc hình dự định trước khi đổi đơn vị.
  5. Gắn nhãn riêng giá trị hiệu chuẩn, tổng đường bao và số đo ở nơi nhận.

Nếu mẫu đoạn thẳng đã biết không trả 50 trong dung sai đã nêu, kiểm tra bạn chọn phần tử nào và dữ liệu nguồn có đổi không. Nếu kết quả cục bộ khớp nhưng kích thước danh nghĩa khác, kiểm tra khung nhìn, biến đổi và tỷ lệ nơi nhận trước khi sửa đường dẫn. Thêm chữ số thập phân không giải quyết ánh xạ tọa độ sai.

Kiểm tra hình học tệp hoàn tất khi người khác tái tạo được tổng đường bao đã chọn và hiểu đơn vị, ánh xạ, dung sai và đối tượng được tính. Mẫu trình duyệt giữ lại của chúng tôi đạt các kiểm soát số đó. Không thử nhập trình biên tập, hành trình máy hay kích thước vật lý.

Nếu nguồn duy nhất là bitmap, quy trình ảnh sang vector của PerfectVector có thể tái tạo hình học SVG chỉnh sửa được trước. Kiểm tra đường bao và lỗ khôi phục rồi đo hình học đã chọn với tỷ lệ rõ ràng. Vector hóa tạo đường dẫn từ pixel; nó không khôi phục kích thước vật lý đã mất, suy ra đường tâm hay cung cấp ước tính hành trình máy. Giữ bản vector gốc hiện có khi có sẵn. Biểu tượng trong bài được tạo trực tiếp, không đồ lại.

Câu hỏi thường gặp

getTotalLength() trả pixel hay milimét? Nó trả độ dài do trình duyệt tính theo đơn vị người dùng SVG. Xác lập ánh xạ tọa độ và kích thước trước khi biểu diễn kết quả thành pixel khung nhìn hoặc đơn vị vật lý danh nghĩa.

Vì sao co giãn đường dẫn không đổi kết quả API cục bộ? Tuyến cục bộ được lưu và cách biểu diễn đã biến đổi ở các không gian tọa độ khác nhau. Đoạn cùng dữ liệu của chúng tôi trả 50 cục bộ sau cả co giãn đều lẫn không đều. Độ dài sau biến đổi là 100 và khoảng 72,111 đơn vị SVG gốc.

pathLength="1" có nghĩa đường dẫn dài một đơn vị không? Nó cung cấp giá trị hiệu chuẩn cho hành vi khoảng cách dọc đường dẫn được hỗ trợ. Độ dài tính bởi API hình học bỏ qua thuộc tính đó; mẫu 50 đơn vị vẫn trả 50.

Tôi có thể ước tính thời gian cắt từ tổng đường bao không? Chỉ tổng là không đủ. Nó không xác lập các tuyến nơi nhận tạo, di chuyển giữa đường bao, nhiều lượt, thay đổi tốc độ hay hành vi vật liệu. Dùng kiểm tra công việc của nơi nhận thực tế và thử nghiệm sản xuất phù hợp.

Nguồn tham khảo

  1. MDN: SVGGeometryElement.getTotalLength() — Độ dài đường dẫn trình duyệt tính theo đơn vị người dùng.
  2. W3C API hình học SVG — Độ dài tính và sự độc lập với hiệu chuẩn pathLength.
  3. W3C Hệ tọa độ SVG — Ánh xạ khung nhìn, viewBox và biến đổi.
  4. MDN: pathLength — Hiệu chuẩn hành vi khoảng cách dọc đường dẫn.
  5. W3C Đường dẫn SVG — Đường con, đoạn vẽ và lệnh đóng.

Cần hình học chỉnh sửa được từ bitmap trước khi đo? Tạo phương án SVG, kiểm tra đường bao nó chứa và xác lập tỷ lệ dự định trước khi ghi độ dài.

Thêm từ blog

PerfectVector

Bắt đầu với SVG gọn sạch hơn
và dễ chỉnh sửa hơn

Không cần thẻ tín dụng