马黑黑 发表于 2025-8-29 12:30

我切(动态生成svg星形切图路径)

本帖最后由 马黑黑 于 2025-8-29 12:42 编辑 <br /><br /><div class="codebox" data-prev="1">
&lt;img id="girl" width="400" height="400" src="https://638183.freep.cn/638183/small/2025/g0.webp" alt="" /&gt;

&lt;script type="module"&gt;
        var path = createStartPath(8, 200, 160);
        girl.style.setProperty('clip-path',`path('${path}')`);

        // 创建星形函数,参数:
        // lines 边的总数
        // r1 外圆半径(确定顶角,取值依据为正方形边长)
        // r2 内圆半径(确定控制点,取值依据为曲线曲率期望值)
        // 注意 :r1 &gt; r2 是设计初衷
        function createStartPath(lines, r1, r2=0) {
                var a = 360 / lines, path = 'M', bx1, by1, bx2, by2;
                Array.from({length: lines}).forEach((_,k) =&gt; {
                        var a1 = a * k,
                                a2 = a1 - a / 2,
                                x1 = (r1 + r1 * Math.cos(Math.PI / 180 * a1)).toFixed(2),
                                y1 = (r1 + r1 * Math.sin(Math.PI / 180 * a1)).toFixed(2),
                                x2 = (r1 + r2 * Math.cos(Math.PI / 180 * a2)).toFixed(2),
                                y2 = (r1 +r2 * Math.sin(Math.PI / 180 * a2)).toFixed(2);
                        if (k === 0) {
                                bx1 = x1;
                                by1 = y1;
                                bx2 = x2;
                                by2 = y2;
                                path += `${x1} ${y1} `;
                        } else {
                                path += `Q${x2} ${y2},${x1} ${y1} `;
                        }
                        if (k === lines - 1) path += `Q${bx2} ${by2},${bx1} ${by1}`;
                });
                return path;
        }
&lt;/script&gt;
</div>

<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script>

马黑黑 发表于 2025-8-29 12:36

函数绘制原理:

      依据边数设定,计算出外圆上的顶点,同时计算出内圆上的顶点。外圆上的顶点用于确定切割点,内圆上的顶点用于确定曲线的控制点(为了对称角度减去平均角度值的一半)。

通常,外圆半径应大于内圆半径,这样得到的结果是向内凸进的弧线;函数没有处理内圆半径大于外圆半径的机制,但会灵活使用也可以,这将得到比较特别的切割效果。

杨帆 发表于 2025-8-29 13:32

巧妙的路径,简洁的代码,精美的效果,谢谢马老师精彩分享{:4_190:}

红影 发表于 2025-8-29 14:13

用这个就可以切割出星形图案了,真漂亮{:4_187:}

红影 发表于 2025-8-29 14:20



<img id="girl2" width="400" height="400" src="https://638183.freep.cn/638183/small/2025/g0.webp" alt="" />

<script type="module">
        var path = createStartPath(8, 140, 180);
        girl2.style.setProperty('clip-path',`path('${path}')`);

        // 创建星形函数,参数:
        // lines 边的总数
        // r1 外圆半径(确定顶角,取值依据为正方形边长)
        // r2 内圆半径(确定控制点,取值依据为曲线曲率期望值)
        // 注意 :r1 > r2 是设计初衷
        function createStartPath(lines, r1, r2=0) {
                var a = 360 / lines, path = 'M', bx1, by1, bx2, by2;
                Array.from({length: lines}).forEach((_,k) => {
                        var a1 = a * k,
                                a2 = a1 - a / 2,
                                x1 = (r2 + r1 * Math.cos(Math.PI / 180 * a1)).toFixed(2),
                                y1 = (r2 + r1 * Math.sin(Math.PI / 180 * a1)).toFixed(2),
                                x2 = (r2 + r2 * Math.cos(Math.PI / 180 * a2)).toFixed(2),
                                y2 = (r2 +r2 * Math.sin(Math.PI / 180 * a2)).toFixed(2);
                        if (k === 0) {
                                bx1 = x1;
                                by1 = y1;
                                bx2 = x2;
                                by2 = y2;
                                path += `${x1} ${y1} `;
                        } else {
                                path += `Q${x2} ${y2},${x1} ${y1} `;
                        }
                        if (k === lines - 1) path += `Q${bx2} ${by2},${bx1} ${by1}`;
                });
                return path;
        }
</script>

红影 发表于 2025-8-29 14:21

r2 > r1 的也挺好{:4_173:}

马黑黑 发表于 2025-8-29 19:44

红影 发表于 2025-8-29 14:21
r2 > r1 的也挺好

只能试试,毕竟不专门作处理

马黑黑 发表于 2025-8-29 19:44

红影 发表于 2025-8-29 14:20
var path = createStartPath(8, 140, 180);
        girl2.style.setProperty('clip-path',`path('${p ...

这是划线外凸的效果

花飞飞 发表于 2025-8-29 19:44

马黑黑 发表于 2025-8-29 12:36
函数绘制原理:

      依据边数设定,计算出外圆上的顶点,同时计算出内圆上的顶点。外圆上的顶点用于 ...

切出这么漂亮的多边弧形状。。。跟古典的窗框一样。。{:4_199:}

马黑黑 发表于 2025-8-29 19:45

红影 发表于 2025-8-29 14:13
用这个就可以切割出星形图案了,真漂亮

就一个小函数,也许可以做些改动,还能做出更多的效果

马黑黑 发表于 2025-8-29 19:45

杨帆 发表于 2025-8-29 13:32
巧妙的路径,简洁的代码,精美的效果,谢谢马老师精彩分享

希望能看懂函数的每一句

马黑黑 发表于 2025-8-29 19:46

花飞飞 发表于 2025-8-29 19:44
切出这么漂亮的多边弧形状。。。跟古典的窗框一样。。

好看吧

花飞飞 发表于 2025-8-29 19:55

<img id="girl" width="400" height="400" src="https://642303.freep.cn/642303/za/38477af75a9245ae9a27fb2a3fb33efa_tplv-obj_500_500.gif" alt="" />

<script type="module">
        var path = createStartPath(16, 200, 80);
        girl.style.setProperty('clip-path',`path('${path}')`);

        // 创建星形函数,参数:
        // lines 边的总数
        // r1 外圆半径(确定顶角,取值依据为正方形边长)
        // r2 内圆半径(确定控制点,取值依据为曲线曲率期望值)
        // 注意 :r1 > r2 是设计初衷
        function createStartPath(lines, r1, r2=0) {
                var a = 360 / lines, path = 'M', bx1, by1, bx2, by2;
                Array.from({length: lines}).forEach((_,k) => {
                        var a1 = a * k,
                                a2 = a1 - a / 2,
                                x2 = (r1 + r1 * Math.cos(Math.PI / 180 * a1)).toFixed(2),
                                y2 = (r1 + r1 * Math.sin(Math.PI / 180 * a1)).toFixed(2),
                                x1 = (r1 + r2 * Math.cos(Math.PI / 180 * a2)).toFixed(2),
                                y1 = (r1 +r2 * Math.sin(Math.PI / 180 * a2)).toFixed(2);
                        if (k === 0) {
                                bx1 = x1;
                                by1 = y1;
                                bx2 = x2;
                                by2 = y2;
                                path += `${x1} ${y1} `;
                        } else {
                                path += `Q${x2} ${y2},${x1} ${y1} `;
                        }
                        if (k === lines - 1) path += `Q${bx2} ${by2},${bx1} ${by1}`;
                });
                return path;
        }
</script>

花飞飞 发表于 2025-8-29 19:57

马黑黑 发表于 2025-8-29 19:46
好看吧
白老师出品必是精品,好看。。{:4_173:}

马黑黑 发表于 2025-8-29 19:58

花飞飞 发表于 2025-8-29 19:57
白老师出品必是精品,好看。。

{:4_173:}

马黑黑 发表于 2025-8-29 19:58

花飞飞 发表于 2025-8-29 19:55
var path = createStartPath(16, 200, 80);
        girl.style.setProperty('clip-path',`path('${path}' ...

矮油,介么黑

杨帆 发表于 2025-8-29 20:03

马黑黑 发表于 2025-8-29 19:45
希望能看懂函数的每一句

好的,谢谢老师~目前还只能看个大概{:4_173:}

花飞飞 发表于 2025-8-29 20:20

马黑黑 发表于 2025-8-29 19:58


你真会设计切的公式,怎么用都好用,还是万能的。

花飞飞 发表于 2025-8-29 20:21

马黑黑 发表于 2025-8-29 19:58
矮油,介么黑

黑的神秘

马黑黑 发表于 2025-8-29 20:21

花飞飞 发表于 2025-8-29 20:21
黑的神秘

{:4_205:}
页: [1] 2 3 4 5 6 7
查看完整版本: 我切(动态生成svg星形切图路径)