马黑黑 发表于 2023-6-22 07:02

用 clip-path: polygon() 绘制星形线

<style>
.papa {
        width: 200px;
        height: 200px;
        border: 1px solid orange;
        position: relative;
}
#mydiv {
        width: 100%;
        height: 100%;
        background: orange;
        position: absolute;
}
#msgBox { display: none; }
</style>

<div class="papa">
        <div id="mydiv"></div>
</div>
<p><br><br><button id="showCode" value="1">查看代码</button><br></p>
<div id="msgBox"></div>

<script>

let toPercent = (num1,num2) => (num2 / num1 * 100).toFixed(2) + '%'; /* 转百分比 */

let mkAstroid = (ww) => {
        let a = ww / 2, arr = [];
        for(let i = 0; i <= 2 * Math.PI; i += Math.PI/20) {
                let x = a * Math.pow(Math.cos(i), 3) + a;
                var y = a * Math.pow(Math.sin(i), 3) + a;
                arr.push(toPercent(a * 2, x) + ' ' + toPercent(a * 2, y));
        }
        return `polygon(${arr.join(', ')})`;
}

msgBox.innerText = mydiv.style.clipPath = mkAstroid(200);

showCode.onclick = () => showCode.innerText === '查看代码' ? (msgBox.style.display = 'block', showCode.innerText = '收起代码') : (msgBox.style.display = 'none', showCode.innerText = '查看代码');

</script>

马黑黑 发表于 2023-6-22 07:04

核心 JS 代码:

let toPercent = (num1,num2) => (num2 / num1 * 100).toFixed(2) + '%'; /* 转百分比 */

let mkAstroid = (ww) => {
/*
        星形线参数方程式:x = a*(cost)^3,y = a*(sint)^3
        其中:a 为原点到曲线与X轴相交的距离,是圆的半径;t 为参数,0≤ t ≤2π
       
        自定义函数参数 ww 为正方形元素宽高尺寸
        for 语句 加 a 是为了将裁剪点移到可视区域;
        循环步进 i += Math.PI/20 除数越大星形边缘越平滑
*/
        let a = ww / 2, arr = [];
        for(let i = 0; i <= 2 * Math.PI; i += Math.PI/20) {
                let x = a * Math.pow(Math.cos(i), 3) + a;
                var y = a * Math.pow(Math.sin(i), 3) + a;
                arr.push(toPercent(a * 2, x) + ' ' + toPercent(a * 2, y));
        }
        return `polygon(${arr.join(', ')})`;
}

马黑黑 发表于 2023-6-22 07:08

本帖最后由 马黑黑 于 2023-6-22 07:50 编辑

函数 mkAstroid(ww) 的调用(假如我们要裁剪 id="mybox" 盒子):

    mybox.style.clipPath = mkAstroid(200);

其中,参数值 200 指 mybox 盒子的宽高尺寸(宽=高=200px)。

马黑黑 发表于 2023-6-22 07:09

星形线的定义之一:

星形线属于内摆线,内摆线顾名思义就是在一个半径为a的动圆A上固定一点p,然后这个动圆A绕着半径为b的定圆B的"内侧"滚动一周,p点所形成的轨迹就是内摆线。

醉美水芙蓉 发表于 2023-6-22 07:19

樵歌 发表于 2023-6-22 07:34

端午快乐,多吃几个甜的{:4_189:}

马黑黑 发表于 2023-6-22 07:49

樵歌 发表于 2023-6-22 07:34
端午快乐,多吃几个甜的

甜粽不好吃

马黑黑 发表于 2023-6-22 07:49

醉美水芙蓉 发表于 2023-6-22 07:19
老师好早呀!端午节安康!

谢谢,同样祝你

红影 发表于 2023-6-22 12:37

这个数学公式实际不知道的,去搜一下,是让一个半径为原半径1/4的圆,沿着圆的圆周旋转得到的轨迹。嗯,挺难理解的。不过图形很漂亮{:4_199:}

红影 发表于 2023-6-22 12:45

循环步进 i += Math.PI/20 除数越大星形边缘越平滑,Math.PI对应180度,也就是整个360方向取了40个点。这个倒是没用上次那个图形取点多呢。

马黑黑 发表于 2023-6-22 12:52

红影 发表于 2023-6-22 12:37
这个数学公式实际不知道的,去搜一下,是让一个半径为原半径1/4的圆,沿着圆的圆周旋转得到的轨迹。嗯,挺 ...

有各种理解。从数学上讲,星形线是内摆线,有自己的参数公式,即——

x = a*(cost)^3,y = a*(sint)^3

然后,按这个公式去实现便可以了。

而更形象、通俗的解释,请查地板的定义。星形线和心形线某种意义上其实正好相反:前者动圆在内,后者动圆在外。

马黑黑 发表于 2023-6-22 12:54

红影 发表于 2023-6-22 12:45
循环步进 i += Math.PI/20 除数越大星形边缘越平滑,Math.PI对应180度,也就是整个360方向取了40个点。这 ...

我已经编写好的桃心形函数也采用这个循环方式,生成的裁剪代码也不是瀑布型的

南无月 发表于 2023-6-22 13:15

这个图形好靓~~很是喜欢。。

南无月 发表于 2023-6-22 13:16

马黑黑 发表于 2023-6-22 12:54
我已经编写好的桃心形函数也采用这个循环方式,生成的裁剪代码也不是瀑布型的

{:4_173:}瀑布占地方。。。看到桃心形了,代码很友好,一把可以抓走

马黑黑 发表于 2023-6-22 15:06

南无月 发表于 2023-6-22 13:16
瀑布占地方。。。看到桃心形了,代码很友好,一把可以抓走

{:4_173:}

马黑黑 发表于 2023-6-22 15:06

南无月 发表于 2023-6-22 13:15
这个图形好靓~~很是喜欢。。

css-doodle很容易做这个

南无月 发表于 2023-6-22 17:32

马黑黑 发表于 2023-6-22 15:06


一般瀑布都是个景点{:4_173:}

南无月 发表于 2023-6-22 17:33

马黑黑 发表于 2023-6-22 15:06
css-doodle很容易做这个

看你做什么都容易{:4_173:}

马黑黑 发表于 2023-6-22 17:42

南无月 发表于 2023-6-22 17:33
看你做什么都容易

也不是这么说

马黑黑 发表于 2023-6-22 17:43

南无月 发表于 2023-6-22 17:32
一般瀑布都是个景点

大约吧
页: [1] 2 3 4
查看完整版本: 用 clip-path: polygon() 绘制星形线