PerfectVector
Bởi Irene Kim10 phút đọc

Thứ tự transform SVG: đổi tỷ lệ và đặt vị trí hình

So sánh thứ tự translate và scale trong SVG qua logo có số đo. Dùng nhóm lồng nhau, theo dõi một điểm và bố trí hình mà không thay đổi đường dẫn nguồn.

Trên trang này

Với thuộc tính SVG transform="translate(60 25) scale(2)", tọa độ điểm nguồn được nhân với 2, rồi di chuyển 60 đơn vị theo chiều ngang và 25 theo chiều dọc khi ánh xạ vào hệ tọa độ cha. Đảo danh sách thành scale(2) translate(60 25), và độ dịch chuyển cũng được nhân đôi. Hình có cùng kích thước nhưng ở vị trí khác.

Khi logo nhảy vị trí sau khi đổi kích thước, hãy kiểm tra danh sách transform trước khi chỉnh sửa đường dẫn. Một cách sắp xếp hữu ích là nhóm ngoài để bố trí và nhóm trong để thay đổi tỷ lệ. Hai nhiệm vụ luôn rõ ràng, và tọa độ hình gốc vẫn sẵn có để chỉnh sửa về sau.

Theo dõi một điểm thay vì đoán thứ tự

Lấy điểm nguồn (10, 10). Với tỷ lệ 2 và độ dịch chuyển (60, 25), hai danh sách cho kết quả:

Thuộc tính transform SVGPhép tính điểmĐiểm cuối trong tọa độ cha
translate(60 25) scale(2)(10 × 2 + 60, 10 × 2 + 25)(80, 45)
scale(2) translate(60 25)((10 + 60) × 2, (10 + 25) × 2)(140, 70)

Cả hai điểm xuất phát từ cùng tọa độ nguồn. Danh sách thứ hai thay đổi tỷ lệ cả độ dịch chuyển lẫn hình. Vị trí cuối của nó lệch (60, 25) so với danh sách đầu.

Bạn có thể gặp các mô tả thứ tự tưởng như mâu thuẫn. Đặc tả SVG mô tả danh sách như các hệ tọa độ lồng nhau theo thứ tự viết: transform ngoài cùng bên trái trở thành nhóm ngoài. Khi theo dõi điểm nguồn đi ra qua các nhóm đó, phép biến đổi trong cùng tác động trước. Định nghĩa thuộc tính transform của W3C minh họa rõ cấu trúc lồng tương đương.

Với phép tính điểm, đi từ hàm ngoài cùng bên phải sang trái. Với cấu trúc nhóm, đọc từ ngoài vào trong. Giữ cách diễn giải đã chọn nhất quán trong toàn bộ phép tính.

So sánh cùng biểu trưng gồm hai phần

Lưu ví dụ đầy đủ này thành transform-order.svg và mở trong trình duyệt. Hình là một vòng vuông tự tạo với điểm nhấn tam giác riêng. Khoảng trống là vùng rỗng thực sự được xác định bằng quy tắc tô even-odd.

<svg xmlns="http://www.w3.org/2000/svg" width="700" height="400"
     viewBox="0 0 350 200">
  <g id="art" transform="translate(60 25) scale(2)">
    <path fill="#147d78" fill-rule="evenodd"
      d="M10 10H50V50H10Z M20 20H40V40H20Z"/>
    <path fill="#e5a340" d="M65 40L85 10L105 40Z"/>
  </g>
</svg>

Chỉ đổi thuộc tính nhóm thành transform="scale(2) translate(60 25)". Biểu trưng di chuyển xa hơn sang phải và xuống dưới, trong khi kích thước và khoảng cách giữa các phần giữ nguyên.

Chúng tôi hiển thị cả hai danh sách và phiên bản nhóm lồng tương đương trong trình duyệt. Các khung so sánh dùng vùng tọa độ giống hệt; biểu trưng mờ cho thấy hình học gốc. Mỗi chấm đỏ đánh dấu nơi điểm nguồn (10, 10) được đưa đến.

So sánh trong trình duyệt vòng vuông và tam giác với danh sách translate và scale đảo thứ tự, bên cạnh cách sắp xếp nhóm lồng tương đương
Cùng các đường dẫn gốc dưới ba cách sắp xếp transform. Danh sách đầu và nhóm lồng đặt điểm đánh dấu tại (80, 45); danh sách đảo đặt tại (140, 70).

Hộp cục bộ của hình gốc là x=10, y=10, width=95, height=40. Cách sắp xếp đầu tạo giới hạn trong hệ tọa độ của phần tử SVG gốc là x=80, y=45, width=190, height=80. Danh sách đảo tạo x=140, y=70, cùng kích thước 190 × 80.

Các số đo này mô tả mẫu thử đơn giản không có đường viền này. Ví dụ không có chuyển động hay CSS transform. Nó minh họa việc kết hợp tọa độ, không minh họa chất lượng chuyển đổi PerfectVector hoặc tính tương thích với mọi trình chỉnh sửa SVG.

Tách vị trí khỏi kích thước bằng nhóm lồng nhau

Thay nhóm gốc bằng cấu trúc này, giữ nguyên các đường dẫn:

<g transform="translate(60 25)">
  <g id="art" transform="scale(2)">
    <path fill="#147d78" fill-rule="evenodd"
      d="M10 10H50V50H10Z M20 20H40V40H20Z"/>
    <path fill="#e5a340" d="M65 40L85 10L105 40Z"/>
  </g>
</g>

Cấu trúc này khớp với translate(60 25) scale(2) trên một nhóm. Phép dịch chuyển ngoài đặt vị trí hệ tọa độ đã thay đổi tỷ lệ. Thay đổi tỷ lệ trong giữ các giá trị dịch chuyển ngoài ở (60, 25).

Điều đó không có nghĩa mọi điểm nhìn thấy giữ cố định khi bạn thay đổi tỷ lệ. Điểm cách gốc tọa độ cục bộ vẫn di chuyển khi tọa độ được nhân. Quyết định điểm nguồn nào cần neo hình trước khi chọn độ dịch chuyển.

Ví dụ, giả sử góc nguồn (10, 10) của vòng cần đến (120, 80) sau khi nhân tỷ lệ 2. Tính:

tx = targetX - scale × anchorX = 120 - 2 × 10 = 100
ty = targetY - scale × anchorY =  80 - 2 × 10 =  60

Dùng translate(100 60) scale(2). Góc đó giờ ánh xạ tới (120, 80). Dịch chuyển trực tiếp bằng (120, 80) sẽ đặt gốc tọa độ cục bộ ở đó và để góc xa hơn sang phải và xuống dưới.

Phép tính này giả định thay đổi tỷ lệ đồng đều, không xoay hoặc nghiêng. Với tâm xoay được chọn chủ động, dùng hướng dẫn transform-origin SVG. Giữ mỗi transform trên nhóm phụ trách nhiệm vụ đó thay vì kết hợp các hiệu chỉnh không liên quan bằng thử và sai.

Đọc ánh xạ hiển thị khi tệp có cấu trúc lồng

SVG nhập vào có thể đã có transform trên nhiều phần tử tổ tiên. Chỉ nhìn thuộc tính của nhóm gần nhất sẽ bỏ sót tác động kết hợp. Tài liệu transform của MDN cũng lưu ý CSS transform được ưu tiên khi thuộc tính CSS và thuộc tính trình bày nhắm cùng phần tử. Kiểm tra kiểu đã tính nếu đổi thuộc tính dường như không có tác dụng.

Với SVG nội tuyến đã hiển thị, đoạn mã này ánh xạ điểm của nhóm được chọn vào tọa độ người dùng của phần tử SVG gốc:

const root = document.querySelector('svg');
const art = document.querySelector('#art');
const rootMatrix = root.getScreenCTM();
const artMatrix = art.getScreenCTM();
if (!rootMatrix || !artMatrix) throw new Error('SVG is not measurable');
 
const toRoot = rootMatrix.inverse().multiply(artMatrix);
const point = new DOMPoint(10, 10).matrixTransform(toRoot);
const result = { x: point.x, y: point.y };

Ma trận nghịch đảo của phần tử gốc loại bỏ ánh xạ màn hình chung của nó. Điều đó quan trọng vì kích thước hiển thị 700 × 400 của ví dụ gấp đôi viewBox 350 × 200. Pixel màn hình và tọa độ SVG là đơn vị khác nhau ở đây. MDN mô tả ánh xạ do getScreenCTM() trả về.

Phép so sánh trình duyệt của chúng tôi tạo matrix(2 0 0 2 60 25) cho danh sách đầu và phiên bản lồng. Danh sách đảo tạo matrix(2 0 0 2 120 50). Trong ví dụ tỷ lệ và dịch chuyển này, hai số cuối thể hiện rõ độ dịch chuyển khác nhau.

Đoạn mã giả định transform hai chiều khả nghịch. Tỷ lệ bằng không không phù hợp cho phép kiểm tra ma trận nghịch đảo này. Với lớp phủ, bản xuất khớp giới hạn, đường viền hoặc hộp xoay, dùng quy trình giới hạn SVG chi tiết hơn.

Đừng kỳ vọng getBBox() trên nhóm hình báo vị trí sau biến đổi trong hệ tọa độ của phần tử SVG gốc. Kết quả cục bộ không bao gồm transform của chính phần tử đó và của các phần tử tổ tiên, như tài liệu getBBox giải thích. Hộp cục bộ có thể giữ nguyên trong khi biểu trưng di chuyển rõ ràng.

Sửa transform trước khi dựng lại hình

Làm việc trên bản sao SVG. Xác định các đường dẫn cần di chuyển cùng nhau, rồi kiểm tra nhóm và các phần tử tổ tiên của chúng. Ghi lại điểm neo dễ nhận biết và vị trí đích dự định của điểm đó.

Thay đổi từng transform một. Nếu kích thước đúng nhưng vị trí sai, so sánh độ dịch chuyển do hai thứ tự tạo ra. Nếu các phần di chuyển độc lập, đặt vị trí chung của chúng trên nhóm chứa. Tách riêng tâm xoay khỏi câu hỏi thứ tự tỷ lệ.

Mở lại tệp đã lưu trong ứng dụng đích và kiểm tra toàn bộ phạm vi biểu trưng. Transform đúng vẫn có thể đưa hình ra ngoài viewBox hoặc vào vùng cắt. Hướng dẫn chỉnh sửa SVG trình bày quy trình làm sạch và xuất rộng hơn.

Nếu biểu trưng chỉ tồn tại dưới dạng PNG hoặc JPG và bạn cần đường bao chỉnh sửa được, công cụ vector hóa logo của PerfectVector có thể chuẩn bị một bản SVG để kiểm tra. Kiểm tra dáng bao ngoài, khoảng trống và các hình rời, rồi nhóm hình khôi phục và áp dụng transform bố trí trong trình chỉnh sửa hoặc mã.

Bitmap có thể được di chuyển và thay đổi tỷ lệ mà không cần vector hóa. Dùng đồ lại khi cần hình chỉnh sửa được, và giữ bản vector gốc nếu có. Hình học logo hoặc chữ chính xác vẫn có thể cần tái dựng thủ công; hướng dẫn vector hóa logo giải thích cách chọn phương pháp bắt đầu đó.

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

SVG áp dụng transform từ trái sang phải hay từ phải sang trái? Danh sách tương ứng với hệ tọa độ lồng nhau theo thứ tự viết, từ ngoài vào trong. Khi tính điểm nguồn đến đâu, áp dụng hàm ngoài cùng bên phải trước và đi ra ngoài về phía trái.

Vì sao đảo translate và scale khiến logo di chuyển? Khi scale đứng trước translate trong danh sách thuộc tính, scale cũng nhân độ dịch chuyển. Khi translate đứng trước scale, độ dịch chuyển nằm ngoài scale đó. Vì vậy cùng giá trị có thể cho kích thước bằng nhau ở vị trí khác nhau.

Dịch chuyển ngoài có giữ mọi điểm cố định khi đổi kích thước nhóm trong không? Không. Nó giữ giá trị dịch chuyển ngoài riêng với tỷ lệ trong. Điểm cách gốc cục bộ vẫn di chuyển khi thay đổi tỷ lệ. Chọn điểm neo và tính độ dịch chuyển cần để đặt nó.

Nguồn tham khảo

  1. W3C — thuộc tính transform SVG — Xác định quan hệ giữa danh sách transform và các hệ tọa độ lồng.
  2. MDN — SVG transform — Mô tả cú pháp transform, ánh xạ ma trận và ưu tiên CSS.
  3. MDN — getScreenCTM — Mô tả ma trận dùng để ánh xạ tọa độ SVG về khung nhìn tài liệu.
  4. MDN — getBBox — Giải thích giới hạn cục bộ và việc loại trừ transform của phần tử được đo.

Nếu logo nguồn cần hình học chỉnh sửa được, chuẩn bị một bản SVG bằng PerfectVector, kiểm tra đường bao và các phần riêng, rồi chọn điểm neo và xác minh vị trí cuối sau khi thay đổi tỷ lệ.

Thêm từ blog

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