Spec-Zone.ru › CSS

Функция CSS `ray()`

Базовая поддержка Широко доступна

Эта функция хорошо зарекомендовала себя и работает на множестве устройств и в разных версиях браузеров. Она доступна во всех браузерах с сентября 2022 года.

ray() — CSS-функция, которая задаёт отрезок линии offset-path, по которому может перемещаться анимированный элемент. Этот отрезок называется «лучом». Луч начинается в точке offset-position и продолжается в направлении указанного угла. Длину луча можно ограничить, указав размер и используя ключевое слово contain.

Синтаксис

/* 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), элемент размещается в center (или 50% 50%) содержащего блока. Значение offset-position: auto задаёт начальное положение в top left углу (или 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> = 
  [ [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ] ]

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

Примеры

Задание угла и начального положения луча

В этом примере показано, как задать начальное положение элемента и как указанный угол луча влияет на его ориентацию.

CSS

body {
  width: fit-content;
  height: fit-content;
}

.container {
  width: 80vw;
  height: 100px;
  border: 1px dashed black;
  margin: 0 0.5em 2em 2em;
  text-align: center;
}

pre {
  font-size: 1em;
  text-align: right;
  padding-right: 10px;
  line-height: 1em;
}

.box {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50px;
  height: 50px;
}

.box + .box {
  opacity: 1;
}
.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);
}
<pre>/* original */</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box0">0</div>
</div>

<pre>
  offset-path: ray(0deg);
  /* Default offset starting position is 50% 50% */
</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box1">1</div>
</div>

<pre>
  offset-path: ray(150deg);
</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box2">2</div>
</div>

<pre>
  offset-rotate: 0deg;
  offset-position: 20% 40%;
  offset-path: ray(150deg);
</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box3">3</div>
</div>

<pre>
  offset-position: 0 0;
  offset-path: ray(0deg);
</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box4">4</div>
</div>

<pre>
  offset-path: ray(60deg closest-side at bottom right);
</pre>
<div class="container">
  <div class="box">0</div>
  <div class="box box5">5</div>
</div>

Как и у transform-origin, точка привязки по умолчанию находится в центре элемента. Её можно изменить с помощью свойства offset-anchor.

В этом примере к блокам с номерами от 1 до 5 применяются различные значения offset-path: ray(). «Содержащий блок» каждого блока обозначен пунктирной рамкой. В левом верхнем углу показан полупрозрачный блок — положение каждого блока по умолчанию, без применения offset-position или offset-path, что позволяет сравнить их рядом. Верхняя сторона каждого блока выделена рамкой solid, чтобы показать различия в начальном положении и ориентации луча. После размещения в начальной точке луча блок ориентируется в направлении заданного угла луча. Если offset-position не задано, начальным положением смещения луча по умолчанию служит центр (или 50% 50%) содержащего блока.

Результат

  • Изначально box1 размещается так, что его точка привязки (центр) находится в начальной точке смещения по умолчанию (50% 50% содержащего блока). box1 также поворачивается в направлении угла 0deg луча. Теперь это будет начальная точка пути. Изменение положения и поворота блока можно увидеть, сравнив его с полупрозрачным box0 слева. Блок поворачивается в соответствии с углом 0deg на оси Y, направленной вверх. О повороте блока можно судить по ориентации цифры внутри него.

  • В box2 к лучу применяется больший положительный угол 150deg, чтобы показать, как работает угол луча. Начиная с верхнего левого угла, блок поворачивается по часовой стрелке до указанного угла 150deg.

  • У box2 и box3 одинаковые значения offset-path. В box3 к элементу также применяется offset-rotate со значением 0deg. В результате элемент сохраняет этот угол поворота на всём протяжении пути луча и не поворачивается в направлении пути. Обратите внимание, что в box3 путь луча расположен под углом 150deg, но ориентация блока не меняется вдоль пути благодаря offset-rotate. Также обратите внимание, что свойство offset-path элемента box3 не задаёт начальное значение <position>, поэтому начальное положение луча определяется значением offset-position элемента, которое в данном случае равно top 20% left 40%.

  • Значение offset-position элемента box4 задано как верхний левый угол (0 0) содержащего блока, поэтому точка привязки элемента совпадает с начальной точкой смещения. В этой начальной точке к элементу применяется угол луча 0deg.

  • В box5 свойство offset-path задаёт значение at <position>, которое размещает блок у bottom и right края содержащего блока элемента; к углу луча применяется 60deg.

Анимация элемента вдоль луча

В этом примере первая фигура показана как ориентир для положения и ориентации. Для остальных фигур задан путь движения в виде луча.

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%;
  }
}
<div>
  <div class="container">
    <div class="shape shape1">&mdash;</div>
  </div>
</div>

<pre>/* no offset-path applied */</pre>

<div>
  <div class="container">
    <div class="shape shape2">&mdash;</div>
  </div>
</div>

<pre>offset-path: ray(120deg sides contain);</pre>

<div>
  <div class="container">
    <div class="shape shape3">&mdash;</div>
  </div>
</div>

<pre>
offset-path: ray(120deg sides contain);
offset-rotate: 0deg;
</pre>

<div>
  <div class="container">
    <div class="shape shape4">&mdash;</div>
  </div>
</div>

<pre>
  offset-position: auto;
  offset-path: ray(120deg closest-corner);
</pre>

<div>
  <div class="container">
    <div class="shape shape5">&mdash;</div>
  </div>
</div>

<pre>
  offset-position: auto;
  offset-path: ray(120deg farthest-corner);
</pre>

Результат

В первых двух примерах, где применяется offset-path, обратите внимание на ориентацию фигуры без offset-rotate и с offset-rotate. В обоих примерах используется значение offset-position по умолчанию — normal, поэтому движение по пути начинается из 50% 50%. В двух последних примерах offset-path показано влияние значений <size> углов: closest-corner и farthest-corner. Значение closest-corner создаёт очень короткий путь смещения, поскольку фигура уже находится в углу (offset-position: auto). Значение farthest-corner создаёт самый длинный путь смещения — от верхнего левого угла содержащего блока до нижнего правого.

Спецификации

Спецификация
Модуль Motion Path, уровень 1
# funcdef-ray

Совместимость с браузерами

Настольные компьютеры Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome для Android Firefox для Android Opera для Android Safari на iOS Samsung Internet WebView для Android WebView на iOS
ray
116
116
122
102
16
116
122
78
16
24.0
116
16
position
116
116
122
102
17.2
116
122
78
17.2
24.0
116
17.2
size
116
116
122
102
17
116
122
78
17
24.0
116
17

См. также

  • offset-distance
  • offset-path
  • offset-rotate

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/ray

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API