2 điểm bởi GN⁺ 2024-12-21 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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 .wasm 15KB
  • 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 .wasm có 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 mallocfree
    • 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 d trên trang để dùng thử công cụ debug

1 bình luận

 
GN⁺ 2024-12-21
Ý 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

    • Những phần giải thích rõ ràng và trực quan như vậy khá hiếm, video này thật sự rất hay
    • Có vẻ nhà phát triển đang tái khám phá khái niệm thư viện GUI
      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

    • Hay đấy. Tôi cũng có một bản triển khai CSS Grid độc lập, viết bằng Rust: https://github.com/DioxusLabs/taffy
      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
    • Tính toán layout CSS Grid chính xác gần giống việc giải một hệ phương trình và ràng buộc
      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

    • Chọn văn bản và phóng to/thu nhỏ cũng có vấn đề
    • Có dòng “Cũng có HTML renderer. Thứ bạn đang xem chính là nó!”, nhưng lúc đọc câu đó thì tôi đã chuyển sang Canvas renderer rồi
    • Trên Chrome, HTML renderer rõ ràng nhanh hơn, tôi tò mò vì sao
      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ỏ

    • Có lẽ vì mỗi frame đều khởi tạo lại toàn bộ, và animation đang chạy
    • Trên di động, hiện tượng tương tự xảy ra ở cả trình duyệt dựa trên Chromium lẫn Gecko
      Đ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

    • Ít nhất làm như vậy thì cũng dùng được từ các ngôn ngữ khác
  • 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-L67C2

  • 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

    • Thấy việc chọn văn bản và sao chép/dán bị hỏng thì khá lạ, nhưng có vẻ cũng có thể sửa được
      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