马黑黑 发表于 2026-7-30 18:11

offset-path ray 函数演示(一)

<style>
    .artBox { margin: 20px auto; font: normal 18px/26px sans-serif; }
    .artBox mark { padding: 2px 6px; background: #ccc; }
    .artBox p { margin: 10px 0; }
</style>

<div class="artBox">
    <p>CSS 属性 <mark>offset-path</mark> 可以通过 <mark>ray()</mark> 函数创建由里往外发射的射线路径。射线路径的发起点默认在包含块即容器的中心(50% 50%);射线方向由射线角度决定,0deg 为正上方向;射线终止点在包含块内部、边界或以外。ray() 函数可支持多个参数:angle(射线角度)、size(射线尺寸)、contain(约束在包含块内)、at(射线发起位置)。这些参数,角度必须,其余可选。本演示仅使用 ray() 函数的角度参数,辅以 offset-distance 属性帮助查看射线路径信息:</p>
    <div class="hEdiv" data-prev="1"><pre class="hEpre">
&lt;style&gt;
    @import 'https://638183.freep.cn/638183/web/css/hl.css';
    .pa {
      margin: 20px auto;
      width: 200px;
    }
    .pa:nth-of-type(1) {
      height: 200px;
      border: 1px solid gray;
      margin-top: 100px;
    }
    .pa:nth-of-type(2) {
      width: 400px;
      border-width: 0;
    }
    .son {
      width: 60px;
      height: 40px;
      background: purple;
      clip-path: polygon(50% 60%,0 60%,0 40%,50% 40%,50% 0,100% 50%, 50% 100%);
      offset-path: ray(0deg);
      transition: offset-distance .7s;
    }
&lt;/style&gt;

&lt;div class="pa"&gt;
    &lt;div id="son" class="son"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="pa"&gt;
    &lt;p class="hlCode"&gt;offset-path: &lt;output id="outputCode"&gt;ray(0deg);&lt;/output&gt;&lt;/p&gt;
    &lt;p&gt;
      &lt;label for="rangeAngle"&gt;射线角度 :&lt;/label&gt;
      &lt;input id="rangeAngle" type="range" max="360" min="-360" step="5" /&gt;
      &lt;output id="outputAngle"&gt;0deg&lt;/output&gt;
    &lt;/p&gt;
    &lt;p&gt;
      &lt;label for="rangeDistance"&gt;元素在路径上的偏移位置 :&lt;/label&gt;
      &lt;input id="rangeDistance" type="range" max="100" min="0" value="0" /&gt;
      &lt;output id="outputDistance"&gt;0%&lt;/output&gt;
    &lt;/p&gt;
&lt;/div&gt;

&lt;script&gt;
    rangeAngle.oninput = () =&gt; {
      outputAngle.value = rangeAngle.value + 'deg';
      outputCode.value = `ray(${rangeAngle.value}deg);`
      son.style.offsetPath = `ray(${rangeAngle.value}deg)`;
    }
   
    rangeDistance.oninput = () =&gt; outputDistance.value = rangeDistance.value + '%';
   
    rangeDistance.onchange = () =&gt; son.style.offsetDistance = rangeDistance.value + '%';
&lt;/script&gt;
    </pre></div>
    <p>核心要点:CSS 函数 ray() 为 offset-path 属性创建的射线路径,最简单时只需要一个参数,角度参数,具体代码参见 21 行,在预览页面也会动态提供代码。ray() 函数仅设置角度参数时,其余参数为缺省默认,此时,正上、正右、正下和正左四个方向的射线路径的终点正好处在容器边界之上。演示中应该会看到运动元素(子元素)越界,那是因为运动元素的偏移锚点(由 offset-anchor 属性设置)默认设在元素的中心点,而偏移锚点是元素在 offset-distance(元素在路径上的偏移距离)为 100% 时的抛锚点;若不希望子元素整体突破容器边界,可设 <mark>offset-anchor: 100% 50%;</mark> 或 <mark>offset-anchor: right center;</mark>,即将偏移锚点设在元素X轴的右侧、Y轴的中心。</p>
</div>

<script type="module">
    import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
    const divs = document.querySelectorAll('.hEdiv');
    const pres = document.querySelectorAll('.hEpre');
    divs.forEach((div,idx) => hl.hl(div, pres));
</script>

红影 发表于 2026-7-30 20:14

在图形里理解这些参数的设置真好,可以在图中看得很清晰。
感谢黑黑的教学帖子{:4_199:}

马黑黑 发表于 2026-7-30 21:24

红影 发表于 2026-7-30 20:14
在图形里理解这些参数的设置真好,可以在图中看得很清晰。
感谢黑黑的教学帖子

先讲基础参数,往后参数一多,就会难一些

红影 发表于 2026-7-30 22:25

马黑黑 发表于 2026-7-30 21:24
先讲基础参数,往后参数一多,就会难一些

嗯嗯,参数越多越难{:4_204:}

宕.. 发表于 2026-7-30 22:31

本帖最后由 宕.. 于 2026-7-30 22:36 编辑

每次都一如既往一本正经的从头看完,然后郑重其事煞有介事的一点不通,最后知道我看过就好啊,嘿嘿{:5_106:}

杨帆 发表于 2026-7-30 23:50

很实用的教程,谢谢马老师细致入微的讲解{:4_180:}

马黑黑 发表于 2026-7-31 07:57

杨帆 发表于 2026-7-30 23:50
很实用的教程,谢谢马老师细致入微的讲解

这是一个简化的演示,下一个演示会复杂一些,正在准备

马黑黑 发表于 2026-7-31 07:58

宕.. 发表于 2026-7-30 22:31
每次都一如既往一本正经的从头看完,然后郑重其事煞有介事的一点不通,最后知道我看过就好啊,嘿嘿{:5_106: ...

这些东东有些复杂,如果此前没有多少 CSS、HTML、JS 基础,理解起来可能有难度

马黑黑 发表于 2026-7-31 07:59

红影 发表于 2026-7-30 22:25
嗯嗯,参数越多越难

问题还在于:浏览器对 ray() 的支持会音内核、版本而有所不同

杨帆 发表于 2026-7-31 11:05

马黑黑 发表于 2026-7-31 07:57
这是一个简化的演示,下一个演示会复杂一些,正在准备

期待中,马老师您辛苦了{:4_180:}

马黑黑 发表于 2026-7-31 13:07

杨帆 发表于 2026-7-31 11:05
期待中,马老师您辛苦了

等有空做下文字组织工作就可以了

杨帆 发表于 2026-7-31 14:24

本帖最后由 杨帆 于 2026-7-31 17:07 编辑

马黑黑 发表于 2026-7-31 13:07
等有空做下文字组织工作就可以了
厉害~忙里偷闲,佳作频出,福泽大众{:4_190:}

宕.. 发表于 2026-7-31 17:29

马黑黑 发表于 2026-7-31 07:58
这些东东有些复杂,如果此前没有多少 CSS、HTML、JS 基础,理解起来可能有难度

嗯呢,一点基础没有,看你们说文科理科
于我,文科眼里我偏理科,理科眼里我又偏文科
哪一科都半吊子,这咋算哩{:5_106:}

红影 发表于 2026-7-31 20:34

马黑黑 发表于 2026-7-31 07:59
问题还在于:浏览器对 ray() 的支持会音内核、版本而有所不同

嗯嗯,那就更难了。

马黑黑 发表于 2026-7-31 22:19

红影 发表于 2026-7-31 20:34
嗯嗯,那就更难了。

特别是 contain 参数,目前来讲,设计预期与实现效果还有差异

马黑黑 发表于 2026-7-31 22:20

宕.. 发表于 2026-7-31 17:29
嗯呢,一点基础没有,看你们说文科理科
于我,文科眼里我偏理科,理科眼里我又偏文科
哪一科都半吊子, ...

这叫双科生,地地道道的

马黑黑 发表于 2026-7-31 22:21

杨帆 发表于 2026-7-31 14:24
厉害~忙里偷闲,佳作频出,福泽大众

没那么高大上,就是玩玩

宕.. 发表于 2026-7-31 22:23

马黑黑 发表于 2026-7-31 22:20
这叫双科生,地地道道的

哈哈,今天开心的事儿就你这句话带来的,这肯定句美妙的无与伦比{:4_196:}

马黑黑 发表于 2026-7-31 23:21

宕.. 发表于 2026-7-31 22:23
哈哈,今天开心的事儿就你这句话带来的,这肯定句美妙的无与伦比

{:4_190:}

红影 发表于 2026-8-1 08:45

马黑黑 发表于 2026-7-31 22:19
特别是 contain 参数,目前来讲,设计预期与实现效果还有差异

那样会很难有统一的效果啊,学习的人也会迷惑。
页: [1] 2
查看完整版本: offset-path ray 函数演示(一)