YStudio Y++

画布控件

Y++ / YStudio 开发文档 · 一点滴

工具箱组件 画布(设计器类型名:画布;支持库:画布类)。
用于在窗口内做可交互的 2D 绘图:图形编辑、手绘笔迹、像素涂鸦、HUD 叠层、导出图片等。


1. 三种绘制层(先选对层)

从下到上每帧合成顺序为:

  1. 控件背景(设计器背景色等)
  2. 像素层(可选):整幅位图,适合涂鸦、贴图底图
  3. 场景层:带稳定 图形ID 的矢量/文本/图片节点,可点选、拖动、组合、持久化
  4. 即时层:只在 绘制 事件里临时画一帧,帧末清空,不进场景、不可点选
需求 用哪一层 典型 API
可点选的矩形、连线、图元 场景 添加矩形 / 添加直线 / …
鼠标拖出自由曲线并保留 场景路径 开始路径线到结束路径
十字准星、临时辅助线、帧率文字 即时 仅在 绘制画线 / 画文本
位图涂抹、导入照片当底 像素 锁定像素 / 置像素 / 从字节集载入
保存当前画面给人看 导出 导出PNG / 到字节集
保存可再编辑的工程内容 场景文本 导出场景 / 导入场景

颜色统一用文本:#AARRGGBB#RRGGBB(如 "#FFFF0000" 不透明红,"#4080FF80" 半透明蓝)。


2. 坐标系(极易写错)

画布上有两套坐标,都不是窗口客户区绝对坐标

名称 原点 用途
控件坐标 画布控件左上角 鼠标事件 X/Y取命中框选取/置像素
场景坐标 内容坐标系(已含视图平移与缩放) 添加*置位置、路径点、移动选中

转换(传入的一对坐标是「点」的两个分量):

小数 sx = 画布1.控件到场景X(控件x, 控件y)
小数 sy = 画布1.控件到场景Y(控件x, 控件y)
小数 cx = 画布1.场景到控件X(场景x, 场景y)
小数 cy = 画布1.场景到控件Y(场景x, 场景y)

规则: 鼠标事件里先转场景再写入场景 API;取命中(X, Y) 直接用事件里的控件坐标。

视图:

  • 中键拖:平移(属性「允许平移」)
  • Ctrl+滚轮:缩放(属性「允许缩放」;「最小缩放」「最大缩放」为百分比,如 25 表示 0.25)
  • 代码:置视图(平移X, 平移Y, 缩放) / 复位视图() / 取平移X / 取平移Y / 取视图缩放
  • 视图变化会触发事件 视图改变
  • 选中集合变化会触发事件 选中改变(可用 取选中数 / 取选中列表

3. 编辑模式与默认鼠标行为

画布1.置编辑模式(1)   // 1=选择+拖动(默认);0=关闭内置拖动(更适合纯手绘脚本)

当模式为 1 时(需先点击画布取得焦点):

操作 效果
左键点在图形上 选中;可拖动;单选显示缩放/旋转手柄
Ctrl+点图形 追加或取消该项选中
Shift+拖空白 框选;再按 Ctrl 为追加框选
空白处左键(无 Shift) 不强制选中;脚本可在此手绘
Delete / Backspace 删除选中
方向键 微调 1 场景单位;Ctrl+方向键为 10
Ctrl+C / X / V / D / A 复制 / 剪切 / 粘贴 / 克隆 / 全选

拖动时默认 吸附 其它图形边/中线;可用 置吸附 / 置网格 调整。


4. 场景图形:创建与改属性

所有 添加* 返回 整数图形ID(失败为 0)。之后用 ID 改外观与位姿。

4.1 创建

方法 说明
添加直线(x1,y1,x2,y2) 线段
添加矩形(x,y,宽,高) 轴对齐矩形
添加椭圆(x,y,宽,高) 外接矩形定义的椭圆
添加多边形(点列) 点列文本 "x,y;x,y;…",至少 3 点
添加文本(x,y,内容) 文本图元
添加图片(x,y,宽,高,路径) 本地路径或资源路径;解码失败时显示占位框
开始路径(x,y)线到 / 曲线到 / 关闭路径 / 结束路径() 构造折线/曲线路径
删除(图形ID) / 清空() 删一个 / 清空场景
取数量() / 是否存在(图形ID) / 取图形列表() 查询

多边形示例:

整数 id = 画布1.添加多边形("0,0;100,0;50,80")
画布1.置填充色(id, "#4080FF80")
画布1.置描边色(id, "#FFFFFFFF")
画布1.置线宽(id, 2)

路径手绘(与选择模式共存时:先判断未命中图形再起笔):

逻辑 g_画中 = 假

函数 画布1.鼠标按下(整数 X, 整数 Y, 逻辑 按下) {
    如果 (画布1.取命中(X, Y) > 0) { 返回 }
    小数 sx = 画布1.控件到场景X(X, Y)
    小数 sy = 画布1.控件到场景Y(X, Y)
    整数 id = 画布1.开始路径(sx, sy)
    画布1.置描边色(id, "#FFFFEE88")
    画布1.置线宽(id, 2)
    g_画中 = 真
}

函数 画布1.鼠标移动(整数 X, 整数 Y, 逻辑 按下) {
    如果 (g_画中 && 按下) {
        画布1.线到(画布1.控件到场景X(X, Y), 画布1.控件到场景Y(X, Y))
    }
}

函数 画布1.鼠标抬起(整数 X, 整数 Y, 逻辑 按下) {
    如果 (g_画中) {
        画布1.结束路径()
        g_画中 = 假
    }
}

4.2 外观与变换

方法 说明
置填充色 / 置描边色 / 置线宽 填充、描边
取填充色 / 取描边色 / 取线宽 读取外观
置位置(图形ID, x, y) 场景坐标位置
取位置X / 取位置Y 读取场景位置
置尺寸 / 置旋转 / 置缩放 尺寸、角度(度)、缩放
取宽度 / 取高度 / 取旋转 / 取缩放X / 取缩放Y 读取尺寸与变换
置可见 / 置锁定 不可见 / 锁定后不参与命中与编辑
取可见 / 取锁定 读取状态
置Z序 / 取Z序 数值越大越靠上
置标签 / 取标签 自定义字符串,便于业务标记

5. 选中、组合、对齐、剪贴板、层级

画布1.选中(id)           // 单选
画布1.选中(id2, 真)      // 追加
画布1.清空选中()
画布1.全选()
画布1.反选()
整数 n = 画布1.框选(0, 0, 200, 150)   // 控件坐标矩形,返回新选中数量

画布1.移动选中(10, 0)    // 场景位移;可吸附
整数 g = 画布1.组合()    // ≥2 个选中;返回组 ID
画布1.取消组合()         // 或 取消组合(组ID)
整数 p = 画布1.取父级(id)
逻辑 是组 = 画布1.是否组合(g)

画布1.对齐左()
画布1.水平居中()
画布1.水平分布()         // 至少 3 个
画布1.水平翻转()
画布1.垂直翻转()

画布1.复制选中()
画布1.粘贴()
画布1.克隆选中()
画布1.剪切选中()
画布1.删除选中()

画布1.置顶()
画布1.置底()
画布1.上移一层()
画布1.下移一层()

吸附:

画布1.置吸附(真)
画布1.置吸附容差(8)      // 屏幕像素容差
画布1.置网格(10)         // 场景单位;0=关网格

读选区:是否选中 / 取选中数 / 取选中(索引) / 取选中列表()


6. 即时层(仅 绘制 事件)

函数 画布1.绘制() {
    画布1.置笔触("#FFFFCC00", 1)
    画布1.画线(0, 0, 50, 50)
    画布1.置填充("#40FFFFFF")
    画布1.画矩形(10, 10, 40, 30)
    画布1.画椭圆(60, 10, 40, 30)
    画布1.画文本(5, 5, "提示")
}

坐标为 场景坐标。勿在其它事件里调用 画线 等即时 API(无效或不符合预期)。


7. 像素层与导出画面

画布1.锁定像素()
画布1.置像素(10, 10, "#FFFF0000")
文本 c = 画布1.取像素(10, 10)
画布1.解锁像素()

逻辑 ok = 画布1.导出PNG(取临时目录() + "画布.png")
字节集 png = 画布1.到字节集()
画布1.从字节集载入(png)   // 用图片字节替换像素缓冲尺寸
画布1.清空像素()
方法 说明
锁定像素 / 解锁像素 确保缓冲存在并刷新显示
取像素宽 / 取像素高 未锁定时为 0
取像素 / 置像素 控件坐标;颜色 #AARRGGBB
导出PNG / 到字节集 导出当前视图下控件矩形内容(含像素+场景+一帧即时)
从字节集载入 图片字节 → 像素缓冲
清空像素 丢弃像素缓冲

8. 场景持久化

文本 s = 画布1.导出场景()
到文件(取临时目录() + "scene.txt", s)      // 按你项目里的文件 API 书写

文本 s2 = 到文本(读入文件(...))            // 读回文本
整数 n = 画布1.导入场景(s2, 真)            // 真=先清空再导入;返回导入项数

导出场景 得到以 YCANVAS|1 开头的文本,含图形种类、位置、样式、组合关系、多边形点与路径点等,可供再次 导入场景 恢复可编辑内容。
若只要给人看的截图,用 导出PNG,不要用场景文本。


9. 事件

事件 参数 何时
绘制 每帧;写即时层
图形单击 整数 图形ID 点中场景图形
图形双击 整数 图形ID 双击图形
视图改变 平移/缩放变化后
选中改变 场景选中集合变化;可用 取选中数 / 取选中列表
鼠标按下 / 鼠标移动 / 鼠标抬起 整数 X, 整数 Y, 逻辑 按下 控件坐标;手绘等
函数 画布1.选中改变() {
    输出("选中数=", 画布1.取选中数())
}

函数 画布1.图形单击(整数 图形ID) {
    输出("点中", 图形ID)
}

10. 设计器属性(画布专用)

面板标题 含义 语言读写
抗锯齿 绘制是否抗锯齿 画布1.抗锯齿
允许平移 是否允许中键拖视图 画布1.允许平移
允许缩放 是否允许 Ctrl+滚轮缩放 画布1.允许缩放
最小缩放 / 最大缩放 缩放范围(百分比整数,25=0.25 倍) 画布1.最小缩放 / 最大缩放

另有通用:背景色、边框、布局锚定等(语言侧亦可读写 背景色 / 显示边框 / 边框大小 / 边框颜色)。


11. 按需求对照写法(速查)

用户需求 建议写法
流程图/框图可拖可组合 场景 添加矩形+添加直线;模式 1;组合/对齐*
签字板/随手画 模式 1 + 空白处路径手绘;或模式 0 专心手绘
游戏 HUD / 准星 绘制 里即时绘制
像素画板 锁定像素+置像素;可再叠场景
打开图片当底图 从字节集载入添加图片
保存作品给人看 导出PNG
保存工程可再编辑 导出场景 / 导入场景
多选批量移动 框选 或 Ctrl 点选后 移动选中
对齐一排按钮图元 多选后 对齐顶+水平分布
读图元当前样式/位姿 取填充色 / 取位置X / 取旋转

12. 完整方法一览(画布类)

场景结构: 清空 添加直线 添加矩形 添加椭圆 添加多边形 添加文本 添加图片 开始路径 线到 曲线到 关闭路径 结束路径 删除 取数量 是否存在 取图形列表

外观变换: 置填充色 置描边色 置线宽 置位置 置尺寸 置旋转 置缩放 置可见 置锁定 置Z序 置标签
取填充色 取描边色 取线宽 取位置X 取位置Y 取宽度 取高度 取旋转 取缩放X 取缩放Y 取可见 取锁定 取Z序 取标签

坐标视图: 取命中 控件到场景X/Y 场景到控件X/Y 置视图 复位视图 取平移X 取平移Y 取视图缩放

即时: 置笔触 置填充 画线 画矩形 画椭圆 画文本

像素导出: 锁定像素 解锁像素 清空像素 取像素宽/高 取/置像素 导出PNG 到字节集 从字节集载入

选区编辑: 选中 取消选中 清空选中 是否选中 取选中数 取选中 取选中列表 置/取编辑模式 组合 取消组合 取父级 是否组合 移动选中 全选 反选 框选 水平/垂直翻转

吸附对齐: 置/取吸附 置/取吸附容差 置/取网格 对齐左/右/顶/底 水平/垂直居中 水平/垂直分布

剪贴板层级: 删除选中 克隆选中 复制选中 剪切选中 粘贴 置顶 置底 上移一层 下移一层

场景文本: 导出场景 导入场景