jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

SVG from Zero to Senior · Part 1 — Foundations & the viewBox

Start SVG the right way: what SVG really is, the coordinate system, the basic shapes, and the one concept that confuses everyone — viewBox. With a live pan/zoom playground you can drag.

Chào mừng, đồ đệ. Trong mười phần tới, sư phụ già sẽ đưa con từ “tôi copy-paste icon SVG rồi cầu nguyện” lên “tôi dựng, animate, và ship đồ hoạ vector như một senior.”

Sự thật đầu tiên: SVG không phải định dạng ảnh, nó là một ngôn ngữ vẽ. PNG là lưới pixel cố định; SVG là tập chỉ dẫn (“vẽ hình tròn ở đây, to cỡ này”) mà trình duyệt vẽ lại ở mọi kích thước, sắc nét tuyệt đối. Vì thế logo của con sắc nét cả trên màn 4K lẫn smartwatch từ cùng một file.

Nghịch demo trước — kéo slider viewBox, cảm nhận cửa sổ di chuyển trên bản vẽ, rồi mới đọc lý do.

Mở demo đầy đủ:

Bộ xương của mọi SVG

Con có thể viết SVG thẳng vào HTML — không cần <img>. Đây là inline SVG, và nó mở khoá việc style và scripting sau này.

<svg viewBox="0 0 100 100" width="200" height="200">
  <circle cx="50" cy="50" r="40" fill="#c8ff00" />
</svg>

Đọc nó như một câu: “Trong không gian toạ độ 100×100, vẽ hình tròn tâm (50,50) bán kính 40, tô màu lime, và hiển thị 200×200 pixel trên trang.”

Hệ toạ độ — giấy kẻ ô, nhưng Y hướng xuống

Bức tranh quan trọng nhất phải khắc vào đầu:

(0,0) ───────────► +X

  │     • (50,30)


 +Y
  • Gốc (0,0)góc trên-trái, không phải tâm.
  • X tăng sang phải — giống toán.
  • Y tăng xuống dưới — ngược với toán phổ thông, giống mọi màn hình.

Mọi cx, cy, x, y con từng viết đều sống trong không gian này.

viewBox — khái niệm làm ai cũng rối

Người mới tưởng width/heightviewBox giống nhau. Không phải, và hiểu khác biệt này chính là trọng tâm Phần 1.

  • = cái khung SVG to cỡ nào trên trang, tính bằng pixel thật.
  • = con cắt ra lát nào của mặt vẽ vô hạn, tính bằng user unit.

Trình duyệt rồi kéo lát cắt đó cho đầy cái khung. Nên viewBox cho con pan và zoom miễn phí:

<!-- Same drawing, two windows over it -->
<svg viewBox="0 0 200 200">...</svg>   <!-- full scene -->
<svg viewBox="50 50 100 100">...</svg>  <!-- zoomed into the middle -->

Mô hình tư duy: viewBox là khung máy ảnh lơ lửng trên giấy kẻ ô. Dịch min-x/min-y → máy ảnh lia. Thu nhỏ width/height → ít unit lấp đầy cùng số pixel → zoom vào. “World view” trong demo vẽ khung máy ảnh đó thành hình chữ nhật nét đứt để con thấy được.

Thói quen senior: đặt viewBox rồi để CSS điều khiển kích thước hiển thị. Bỏ width/height cứng và SVG trở nên co giãn.

preserveAspectRatio — nếu khung và viewBox lệch tỉ lệ?

Nếu khung 300×100 nhưng viewBox vuông, phải có cái gì nhường. Mặc định xMidYMid meet giữ tỉ lệ và canh giữa (viền đen kiểu letterbox). Dùng slice để lấp-đầy-rồi-cắt, hoặc none để kéo méo (hiếm khi con muốn).

<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice">…</svg>

Các hình cơ bản — vốn từ của con

Trước khi tới path (Phần 2), sáu primitive đã làm được nhiều bất ngờ:

<rect x="10" y="10" width="80" height="50" rx="6" />     <!-- rounded box -->
<circle cx="50" cy="50" r="40" />                         <!-- center + radius -->
<ellipse cx="50" cy="50" rx="40" ry="25" />               <!-- two radii -->
<line x1="0" y1="0" x2="100" y2="100" />                  <!-- a segment -->
<polyline points="0,40 20,10 40,40 60,10" />             <!-- open path of points -->
<polygon points="50,5 90,90 10,90" />                     <!-- auto-closed shape -->

Một cái bẫy: <line> hay <polyline> vô hình nếu không có stroke — nó không có diện tích để fill. Và <polygon> tự lặng lẽ đóng về điểm đầu, còn <polyline> thì để hở. Bật/tắt chúng trong demo và so sánh.

Lời cảnh báo của sư phụ

  • Y hướng xuống. Phân nửa lỗi “hình của tôi sai chỗ” là quên điều này.
  • viewBox không có đơn vị. Đừng viết 200px — chỉ con số.
  • Không fill cho line. Line và polyline hở cần stroke, không phải fill.

Luyện tập, không thì coi như chưa học

  1. Vẽ chữ cái đầu tên con chỉ bằng <line><polyline>.
  2. Dựng tấm bia: ba <circle> đồng tâm. Rồi đổi chỉ width/height của viewBox và xem nó zoom mà không động vào circle nào.
  3. Phá nó có chủ đích: đặt none cho bản vẽ vuông trong khung rộng và xem nó méo.

Phần tiếp theo

Giờ con đã biết đặt máy ảnh trên canvas vô hạn và vẽ bằng sáu hình. Nhưng icon, logo, biểu đồ thật được làm từ đường cong — và đường cong nghĩa là một element: <path>. Ở Phần 2 ta giải mã ngôn ngữ path — M, L, các đường Bézier C/Q, và cung elip A đáng sợ — với một trình dựng cho con kéo control point và xem thuộc tính d tự viết.