用 godking.paint 画圆盘菜单

光庆 26天前 547

写了个简单的例程,请自行修改完善。

代码并不多,要点如下:

1、数学运算:角度、距离的计算

2、gdip绘图:绘制图形、文字。


import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=527;bottom=527;bgcolor=0x273610;)
winform.add(
plus={cls="plus";left=12;top=12;right=512;bottom=512;notify=1;z=1}
)
/*}}*/
winform.show();
import godking.paint
import inet.http
//下载图标
var img = inet.http.get("https://aardio.online/upload/files/20250201/1738418676.png")
var imgs = godking.paint.splitImage(img,5/*列数*/,5/*行数*/,/*小图左*/,/*上*/,/*右*/,/*下*/,/*原图左*/,/*上*/,/*右*/,/*下*/);
//创建paint对象
var p = godking.paint(500 /*宽度*/,500/*高度*/,0xFF103627/*背景颜色*/,/*背景图像*/)
p.plus.bind(winform.plus,false/*自动刷新*/,false/*重绘背景*/)
//创建绘制函数
var mouseceng,mousejiao,color=0,0,0;
var drawall = function(x,y){
	p.clear();
	var r = {150,250};
	var a = {8,16};
	var len = math.sqrt((x-250)**2+(y-250)**2);
	mouseceng,mousejiao=0,0;
	for(ceng=#r;1;-1){
		var angle = 360/a[ceng];
		for(jiao=1;a[ceng];1){
			var p1,p2 = 250-r[ceng],r[ceng]*2;
			var path = p.path(1/*0:交叉填充 1:全填充*/);
			path.addPie(p1,p1,p2,p2,angle*(jiao+0.5),angle);
			if (p.isInPath(x,y,path)?(len>r[ceng]-100)?(len<r[ceng])) {
				mouseceng,mousejiao,color = ceng,jiao,0xFFD8D8D8;
			} else {
				color = (jiao%2)?0xFFF5F5F5:0xFFF8F8FF;
			}
			p.fillPath(path /*路径*/,color/*填充颜色或brush对象*/);
			p.drawPath(path /*路径*/,0xFFBBBBBB/*线条颜色或pen对象*/,/*线宽*/,/*线型*/);
			path.delete();
			var x = 250 + (r[ceng]-50)*(math.cos((angle*(jiao+1))*math.pi/180));
			var y = 250 + (r[ceng]-50)*(math.sin((angle*(jiao+1))*math.pi/180));
			p.drawImageCenter( x/*x*/,y-10/*y*/,20/*宽*/,20/*高*/,imgs[jiao]/*图片*/,/*透明度或图片属性*/,true/*保持比例*/)
			p.drawText(x-50,y,x+50,y+30,"项目"++ceng++"-"++jiao,::LOGFONT(name="宋体";h=14;color=0xFF000000;brush=null),0/*格式*/,1/*水平*/,1/*垂直*/,false/*截短*/)
		}
	}
	p.fillEllipseF( 200/*x*/,200/*y*/,100/*宽度*/,100/*高度*/,0xFFF8F8FF);
	p.drawEllipseF( 200/*x*/,200/*y*/,100/*宽度*/,100/*高度*/,0xFF000000,/*线宽*/,/*线型*/);
	p.drawImageCenter( 250/*x*/,250/*y*/,50/*宽度*/,50/*高度*/,imgs[24]/*图片*/,/*透明度或图片属性*/,true/*保持比例*/);
	if len<250 p.drawLine(250,250,x,y,0xFFFF0000,2/*线宽*/,1/*线型*/);
	p.plus.update( /*刷新区域RECT*/);
}
//调用绘制函数
winform.plus.onMouseMove = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	drawall(x,y);//此处可扩展完善:判断鼠标所在区块变化了以后,再刷新。
}
//定义点击事件
winform.plus.onMouseClick = function(wParam,lParam){
    if mouseceng and mousejiao {
    	..win.msgbox(string.format("您点击的是:项目%d-%d",mouseceng,mousejiao ))
    }
}
//初始化一次
drawall(250,250);
win.loopMessage();


最新回复 (7)
  • ccbwx 26天前
    0 2
    有需求,必庆帝
  • lcj21 26天前
    0 3
    大佬就是大佬,代码精练高效,太厉害了
  • xiaobai 26天前
    0 4
    太强了
  • popde 25天前
    0 5
    牛, 很简洁
  • JRJJ 14天前
    1 6

    想把轮盘改小,研究后代码如下,供参考:

        修改说明:
        1. 将数值改为由 maxr、minr指定最大圈、最内圈半径
        2. 改为从12点钟按顺时针方向
    import win.ui;
    /*DSG{{*/
    var winform = win.form(text="aardio form";right=527;bottom=527;bgcolor=15793151)
    winform.add(
    plus={cls="plus";left=12;top=12;right=512;bottom=512;notify=1;z=1}
    )
    /*}}*/
    
    /**
    光庆大佬的轮盘示例
        修改说明:
        1. 将数值改为由 maxr、minr指定最大圈、最内圈半径
        2. 改为从12点钟按顺时针方向
    **/
    winform.show();
    import godking.paint
    
    //最大圆圈半径
    var maxr = 250
    //最内圈空白圆圈半径
    var minr = 50
    var a = {8, 16}     // 两层轮盘的扇区数量
    
    // 创建paint对象
    var p = godking.paint(
        2*maxr,            // 画布宽度
        2*maxr,            // 画布高度
        0xFF103627,     // 背景颜色(深绿色)
        null            // 背景图像(无)
    )
    p.plus.bind(winform.plus, false, false) // 绑定到plus控件,不自动刷新,不重绘背景
    // 定义变量
    var mouseceng = 0    // 当前鼠标所在的层(1或2)
    var mousejiao = 0    // 当前鼠标所在的扇区编号
    var color = 0        // 当前绘制颜色
    
    // 主绘制函数
    var drawall = function(x, y){
        p.clear();  // 清空画布
        
        // 定义轮盘参数
        var r = {(maxr-minr)/2+minr, maxr}  // 两层轮盘的半径(缩小了原半径) 
        // 计算鼠标到中心点的距离
        var centerX, centerY = maxr,maxr  // 中心点坐标
        var len = math.sqrt((x-centerX)**2 + (y-centerY)**2)
        
        mouseceng, mousejiao = 0, 0  // 重置鼠标所在区域
        
        // 从外到内绘制轮盘层(先画外层,再画内层)
        for(ceng = #r; 1; -1){
            var angle = 360 / a[ceng]  // 每个扇区的角度
            
            // 绘制当前层的所有扇区
            for(jiao = 1; a[ceng]; 1){
                // 创建扇区路径
                var path = p.path(1)  // 1表示全填充
                var p1, p2 = centerX-r[ceng], r[ceng]*2  // 计算扇区边界
                
                // 修改点1:调整起始角度为12点钟方向
                var startAngle = -90  // 12点钟方向为-90度(数学坐标系)
                //原逻辑
                //path.addPie(p1, p1, p2, p2, angle*(jiao+0.5), angle)
                path.addPie(p1, p1, p2, p2, startAngle+angle*(jiao-1), angle)
                
                // 判断鼠标是否在当前扇区内
                if (p.isInPath(x, y, path) ? (len > r[ceng]-2*minr) ? (len < r[ceng])) {
                    mouseceng, mousejiao, color = ceng, jiao, 0xFFD8D8D8  // 高亮显示
                } else {
                    color = (jiao%2) ? 0xFFF5F5F5 : 0xFFF8F8FF  // 交替颜色
                }
                
                // 填充扇区
                p.fillPath(path, color)
                p.drawPath(path, 0xFFBBBBBB)  // 绘制扇区边框
                
                path.delete()  // 释放路径资源
                
                // 计算文字位置(在扇区中间偏外位置)
                //原逻辑
                //var textAngle = angle*(jiao+1)
                var textAngle = startAngle + angle*(jiao-0.5)
                var textX = centerX + (r[ceng]-minr) * math.cos(textAngle * math.pi/180)
                var textY = centerY + (r[ceng]-minr) * math.sin(textAngle * math.pi/180)
                
                // 绘制扇区文字
                p.drawText(
                    textX-minr, textY-15,  // 文字区域左上角
                    textX+minr, textY+15,   // 文字区域右下角
                    ""++ceng++"-"++jiao,  // 文字内容
                    ::LOGFONT(name="宋体"; h=12; color=0xFF000000),  // 字体设置
                    0, 1, 1, false  // 格式、水平居中、垂直居中、不截短
                )
            }
        }
        
        // 绘制中心圆
        p.fillEllipseF(centerX - minr, centerY-minr, 2*minr, 2*minr, 0xFFF8F8FF)
        p.drawEllipseF(centerX - minr, centerY-minr, 2*minr, 2*minr, 0xFF000000)
        
        // 如果鼠标在轮盘内,绘制从中心到鼠标的红线
        if len < 2*r[#r] {
            p.drawLine(centerX, centerY, x, y, 0xFFFF0000, 2, 1)
        }
        
        p.plus.update()  // 更新显示
    }
    
    // 鼠标移动事件
    winform.plus.onMouseMove = function(wParam, lParam){
        var x, y = win.getMessagePos(lParam)
        drawall(x, y)
    }
    
    // 鼠标点击事件
    winform.plus.onMouseClick = function(wParam, lParam){
        if mouseceng and mousejiao {
            win.msgbox(string.format("您点击的是:项目%d-%d", mouseceng, mousejiao))
        }
    }
    
    // 初始绘制(中心位置)
    drawall(maxr, maxr)
    win.loopMessage()


  • lcj21 14天前
    0 7
    JRJJ 想把轮盘改小,研究后代码如下,供参考:&nbsp;&nbsp;&nbsp;&nbsp;修改说明: &nbsp;&nbsp;&nbsp;& ...
    不错,效果挺好
  • 光庆 14天前
    1 8
    JRJJ 想把轮盘改小,研究后代码如下,供参考:&nbsp;&nbsp;&nbsp;&nbsp;修改说明: &nbsp;&nbsp;&nbsp;&amp ...

    很好,注释挺详细,建议重新发布一个帖子,好例程不要被埋没了 

返回