Những thứ thú vị có thể làm với SVG
(fuma-nama.vercel.app)- SVG không chỉ là một định dạng icon đơn giản; có thể kết hợp mask,
pathvà animation CSS để tạo hiệu ứng dây dẫn chạy dọc theo một đường và phần highlight TOC - Cách triển khai cốt lõi là không hiển thị trực tiếp đường được tạo bằng
linehoặcpath, mà dùng nó như một vùng mask để giới hạn phạm vi hiển thị của khối animation - Với Animated Wires, áp dụng
mask="url(#...)"chorectrồi dùng@keyframesđể di chuyểntranslateY, đồng thời mở rộng phong cách hiển thị bằnglinearGradientvà biến CSS - TOC kiểu Clerk của Fumadocs, vì tính tương thích SSR, sẽ render đường viền trên server, còn thumb biểu thị vị trí đang hoạt động thì render ở client bằng thông tin vị trí trong trình duyệt
- Thuộc tính
dcủa SVG<path>không phải là chuỗi được tạo tự động mà là một danh sách lệnh, vì vậy có thể tái tạo ở client một ảnh mask có cùng hình dạng với đường viền TOC đã được render trên server
Animated Wires tạo bằng SVG mask
- Mã ví dụ dựa trên cú pháp JSX hoặc React, không phải HTML thông thường
- Có thể tạo đường cơ bản bằng
linehoặcpathcủa SVG- Trong ví dụ, một
linedọc được đặt trongviewBox="0 0 50 50"
- Trong ví dụ, một
- Thay vì vẽ đường trực tiếp lên màn hình, dùng nó làm
maskđể giới hạn vùng hiển thị của hình khác- Áp dụng
mask="url(#line)"chorect, và đặt mộtlinemàu trắng bên trongmask
- Áp dụng
- Chuyển động được tạo bằng cách áp dụng CSS
animationchorect@keyframes to-downdi chuyển từtranslateY(-10px)đếntranslateY(50px)
- Có thể mở rộng phong cách hiển thị bằng cách kết hợp đường nền, đường mask dày hơn,
linearGradientvà biến CSS--height@keyframes to-down-2di chuyển từcalc(var(--height) * -1)đến100%
- Phần lớn các hiệu ứng tương tự đều dùng cách cắt khối animation bằng mask
- Một số thiết kế có thể tạo bằng Figma hoặc công cụ chỉnh sửa SVG khác
- Trang landing của Unkey là một ví dụ cho cách làm này
TOC kiểu Clerk của Fumadocs
- Fumadocs có triển khai mục lục (TOC) kiểu Clerk
- Để tương thích với SSR, cần render đường viền TOC trên server mà không cần JavaScript phía client
- Trên server không thể biết chính xác vị trí của các phần tử
- Cách triển khai dùng vị trí
absolute, render đường viền như nhiều component riêng rồi nối chúng lại
- Một phần của đường viền tương ứng với mục đang hoạt động hoặc heading đang hiển thị trong viewport được biểu thị bằng thumb
- Vì thumb cần có animation, chỉ đổi màu component đường viền là không đủ
- Thumb, là đối tượng tương tác, được render ở client
- Dựa trên thông tin vị trí lấy từ trình duyệt, phía client sẽ dựng một bản đồ mask
- SVG được dùng để tạo bản đồ mask này
- Thuộc tính
dcủa SVG<path>là danh sách lệnh và có thể render các đường nối giữa các điểm - Tài liệu liên quan có thể xem tại SVG Paths trên MDN Web Docs
- SVG được tạo theo cách này sẽ có cùng hình dạng với đường viền TOC gốc đã được render sẵn trên server
- Tương tự Animated Wires, SVG được đưa vào CSS
mask-imagedưới dạng data URL, rồi dùng để mask một khốidivcó animation nhằm render thumb được highlightdivbên trong dùng các giá trị nhưwidth: 1,height: thumb.height,transform: translateY(${thumb.top}px),transition: "all 500ms",backgroundColor: "white"
- Có thể xem phần triển khai React.js trong mã nguồn toc-clerk.tsx
2 bình luận
Trông thì đẹp thật, nhưng chỉ cần nhấn mạnh rõ ràng riêng mục hiện tại thôi thì sẽ dễ nhìn hơn.
Các ý kiến trên Hacker News
Dù là tài liệu từ 8 năm trước, bài thuyết trình nổi tiếng “SVG Can Do That?” của Sarah Drasner vẫn khiến nhiều người mở mang tầm mắt
Kể từ đó CSS đã trưởng thành vượt bậc, còn bản thân SVG thì tôi không chắc có đến mức đó không, nhưng dù sao cũng rất khuyến nghị
Slide: https://slides.com/sdrasner/svg-can-do-that
Video: https://youtu.be/ADXX4fmWHbo?si=6YPZkopyEDc8PSte
Một việc thú vị có thể làm với file SVG là dùng entity trong DTD inline để định nghĩa các hằng số dùng chung ở nhiều vị trí trong file
Có thể thấy một ví dụ tuyệt vời trong SVG trên trang “Squares in Squares” của David Ellsworth
Trên các trình duyệt lớn thì không vấn đề gì, nhưng một số công cụ như Inkscape thậm chí không parse DTD và cũng không mở rộng entity
[0] https://kingbird.myphotos.cc/packing/squares_in_squares.html
&refđể định nghĩa và tái sử dụng nội dung cú pháp tùy ýTrong SVG, cách làm là đặt hình, path, v.v. dưới
defs, gánid, rồi dùng lại trong phần thân SVG; trang được liên kết có vẻ cũng dùng cách đó trong từng SVGKhông phải là chia sẻ các hình vuông giữa nhiều hình, vì mỗi hình được đưa vào dưới dạng một DOM riêng
Tôi tò mò vì sao các nhà thiết kế SVG ban đầu lại thấy cần tạm thời tái triển khai cơ chế entity
Có thể liên quan đến việc có thể ghi đè thuộc tính render tại điểm sử dụng, và khi đó SVG đang nằm trong làn sóng chuyển đổi XHTML/XML của W3C, nên có lẽ tiền đề rằng trình duyệt sẽ bỏ qua định nghĩa entity hay prologue/DOCTYPE của tài liệu cũng chưa được thiết lập
!doctypehay!elementnào trên trang đó để thể hiện DTDNếu chỉ đang nói đến
defsvàusecủa SVG thì đó không phải là DTDhttps://developer.mozilla.org/en-US/docs/Web/SVG/Reference/E...
Ví dụ như Billion laughs attack
https://en.wikipedia.org/wiki/Billion_laughs_attack
“A Deep Dive Into SVG Path Commands” của Nanda Syahrasyad thật sự rất hay để hiểu các đường dẫn SVG được cấu thành như thế nào
Dù là bài viết gần 2 năm trước, nó đã giúp tôi mở mang về SVG có thể làm gì và chính xác làm bằng cách nào
[0] https://www.nan.fyi/svg-paths
Tôi từng làm một dự án dùng SVG cho những thứ thú vị như thế này
Dự án được làm bằng React, đưa các yếu tố hoạt họa vào nhiều minh họa tĩnh, và màu sắc được điều khiển từ CMS
Frontend gọi API để nhận ảnh SVG với màu đúng, còn hoạt ảnh được xử lý bằng cách ẩn và hiện các phần tử SVG
Có thể xem ví dụ ở đây: https://web.archive.org/web/20221020133516im_/https://uncrow...
Thật sự nhớ Macromedia Flash
Không có công nghệ nào giống như Flash và định dạng SWF, chỉ cần có Flash Player là có thể thưởng thức vô số game indie và phim hoạt hình mà không cần tải riêng
Rào cản gia nhập cũng rất thấp
SVG cũng có tiềm năng làm tất cả những gì SWF từng làm, nhưng không có editor như Flash hay cách lập trình dựa trên cảnh/đối tượng như ActionScript
Mỗi trình duyệt cũng có điểm kỳ quặc riêng, nên chỉ các SVG đơn giản mới được đảm bảo hiển thị đúng ở mọi nơi
Ngay từ đầu, so sánh SVG với Flash có vẻ giống như so sánh táo với cam
Định dạng SVG không cần tự mình làm trực tiếp mọi thứ Flash từng làm, mà có thể dựa vào các công nghệ khác trong trình duyệt
Ví dụ Unity, Unreal, Godot có thể compile cho trình duyệt khá dễ dàng
Vấn đề là các ứng dụng kiểu này khá phình to, thường dễ rơi vào phạm vi hàng chục MB chứ không phải chỉ vài MB một chữ số
SVG có hoạt ảnh phức tạp thì chạy thử khá vui, nhưng nếu đi sâu vào SMIL, Safari có thể làm điện thoại đơ chỉ vì thiếu một số 0 trước dấu thập phân trong số dấu phẩy động, hoặc phát sinh đủ chuyện kỳ quặc
Nếu bạn đang tạo SVG động một cách sáng tạo bằng JavaScript và đang tìm việc, có thể gửi DM cho tôi
Tôi tự hỏi liệu có phần mở rộng SVG nào cho phép điều chỉnh mật độ của nét vẽ không
Tôi có một máy plotter có thể nhấc và hạ bút, được điều khiển bằng file SVG
Sẽ rất tốt nếu có thể hạ bút trong khi đang vẽ một nét, như thường làm trong chữ viết tay
Nhân tiện, đó là Axidraw của Evil Mad Scientist Labs; thiết bị rất tuyệt và những người làm ra nó cũng rất đáng mến
Ví dụ tôi dùng một máy cắt laser/plotter đa dụng, trong đó độ mờ là công suất laser, độ dày nét là tốc độ di chuyển, kênh xanh lá là số lần lặp, kênh xanh dương là độ cao trục Z, kênh đỏ là hạ bút hoặc tắt laser, v.v.
Tôi đã làm loại công việc này ở đây
https://github.com/WillAdams/gcodepreview
Trước khi tự làm icon hay logo, tôi luôn thấy việc SVG có biến đổi (transform) là kỳ lạ
Rất khó căn các đường cong cho đúng
Sau khi hoàn thành logo thứ hai, nó trông quá phẳng nên tôi muốn nghiêng 10°, và khi nghĩ đến việc phải viết lại tất cả các đường thẳng và đường cong đó, xoay nó trông là lựa chọn tốt hơn nhiều
May là khi đặt cạnh văn bản thì trông kỳ, nên tôi lại phải đổi góc thêm vài lần để kerning nhìn có vẻ đúng
Gần đây tôi làm một game nhỏ cho vui, và phần render chủ yếu dùng các tile SVG hoạt ảnh bằng CSS: https://pipeline-panic.vercel.app/
https://boardgamegeek.com/boardgame/333/waterworks