马黑黑 发表于 2025-9-25 13:08

svgdr绘制的简单伞面

本帖最后由 马黑黑 于 2025-9-25 13:21 编辑 <br /><br /><div class="codebox" data-prev="1">
&lt;svg id="msvg" width="600" height="600" viewBox="0 0 400 400"&gt;&lt;/svg&gt;

&lt;script type="module"&gt;
        import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.mod.js?v=1.0';
        var dr = Dr.dr(msvg);

        var points = dr.circlePoints(9, 200, 190); // 获取9个顶点坐标值
        var path = 'M200 200'; // 路径起点 : 绘图区域中心
        // 遍历顶点坐标数组 : 用 L 和 A 指令拼接路径
        points.forEach((p,k) =&gt; {
                var next = points[(k+1) % points.length];
                path += ` L${p} ${p} A180 180 0 0 0 ${next} ${next} L200 200`;
        });
        dr.path(path, 'none', 'darkred', 2); // 绘制
&lt;/script&gt;
</div>

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

马黑黑 发表于 2025-9-25 13:22

获取的点适当多几个形状才接近伞面,最好取奇数。

梦江南 发表于 2025-9-25 13:55

看过了预览,伞面很好看。黑黑老师辛苦了!{:4_190:}

红影 发表于 2025-9-25 14:59

完了,第一句 获取9个顶点坐标值就没看懂,我把dr.circlePoints和dr.circle()弄混了。
路径起点还能和后面路径分开写,这做法也不熟。
知道这绘制很奇妙,依次一个个点连下去就好,可开始没看懂,也就迷迷糊糊了{:4_173:}

红影 发表于 2025-9-25 15:08

想起来了,是那个新指令没学好。svgdr新指令:circlePoints
https://www.huachaowang.com/forum.php?mod=viewthread&tid=86179&fromuid=2
(出处: 花潮论坛)

dr.circlePoints(points, R, r);这里的R, r开始学的时候就没怎么弄明白,“R 是计算顶点的范围依据,具体说来就是,圆心坐标通过 R 来确定,这里(R,R)=(200,200),所有顶点均围绕着它在半径为 r 的外切圆的圆周上均匀分布。” 所以这里的9个顶点圆心在200,200,半径是190吧,跑回去看那个帖子,才整明白了{:4_173:}

马黑黑 发表于 2025-9-25 19:43

红影 发表于 2025-9-25 15:08
想起来了,是那个新指令没学好。svgdr新指令:circlePoints
https://www.huachaowang.com/forum.php?mod=v ...

如果不习惯 circlePoints 指令,可以自己编写一个函数或流程来获取 9 个点的坐标值。

马黑黑 发表于 2025-9-25 19:44

红影 发表于 2025-9-25 14:59
完了,第一句 获取9个顶点坐标值就没看懂,我把dr.circlePoints和dr.circle()弄混了。
路径起点还能和后面 ...

这个正常,毕竟,svgdr 是个小众模块,里面设计的很多指令,不会被熟悉。

马黑黑 发表于 2025-9-25 19:44

梦江南 发表于 2025-9-25 13:55
看过了预览,伞面很好看。黑黑老师辛苦了!

{:4_180:}

花飞飞 发表于 2025-9-25 20:11

马黑黑 发表于 2025-9-25 13:22
获取的点适当多几个形状才接近伞面,最好取奇数。

path += ` L${p} ${p} A180 180 0 0 0 ${next} ${next} L200 200`;
看到这一句的设计可以封神了。。。
从中心点200.2000画直线到一个点,画弧线到下一个点,然后再画直线回到中心点。。
循环往复然后画完为止。。
简直是代码界的美容精华液{:4_170:}

花飞飞 发表于 2025-9-25 20:13

这个小伞真漂亮,记得很久之前有个用彩虹小伞当小播的。。。
想来画法应该是天差地别吧。。{:4_173:}

马黑黑 发表于 2025-9-25 20:49

花飞飞 发表于 2025-9-25 20:13
这个小伞真漂亮,记得很久之前有个用彩虹小伞当小播的。。。
想来画法应该是天差地别吧。。

其实也差不多

马黑黑 发表于 2025-9-25 20:50

花飞飞 发表于 2025-9-25 20:11
path += ` L${p} ${p} A180 180 0 0 0 ${next} ${next} L200 200`;
看到这一句的设计可以封 ...

这是一个画的流程

红影 发表于 2025-9-25 23:20

马黑黑 发表于 2025-9-25 19:43
如果不习惯 circlePoints 指令,可以自己编写一个函数或流程来获取 9 个点的坐标值。

嗯嗯,开始没反应过来,后来想起来,黑黑讲解过的{:4_187:}

红影 发表于 2025-9-25 23:22

马黑黑 发表于 2025-9-25 19:44
这个正常,毕竟,svgdr 是个小众模块,里面设计的很多指令,不会被熟悉。

是黑黑辛辛苦苦设计的的呢,极大地方便了绘制{:4_187:}

马黑黑 发表于 2025-9-26 11:53

红影 发表于 2025-9-25 23:22
是黑黑辛辛苦苦设计的的呢,极大地方便了绘制

这个不辛苦,这是自己为自己做个工具

马黑黑 发表于 2025-9-26 11:58

红影 发表于 2025-9-25 23:20
嗯嗯,开始没反应过来,后来想起来,黑黑讲解过的

这个指令在源码中其实非常简洁:

circlePoints : function(points,R,r,offsetAngle=0) {
        const a = 360 / points;
        const cx = R + this.svg.viewBox.baseVal.x;
        let resAr = [];
        for (let i = 0; i <points; i++) {
                const x = (cx + r * Math.cos(Math.PI / 180 * (a * i - offsetAngle))).toFixed(2);
                const y = (cx + r * Math.sin(Math.PI / 180 * (a * i - offsetAngle))).toFixed(2);
                resAr.push();
        }
        return resAr;
},

它还考虑到了 viewBox 属性,获取 viewBox 的 x 值、令其参与到 R 的实际数值,酱紫,不会因为有了非 0 0 开头的 viewBox 设置而令所计算的顶点所向的圆心偏离 R 所预设的圆心。

红影 发表于 2025-9-26 21:03

马黑黑 发表于 2025-9-26 11:53
这个不辛苦,这是自己为自己做个工具

厉害,想做个工具就能做出来{:4_199:}

红影 发表于 2025-9-26 21:07

马黑黑 发表于 2025-9-26 11:58
这个指令在源码中其实非常简洁:

circlePoints : function(points,R,r,offsetAngle=0) {


谢谢黑黑的讲解。其实会想起这个以后,还是能理解了,不像开始一点摸不着头绪{:4_173:}

马黑黑 发表于 2025-9-26 21:08

红影 发表于 2025-9-26 21:03
厉害,想做个工具就能做出来

嗯嗯,做个锤子

马黑黑 发表于 2025-9-26 21:09

红影 发表于 2025-9-26 21:07
谢谢黑黑的讲解。其实会想起这个以后,还是能理解了,不像开始一点摸不着头绪

这个是生成顶点坐标的高效方法
页: [1] 2
查看完整版本: svgdr绘制的简单伞面