jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

SVG from Zero to Senior · Part 21 — Choreographing a Scene with SMIL

Part 21 opens a bonus Motion & Scenes arc: direct a whole scene, not one element. Use SMIL syncbase timing (begin="other.end") to sequence sky, sun, clouds and title into a self-playing, looping scene — no JS clock. With a live demo.

3 MIN READ

Bạn đã xong hai mươi phần cốt lõi — bạn là senior. Phần này mở một nhánh bonus Motion & Scenes. Ở Phần 6 bạn animate một phần tử đơn. Một hoạt cảnh thì khác: nhiều phần tử chuyển động theo một trình tự có chủ ý, như đạo diễn hô khẩu lệnh. Điều đẹp của SMIL là SVG có thể tự dàn dựng chính nó — không cần timeline JavaScript.

Bấm Replay và xem các khẩu lệnh nổ theo thứ tự: trời sáng → mặt trời mọc → mây trôi → tiêu đề hiện → lặp lại.

Mở demo đầy đủ:

Ý tưởng cốt lõi: định thời syncbase

Đa số đặt begin theo giờ đồng hồ — begin="2s". Cái đó dễ vỡ: đổi một thời lượng là phải tự tính lại mọi con số sau đó. Nước đi senior là định thời syncbase — bắt đầu tương đối với vòng đời của animation khác:

<animate id="a_sky" attributeName="opacity" from="0.35" to="1"
         begin="0s" dur="1.4s" fill="freeze"/>

<!-- starts the instant the sky animation ENDS -->
<animate id="a_sun" attributeName="cy" from="178" to="96"
         begin="a_sky.end" dur="1.6s" fill="freeze"/>

begin="a_sky.end" nghĩa là “bắt đầu khi a_sky xong.” Bạn có thể lệch (a_sun.end+0.3s), móc vào begin thay vì end, hay kích bằng sự kiện. Đổi dur của mặt trời thì mây và tiêu đề tự dời theo — timeline khai báo và tự chữa lành.

fill="freeze" — giữ khung cuối

Mặc định animation SMIL bật về giá trị gốc khi kết thúc — chí mạng cho một cảnh dựng dần. fill="freeze" giữ trạng thái cuối để mỗi khẩu lệnh đã xong ở lại sân khấu khi cái kế tiếp diễn.

Easing trong SMIL: keySplines

SMIL tuyến tính trừ khi bạn bảo khác. Đặt calcMode="spline" và cho một đường Bézier bậc ba mỗi đoạn — cùng toán easing từ các phần CSS:

<animate attributeName="cy" from="178" to="96" dur="1.6s" fill="freeze"
         calcMode="spline" keyTimes="0;1" keySplines="0.2 0.8 0.2 1"/>

keySplines đó là ease-out — mặt trời giảm tốc khi yên vị, thay vì dừng phắt.

Cho cả cảnh lặp lại

Mẹo: đưa kết thúc của khẩu lệnh cuối vào begin của khẩu lệnh đầu như một thời điểm bắt đầu thứ hai.

<animate id="a_sky" begin="0s; a_title.end+1.2s" .../>

Một danh sách begin ngăn cách bằng chấm phẩy cho nhiều thời điểm bắt đầu; cái thứ hai nổ 1.2s sau khi tiêu đề xong, khởi động lại chuỗi — một cảnh tự duy trì.

Điều khiển từ JavaScript khi cần

SMIL phơi bày timeline của tài liệu SVG. Bạn hiếm khi cần JS, nhưng cho nút Replay chỉ một lệnh:

svg.setCurrentTime(0);          // rewind the whole timeline → scene replays
// el.beginElement();           // manually fire one animation
// el.endElement();             // cut one short

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

  • fill="freeze" hoặc cảnh của bạn reset. Mọi khẩu lệnh dựng dần cần nó.
  • Móc vào .end, đừng cứng hóa giây.
  • SMIL không được hỗ trợ ở vài ngữ cảnh. Nó vững trong trình duyệt hiện đại cho cảnh khai báo, nhưng chuyển động sản phẩm phức tạp thì dùng thư viện Phần 18.
  • Tôn trọng prefers-reduced-motion. Cho người chọn tắt một “khung cuối” tĩnh.

Thực hành

  1. Thêm khẩu lệnh thứ 5: một con chim bay ngang sau tiêu đề.
  2. Định lại thời gian cảnh: nhân đôi dur mặt trời và xác nhận mọi khẩu lệnh sau dịch theo, không sửa gì khác.
  3. Bắt đầu theo sự kiện: đổi begin đầu thành click.

Phần tiếp theo

Bạn dàn được một cảnh theo thời gian. Tiếp theo ta cho mọi thứ di chuyển qua không gian dọc các đường cong bất kỳ. Ở Phần 22 ta làm chủ motion pathanimateMotion, <mpath>, và orient="auto" để một vật đi theo con đường, một sao chổi lướt theo cung, và một nhãn cưỡi đường cong mà vẫn hướng đúng.