Skip to main content

Module paint_order

Module paint_order 

Source
Expand description

描画順(スタッキング順)の算出。

§背景 — 実際に踏んだバグ

描画側は全要素を z_index でフラットにソートしていた。ところが実サイトの CSS には

section { position: relative; z-index: 5 }

があり、<section class="hero" id="home"> は z=5、その子孫 (.hero-overlay / .hero-content / .hero-title)は position: static なので z=0 だった。 フラットソートでは セクションが自分の子孫より後に描かれ、自分の背景で 自分の中身を丸ごと消してしまう。実測でも、ヒーローテキストは描画直後に 1655px 残っているのに draw() 終了時点で 0 になっていた。

§仕様(CSS 2.1 Appendix E)

スタッキングコンテキストを作る要素は、自分の背景を先に描き、子孫はその コンテキストの中で描かれる。子孫が祖先の背景より前に描かれることは無い

§実装方針

各要素の「実効 z」を max(自分の z, 祖先の実効 z) とする。 文書順では祖先が必ず子孫より先に現れるため、実効 z が同値なら安定ソートが 祖先→子孫の順を保つ。これで祖先の背景が子孫を塗り潰す事故は起きない。 子孫が自前でより大きい z-index を持つ場合はその値が勝ち、祖先より後= 手前に描かれる(これも仕様どおり)。

グローバル状態にもハードウェアにも依存しない純粋ロジックのみで構成する。

Enums§

PaintOrderError
実効 z の算出でおかしな入力を検出した場合のエラー。

Constants§

MAX_DEPTH
祖先チェーンの深さ上限。これを超えるツリーは異常とみなす。

Functions§

effective_z
要素の実効 z を求める。
effective_z_from_chain
祖先チェーン(ルート→親の順)から実効 z を求める。
paint_sort_key
描画ソートキー。(実効 z, ツリー深さ) の昇順で並べる。