Clay – UIレイアウトライブラリ
(nicbarker.com)- ClayはCで作られたFlexboxスタイルの自動UIレイアウトライブラリで、カスタムエンジンや低レベル環境でも宣言的なUI構成を目指す
- 単一のヘッダーファイルとして提供され、C/C++で利用でき、約2,000行のC99コードと15KBの
.wasmコンパイル結果を特徴としている - C標準ライブラリを含めて依存関係がなく、Raylib、WebGL Canvas、HTMLのようなレンダリング方式と切り離して使える
- UI全体を毎フレーム再計算できるほど高速で、基本3.5MBのメモリと静的割り当て・再利用方式により
malloc/freeなしで動作する - Cコードのループ・条件分岐・関数とUI階層を混在させて使え、組み込みのデバッグツールでレイアウト状態をリアルタイムに確認できる
C99単一ヘッダーとメモリモデル
- ClayはCベースのFlexboxスタイル自動レイアウトライブラリ
- 宣言的な構文を採用
- マイクロ秒単位の性能をうたう
- 現在のWebページ自体もClayでレイアウトされている
- 単一のヘッダーファイル形式で提供される
- C/C++で利用可能
#include clay.h方式で取り込む- 約2,000行のC99コードで構成
- C標準ライブラリを含め依存関係がない
.wasmにコンパイルすると15KBサイズ
- 性能とメモリ使用方式はリアルタイムUI更新を念頭に置いている
- UI全体を毎フレーム再計算できるほど高速
- 基本メモリ使用量は3.5MB
- 静的割り当てと再利用を採用
mallocとfreeを使わない- 標準的なパフォーマンス回避テクニックなしにアニメーションとレスポンシブUI設計を単純化できる
宣言的UIとレンダラー分離
- 宣言的な構文は、入れ子になったUI要素階層を読みやすく構成することに焦点を当てている
- UI要素をCのループ、条件分岐、関数と混在させて使える
- テキスト、画像、長方形のようなUI基本要素で再利用可能なコンポーネントライブラリを作れる
- Clayはレンダラーとプラットフォームに依存しない
- レイアウトはClayが処理し、レンダリングはRaylib、WebGL Canvas、HTMLなどで実行できる
- 出力は
RECTANGLE、TEXT、IMAGEのようなプリミティブなレンダー命令の整列済み配列 - 数百行のコードで独自レンダラーを書いたり、提供されるサンプルを使ったりできる
- HTMLレンダラーも提供され、現在のページがその例である
- 組み込みのデバッグツールを含む
- Chrome Inspectorスタイルのデバッグツールを提供
- レイアウト階層と設定をリアルタイムで確認できる
- ページで
dキーを押すとデバッグツールを試せる
1件のコメント
Hacker Newsのコメント
見た目が良く、開発者本人が説明する YouTube動画 も素晴らしかった: https://www.youtube.com/watch?v=DYWTw19_8r4
現代的な形は1970年代にXeroxが作ったマウスベースのGUIで、その後Xerox Starとして商用化され、JobsがApple Lisaに、GatesがMS Windowsに影響を受けた流れである
GUIフレームワークはプラットフォームの見た目と操作感を決め、開発者がアプリをどれだけ容易に作れるかを左右するため、OS、ブラウザ、グラフィックエンジンなどさまざまな プラットフォーム競争 の中核になる
数千行で作れるのはかなりすごい
ただ、自分はFlexより CSS Grid を好むので、純粋なNimでCSS Gridレイアウトライブラリを作っていて、それなりに誇りに思っている: https://github.com/elcritch/cssgrid
Clayも見てレイアウトアルゴリズムを比較してみたいし、自分で実装したアルゴリズムでボックスが自動的にサイズ変更されるのを見るのは楽しい
Cインターフェースを公開できるのかも気になる
FlexboxとBlockレイアウトもサポートしており、ライセンスもどちらもMITのようなので、必要な部分を持っていってよいと思う。ただ、LICENSEファイルを追加すると見つけやすくなりそう
完全なWeb互換を目標にしているが、まだ完全には到達しておらず、特に興味を持ちそうなのはかなり大きなテスト群だ
テストはHTML断片として定義し、Chromeをwebdriverで動かして正しいアサーションを抽出し、それを純粋なコードの単体テストに変換している。望むなら独自のテストジェネレーターを書いて、こちらの断片を再利用できる
このテスト基盤は、React Nativeを動かしているC++のFlexbox実装 Yoga とも一部共有されている: https://github.com/facebook/yoga
Flexboxのようにセルがまたがっていない単純な場合は比較的容易だが、そうでなければ単純ではなく、シンプレックスソルバーやCassowaryのようなアプローチが必要になる: https://constraints.cs.washington.edu/solvers/cassowary-tochi.pdf
最後にHTMLとCanvasを切り替えるボタンがあるが、たいていは差がほとんどなくて見事
ただし、iOS Safariと Dark Reader の組み合わせでは、HTMLページはダークモードに変わる一方でCanvasページは変わらず、個人的には驚きのポイントが薄れた
それでも見た目は良い
Canvasも十分速いが、「High performance」なアニメーションやスクロール時には差を感じる
アニメーションの背後にあるすべてのテキストを選択できない
何かがフォーカスを奪っているようで、テキストを選択しようとすると即座に選択が解除される
興味深いのは、Firefoxのほうがこのページのレンダリングがはるかに悪いことだ: https://imgur.com/a/DNYe2WN
本当に好きなUIスタイルを楽しく解釈したものだ
UIロジックと描画を 描画コマンド群 として分離するやり方は素晴らしく、非常に汎用性が高い。最初にmicrouiで見たが、その分離のおかげでWASMとCanvas2Dを使ってブラウザでライブラリを簡単に使えた: https://rxi.github.io/microui_v2_an_implementation_overview.html
また、WASMでレイアウトを計算してHTMLでレンダリングするという発想も良く、なぜ以前思いつかなかったのか分からない
最初はCでやる必要があるのか、HaskellやOCamlでもっと安全にできるのではと思った
しかし、Cで2000行、依存関係なしならかなり良い
Rust製の taffy もあり、Cバインディングは作業中だ: https://crates.io/crates/taffy
最初のドラフトとしては良い
ただしHTML出力がdiv要素だけなのは惜しく、アクセシビリティ に少し配慮するだけでも大きく改善しそうだ
あちこちでテキストを選択しようとすると再レンダリングされ、control-cを押す前に選択が解除されてしまうのも問題だ
真面目に言うと、こういう形でWebページを書くのは、コンセプトは格好よくても少しやりすぎではないかと思う
LandingPageDesktop()の中でCLAY(...)、CLAY_TEXT(...)、LandingPageBlob(...)のような呼び出しが深くネストされる形になっていて、サンプルソースはここにある: https://github.com/nicbarker/clay/blob/35d72e5fba6872be48d15ed9d84269a86cd72b4e/examples/clay-official-website/main.c#L50C1-L67C2AWT、SWT、Swing、Qt、Fyne などもみな似たようなもの
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 には実際に XML ベースに見えるレイアウトシステムがあるが、コードでも書けるし、一般的には推奨されていない
https://gist.github.com/ledongthuc/9686787fe51bbe763fa1e50389d63351
各部分を名前付きの関数に分ければ、
LandingPageDesktop(...)、LandingPage(...)、LeftText()のように、より読みやすい構造にできる本当の問題は、グラフィックオブジェクトとその関係 をテキストで表現しようとしていることにある。グラフィックビルダーや RAD ツールが明白な解決策のように見えるが、そうしたアプローチはたいてい廃れている
素晴らしい仕事だ。ブラウザでは 選択可能なテキスト が必須だと思う
そうした機能が不要だったり、自前で提供できたりするクライアントやアプリでは、とても小さくて良い解決策に見える
また同じことを言うようだが、ここ数年の UI の変化で クリップボードの普遍性 が後退したのは、リンク可能性や埋め込みの後退と並んで、最も過小評価されている損失のひとつだと感じる