Clay – Thư viện bố cục UI
(nicbarker.com)- Clay là thư viện bố cục UI tự động kiểu Flexbox viết bằng C, hướng tới việc xây dựng UI theo kiểu khai báo ngay cả trong engine tùy chỉnh hoặc môi trường cấp thấp
- Được cung cấp dưới dạng một file header duy nhất, có thể dùng trong C/C++; nhấn mạnh khoảng 2.000 dòng mã C99 và kết quả biên dịch
.wasm15KB - Không có phụ thuộc, kể cả thư viện chuẩn C, và có thể dùng tách biệt với các phương thức render như Raylib, WebGL Canvas, HTML
- Đủ nhanh để tính lại toàn bộ UI ở mỗi frame; hoạt động với 3,5MB bộ nhớ mặc định cùng cơ chế cấp phát tĩnh và tái sử dụng, không cần
malloc/free - Có thể trộn vòng lặp, câu điều kiện, hàm của mã C với cây phân cấp UI, và kiểm tra trạng thái bố cục theo thời gian thực bằng công cụ debug tích hợp
Header đơn C99 và mô hình bộ nhớ
- Clay là thư viện bố cục tự động kiểu Flexbox dựa trên C
- Sử dụng cú pháp khai báo
- Nêu bật hiệu năng ở mức micro giây
- Bản thân trang web hiện tại cũng được bố cục bằng Clay
- Được cung cấp dưới dạng file header duy nhất
- Có thể dùng trong C/C++
- Include theo kiểu
#include clay.h - Gồm khoảng 2.000 dòng mã C99
- Không có phụ thuộc, kể cả thư viện chuẩn C
- Khi biên dịch sang
.wasmcó kích thước 15KB
- Cách dùng hiệu năng và bộ nhớ được thiết kế với cập nhật UI thời gian thực trong tâm trí
- Đủ nhanh để tính lại toàn bộ UI ở mỗi frame
- Mức dùng bộ nhớ mặc định là 3,5MB
- Sử dụng cấp phát tĩnh và tái sử dụng
- Không dùng
mallocvàfree - Có thể đơn giản hóa thiết kế animation và UI responsive mà không cần các kỹ thuật né tránh chi phí hiệu năng thông thường
UI khai báo và tách biệt renderer
- Cú pháp khai báo tập trung vào việc cấu trúc cây phân cấp các phần tử UI lồng nhau theo cách dễ đọc
- Có thể dùng trộn các phần tử UI với vòng lặp, câu điều kiện và hàm của C
- Có thể tạo thư viện component tái sử dụng từ các phần tử UI cơ bản như văn bản, hình ảnh, hình chữ nhật
- Clay không phụ thuộc vào renderer hay nền tảng
- Bố cục do Clay xử lý, còn render có thể thực hiện bằng Raylib, WebGL Canvas, HTML, v.v.
- Đầu ra là một mảng đã sắp xếp gồm các lệnh render nguyên thủy như
RECTANGLE,TEXT,IMAGE - Có thể tự viết renderer bằng vài trăm dòng mã hoặc dùng các ví dụ được cung cấp
- Renderer HTML cũng được cung cấp, và trang hiện tại là một ví dụ
- Bao gồm công cụ debug tích hợp
- Cung cấp công cụ debug kiểu Chrome Inspector
- Có thể xem cây phân cấp bố cục và thiết lập theo thời gian thực
- Có thể nhấn phím
dtrên trang để dùng thử công cụ debug
1 bình luận
Ý kiến trên Hacker News
Trông đẹp, và video YouTube do chính nhà phát triển giải thích cũng rất tuyệt: https://www.youtube.com/watch?v=DYWTw19_8r4
Hình thức hiện đại là GUI dựa trên chuột do Xerox tạo ra vào thập niên 1970, sau đó được thương mại hóa thành Xerox Star; Jobs chịu ảnh hưởng để làm Apple Lisa, còn Gates chịu ảnh hưởng để làm MS Windows
GUI framework quyết định giao diện và cảm giác của nền tảng, đồng thời chi phối việc nhà phát triển có thể tạo ứng dụng dễ đến mức nào, nên nó trở thành trọng tâm của nhiều cuộc cạnh tranh nền tảng như hệ điều hành, trình duyệt, engine đồ họa, v.v.
Làm được bằng vài nghìn dòng thì khá ngầu
Tuy nhiên tôi thích CSS Grid hơn Flex, nên đã làm một thư viện layout CSS Grid bằng Nim thuần và cũng khá tự hào về nó: https://github.com/elcritch/cssgrid
Tôi cũng muốn xem Clay và so sánh thuật toán layout; nhìn các hộp tự thay đổi kích thước bằng thuật toán mình tự triển khai khá thú vị
Cũng tò mò liệu có thể expose giao diện C không
Nó cũng hỗ trợ Flexbox và layout Block, license của cả hai có vẻ đều kiểu MIT nên bạn có thể lấy những phần cần dùng. Tuy vậy nếu thêm file LICENSE thì sẽ dễ tìm hơn
Mục tiêu là tương thích web hoàn chỉnh nhưng hiện vẫn chưa đạt hoàn toàn; phần có thể khiến bạn quan tâm đặc biệt là bộ test khá lớn
Test được định nghĩa bằng các mảnh HTML, chạy Chrome qua webdriver để trích xuất các assertion đúng, rồi chuyển thành unit test bằng code thuần. Nếu muốn, bạn có thể viết bộ sinh test riêng và tái sử dụng các mảnh của chúng tôi
Hạ tầng test này cũng được chia sẻ một phần với Yoga, bản triển khai Flexbox bằng C++ dùng để chạy React Native: https://github.com/facebook/yoga
Với các trường hợp đơn giản không có cell span như Flexbox thì có thể làm tương đối dễ, nhưng nếu không thì không hề đơn giản, cần cách tiếp cận như bộ giải simplex hoặc Cassowary: https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
Ở cuối có nút chuyển giữa HTML và Canvas, và thường gần như không thấy khác biệt, rất ấn tượng
Nhưng với tổ hợp iOS Safari và Dark Reader, trang HTML chuyển sang dark mode còn trang Canvas thì không, nên với cá nhân tôi điểm “wow” bị giảm
Dù vậy nhìn vẫn đẹp
Canvas cũng đủ nhanh, nhưng có thể cảm nhận khác biệt ở animation “High performance” hoặc khi cuộn
Không thể chọn bất kỳ đoạn văn bản nào phía sau animation
Có vẻ thứ gì đó đang chiếm focus; khi cố chọn văn bản thì vùng chọn lập tức bị bỏ
Điều thú vị là Firefox render trang này tệ hơn nhiều: https://imgur.com/a/DNYe2WN
Đây là một cách diễn giải thú vị cho phong cách UI mà tôi thật sự thích
Cách tách logic UI và phần vẽ thành tập lệnh vẽ rất tuyệt và cực kỳ đa dụng. Lần đầu tôi thấy ở microui, và nhờ sự tách biệt đó mà có thể dễ dàng dùng thư viện trong trình duyệt với WASM và Canvas2D: https://rxi.github.io/microui_v2_an_implementation_overview.html
Ý tưởng tính layout trong WASM rồi render bằng HTML cũng hay; không hiểu sao trước đây tôi chưa nghĩ tới
Ban đầu tôi nghĩ có cần phải viết bằng C không, chẳng phải có thể làm an toàn hơn bằng Haskell hay OCaml sao
Nhưng nếu là 2.000 dòng C và không có dependency thì khá tuyệt
Cũng có taffy viết bằng Rust, và C binding đang được phát triển: https://crates.io/crates/taffy
Là bản nháp đầu tiên thì tốt
Tuy nhiên việc output HTML chỉ toàn phần tử div thì hơi tiếc, và chỉ cần chú ý một chút đến khả năng tiếp cận là sẽ cải thiện đáng kể
Một vấn đề nữa là ở nhiều chỗ, khi cố chọn văn bản thì trang render lại và vùng chọn bị bỏ trước khi kịp nhấn control-c
Nói nghiêm túc thì, dù ý tưởng có hay đi nữa, việc viết trang web theo kiểu này có vẻ hơi quá đà
Bên trong
LandingPageDesktop()là các lời gọi nhưCLAY(...),CLAY_TEXT(...),LandingPageBlob(...)được lồng rất sâu, và mã nguồn ví dụ ở đây: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2AWT, SWT, Swing, Qt, Fyne, v.v. đều tương tự
https://docs.oracle.com/javase/7/docs/api/java/awt/GridLayout.html
https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet75.java
https://stackoverflow.com/a/12867862/243613
https://stackoverflow.com/questions/37304684/qwidgetsetlayout-attempting-to-set-qlayout-on-mainwindow-which-already
Qt thực ra có một hệ thống bố cục trông như dựa trên XML, nhưng cũng có thể viết bằng code và nói chung không được khuyến nghị
https://gist.github.com/ledongthuc/9686787fe51bbe763fa1e50389d63351
Nếu chia từng phần thành các hàm có tên, có thể tạo cấu trúc dễ đọc hơn như
LandingPageDesktop(...),LandingPage(...),LeftText()Vấn đề thật sự nằm ở việc cố biểu diễn các đối tượng đồ họa và mối quan hệ của chúng bằng văn bản. Các công cụ dựng giao diện đồ họa hay RAD trông như lời giải hiển nhiên, nhưng cách tiếp cận đó nhìn chung đã bị bỏ lại
Công việc rất ấn tượng. Tôi nghĩ trong trình duyệt, văn bản có thể chọn được là điều bắt buộc
Với các client và ứng dụng không cần tính năng đó, hoặc có thể tự cung cấp, đây có vẻ là một giải pháp rất nhỏ gọn và hay
Lại phải nói cùng một chuyện, nhưng tôi cảm thấy trong các thay đổi UI những năm gần đây, sự thoái lui của tính phổ quát của clipboard là một trong những mất mát bị đánh giá thấp nhất, cùng với sự thoái lui của khả năng liên kết và nhúng