ray()

Baseline 2024
新推出

自 ⁨2024 年 1 月⁩起,此特性已在最新的裝置和瀏覽器版本中可用。此特性可能無法在較舊的裝置或瀏覽器上使用。

ray() CSS 函式定義了動畫元素可以遵循的 offset-path 線段。該線段被稱為“射線”(ray)。射線從 offset-position 開始,並沿指定角度的方向延伸。射線的長度可以透過指定大小並使用 contain 關鍵字來約束。

語法

css
/* all parameters specified */
offset-path: ray(50deg closest-corner contain at 100px 20px);

/* two parameters specified, order does not matter */
offset-path: ray(contain 200deg);

/* only one parameter specified */
offset-path: ray(45deg);

引數

引數可以按任何順序指定。

<angle>

指定線段從偏移起始位置延伸的方向。角度 0deg 位於 y 軸上指,正角度沿順時針方向增加。

<size>

指定線段的長度,即 offset-distance 0%100% 之間的距離,相對於包含塊。這是一個可選引數(如果未指定 <size>,則使用 closest-side)。它接受以下關鍵字值之一:

closest-side:射線的起點與元素的包含塊最近的邊之間的距離。如果射線的起點位於包含塊的邊緣上,則線段的長度為零。如果射線的起點在包含塊之外,則包含塊的邊緣被視為延伸至無窮遠。這是預設值。

closest-corner:射線的起點與元素包含塊中最近的角之間的距離。如果射線的起點位於包含塊的角上,則線段的長度為零。

farthest-side:射線的起點與元素的包含塊最遠的邊之間的距離。如果射線的起點在包含塊之外,則包含塊的邊緣被視為延伸至無窮遠。

farthest-corner:射線的起點與元素包含塊中最遠的角之間的距離。

sides:射線的起點與線段與包含塊邊界相交的點之間的距離。如果起點在包含塊邊界上或之外,則線段的長度為零。

contain

縮短線段的長度,以便即使在 offset-distance: 100% 時,元素也能保持在包含塊內。具體來說,線段的長度會減少元素邊框盒寬度或高度的一半(取較大者),並且永遠不小於零。這是一個可選引數。

at <position>

指定射線的起點以及元素在其包含塊中的放置位置。這是一個可選引數。如果包含此引數,<position> 值必須以 at 關鍵字開頭。如果省略,則使用元素的 offset-position 值。如果省略且元素沒有 offset-position 值,則射線起始位置使用的值是 offset-position: normal,它將元素放置在包含塊的中心(或 50% 50%)。

描述

ray() 函式透過一個角度和一個與參考點的距離(極座標)來指定元素在二維空間中的位置,從而沿著路徑定位元素。這一特性使得 ray() 函式在建立二維空間過渡時非常有用。相比之下,這種方法不同於透過指定點與固定原點的水平和垂直距離(笛卡爾座標)來定位的方法(如 translate() 函式所使用的),也不同於透過動畫使元素沿已定義路徑移動的方法。

由於 ray() 在二維空間中工作,因此同時考慮元素的初始位置和方向非常重要。當 ray() 函式作為元素的 offset-path 值應用時,你可以透過以下方式控制這些方面:

  • 元素最初透過將元素的offset-anchor 點移動到元素的偏移起始位置來定位。預設情況下,射線的起始位置由 offset-position 值決定。如果 offset-position 被明確指定為 normal(或省略並允許其預設為 normal),則元素位於其包含塊的中心(或 50% 50%)。指定 offset-position: auto 會將起始位置設定在元素位置的左上角(或 0 0)。
  • 元素最初會旋轉,使其內聯軸(文字流動的方向)與 ray() 指定的角度對齊。例如,當 ray() 的角度為 0deg(位於 y 軸向上)時,元素的內聯軸會旋轉為垂直,以匹配射線的角度。元素在其整個路徑上都保持此旋轉。要自定義此行為,請使用 offset-rotate 屬性,它允許你為元素指定不同的旋轉角度或方向,從而更精確地控制其沿路徑移動時的外觀。例如,設定 offset-rotate: 0deg 將移除 ray() 應用的任何旋轉,使元素的內聯軸重新與文字流動方向對齊。

正式語法

<ray()> = 
ray( <angle> &&
<ray-size>? &&
contain? &&
[ at <position> ]? )

<ray-size> =
closest-side |
closest-corner |
farthest-side |
farthest-corner |
sides

<position> =
<position-one> |
<position-two> |
<position-four>

<position-one> =
left |
center |
right |
top |
bottom |
x-start |
x-end |
y-start |
y-end |
block-start |
block-end |
inline-start |
inline-end |
<length-percentage>

<position-two> =
[ left | center | right | x-start | x-end ] && [ top | center | bottom | y-start | y-end ] |
[ left | center | right | x-start | x-end | <length-percentage> ] [ top | center | bottom | y-start | y-end | <length-percentage> ] |
[ block-start | center | block-end ] && [ inline-start | center | inline-end ] |
[ start | center | end ]{2}

<position-four> =
[ [ left | right | x-start | x-end ] <length-percentage> ] && [ [ top | bottom | y-start | y-end ] <length-percentage> ] |
[ [ block-start | block-end ] <length-percentage> ] && [ [ inline-start | inline-end ] <length-percentage> ] |
[ [ start | end ] <length-percentage> ]{2}

<length-percentage> =
<length> |
<percentage>

示例

為射線定義角度和起始位置

此示例展示瞭如何處理元素的起始位置,以及指定的射線角度如何影響元素的方向。

CSS

css
.box {
  background-color: palegreen;
  border-top: 4px solid black;
  opacity: 20%;
}

.box:first-of-type {
  position: absolute;
}

.box1 {
  offset-path: ray(0deg);
}

.box2 {
  offset-path: ray(150deg);
}

.box3 {
  offset-rotate: 0deg;
  offset-position: 20% 40%;
  offset-path: ray(150deg);
}

.box4 {
  offset-position: 0 0;
  offset-path: ray(0deg);
}

.box5 {
  offset-path: ray(60deg closest-side at bottom right);
}

transform-origin 類似,預設的錨點位於元素的中心。可以使用 offset-anchor 屬性修改此錨點。

在此示例中,將各種 offset-path: ray() 值應用於編號為 15 的方框。每個方框的“包含塊”都用虛線邊框表示。左上角一個褪色的方框顯示了在未應用任何 offset-positionoffset-path 的情況下每個方框的預設位置,以便進行並排比較。每個方框的頂部都用實線邊框突出顯示,以說明射線起點和方向的變化。在射線起點定位後,方框會與指定的射線角度方向對齊。如果未指定 offset-position,射線的預設偏移起始位置是方框包含塊的中心(或 50% 50%)。

結果

  • box1 的初始位置是使其錨點(其中心)位於預設的偏移起始位置(包含塊的 50% 50%)。box1 也被旋轉以使其朝向射線的 0deg 角度。這現在將是路徑的起點。透過與左側褪色的 box0 進行比較,你可以觀察到方框位置和旋轉的變化。方框被旋轉以匹配沿 y 軸向上的 0deg 角度。方框的旋轉可以從方框內數字的方向看出。

  • box2 中,對射線應用了更大的正角度 150deg,以顯示射線角度的工作方式。從左上角開始,方框沿順時針方向旋轉以達到指定的 150deg 角度。

  • box2box3 具有相同的 offset-path 值。在 box3 中,還對元素應用了 0degoffset-rotate。因此,元素將在射線的整個路徑上保持這個特定的角度旋轉,並且元素不會沿路徑方向旋轉。請注意,在 box3 中,射線路徑為 150deg,但由於 offset-rotate,方框的方向在路徑上不會改變。另請注意,box3offset-path 屬性沒有指定起始 <position>,因此射線的起始位置從元素的 offset-position 派生,本例中為 top 20% left 40%

  • box4offset-position 設定為包含塊的左上角(0 0),因此,元素的錨點和偏移起始位置重合。0deg 的射線角度在此起始點應用於該元素。

  • box5 中,offset-path 屬性指定了 at <position> 值,將方框放置在元素包含塊的底部右側邊緣,並對射線的角度應用了 60deg

使元素沿射線動畫

在此示例中,第一個形狀作為其位置和方向的參考顯示。對其他形狀應用了射線運動路徑。

CSS

css
body {
  display: grid;
  grid-template-columns: 200px 100px;
  gap: 40px;
  margin-left: 40px;
}

.container {
  transform-style: preserve-3d;
  width: 150px;
  height: 100px;
  border: 2px dotted green;
}

.shape {
  width: 40px;
  height: 40px;
  background: #2bc4a2;
  margin: 5px;
  text-align: center;
  line-height: 40px;
  clip-path: polygon(0% 0%, 70% 0%, 100% 50%, 70% 100%, 0% 100%, 30% 50%);
  animation: move 5000ms infinite alternate ease-in-out;
}

.shape2 {
  offset-path: ray(120deg sides contain);
}

.shape3 {
  offset-rotate: 0deg;
  offset-path: ray(120deg sides contain);
}

.shape4 {
  offset-position: auto;
  offset-path: ray(120deg closest-corner);
}

.shape5 {
  offset-position: auto;
  offset-path: ray(120deg farthest-corner);
}

@keyframes move {
  0%,
  20% {
    offset-distance: 0%;
  }
  80%,
  100% {
    offset-distance: 100%;
  }
}

結果

在前兩個應用了 offset-path 的示例中,請注意在沒有 offset-rotate 和有 offset-rotate 的情況下形狀的方向。這兩個示例都使用預設的 offset-positionnormal,因此,路徑運動從 50% 50% 開始。最後兩個 offset-path 示例顯示了角 <size> 值的影響:closest-cornerfarthest-cornerclosest-corner 值建立了一個非常短的偏移路徑,因為形狀已經位於角落(offset-position: auto)。farthest-corner 值建立了最長的偏移路徑,從包含塊的左上角到右下角。

規範

規範
Motion Path Module Level 1
# ray-function

瀏覽器相容性

另見