SVG from Zero to Senior · Part 22 — Motion Paths & Following a Curve
Part 22: make anything travel along a curve. Master animateMotion, reuse a path with <mpath>, and use rotate="auto" so a traveler banks into the turn instead of sliding — plus the CSS offset-path equivalent. With a live demo.
Ở Phần 21 bạn dàn cảnh theo thời gian. Giờ ta cho mọi thứ di chuyển qua không gian dọc bất kỳ đường cong nào bạn vẽ được. Một sao chổi lướt theo cung, một xe chạy đường quanh co, một nhãn cưỡi sóng — tất cả dùng một công cụ: <animateMotion>. Và thuộc tính tách chuyển động nghiệp dư khỏi senior là rotate="auto".
Hai mũi tên dưới đi theo cùng đường ở cùng tốc độ — chỉ khác rotate="auto". Xem cái xanh lá nghiêng vào khúc cua chữ S.
Mở demo đầy đủ:
<animateMotion> và tái dùng path với <mpath>
animateMotion di chuyển phần tử cha của nó dọc một path. Bạn có thể nội tuyến path trong thuộc tính path, nhưng mẫu senior là vẽ path một lần thành <path> thật rồi tham chiếu — để con đường nhìn thấy và chuyển động chắc chắn trùng khớp:
<path id="road" d="M30 200 C120 40, 300 40, 360 140 S440 220, 450 60" fill="none"/>
<g>
<polygon points="0,-9 20,0 0,9 5,0" fill="#c8ff00"/>
<animateMotion dur="5s" repeatCount="indefinite" rotate="auto">
<mpath href="#road"/>
</animateMotion>
</g>
Hai chi tiết senior: vật được vẽ quanh gốc của chính nó (0,0) — animateMotion đặt gốc đó lên path, nên hãy thiết kế hình tâm tại (0,0). Và mũi tên hướng theo +x, vì với rotate="auto" trục +x cục bộ được căn theo tiếp tuyến.
rotate — khác biệt giữa bay và trượt
| Value | Hiệu ứng |
|---|---|
(none / 0) | giữ hướng gốc — trượt ngang |
auto | xoay để +x hướng tiếp tuyến — nghiêng vào cua |
auto-reverse | như auto, nhưng quay ngược dọc path |
| a number (deg) | một góc xoay cố định thêm |
rotate="auto" làm chiếc máy bay trông như đang bay theo lộ trình thay vì bị kéo lê.
Điều khiển nhịp dọc path: keyPoints & keyTimes
Mặc định chuyển động đều tốc độ dọc path. Để dừng, tăng tốc, hay nán lại ở điểm, ghép keyPoints (phần 0–1 dọc path) với keyTimes (phần 0–1 của thời lượng):
<animateMotion dur="6s" rotate="auto"
keyPoints="0; 0.5; 0.5; 1"
keyTimes="0; 0.4; 0.7; 1"
calcMode="linear">
<mpath href="#road"/>
</animateMotion>
Ở đây vật tới trung điểm path ở 40% thời gian, nán lại tới 70% (cùng keyPoint, keyTime sau), rồi kết — hoàn hảo cho một điểm dừng giao hàng hay một nhịp trong câu chuyện.
Tương đương CSS hiện đại: offset-path
SVG không còn là cách duy nhất. CSS Motion Path làm điều tương tự cho mọi phần tử, và nó animate trên compositor:
.traveler {
offset-path: path('M30 200 C120 40, 300 40, 360 140 S440 220, 450 60');
offset-rotate: auto; /* === rotate="auto" */
animation: drive 5s linear infinite;
}
@keyframes drive { to { offset-distance: 100%; } }
Dùng offset-path trong UI sản phẩm (thân thiện GPU); dùng <animateMotion> khi animation phải nằm bên trong file .svg chuyển giao được.
Lời cảnh báo của sư phụ
- Thiết kế vật quanh
(0,0). Hình lệch gốc sẽ quay quanh kỳ lạ. - Cho hình hướng theo +x. Với
rotate="auto", +x là “trước”. keyPointscầnkeyTimesvàcalcMode.- Chuyển động nặng/tương tác thì ưu tiên
offset-path/JS.
Thực hành
- Thử nghiệm hướng: cho một icon đi vòng có và không
rotate="auto". - Nán lại: cho xe buýt dừng ở hai trạm dọc tuyến.
- Chuyển sang CSS: dựng lại một vật bằng
offset-path+offset-rotate.
Phần tiếp theo
Vật của bạn giờ di chuyển qua không gian, hướng đúng. Nhưng chúng vẫn cứng đờ. Để thổi hồn một nhân vật bạn cần các bộ phận chuyển động tương đối với nhau. Ở Phần 23 ta xử lý rigging nhân vật — điểm xoay với transform-origin, nhóm lồng nhau làm khớp, và chuỗi transform phân cấp tạo cánh tay vẫy và chu kỳ bước đi.