25、Poco绘图与Piu用户界面框架开发指南

Poco绘图与Piu用户界面框架开发指南

1. 额外绘图技术

Poco和Commodetto提供了许多工具,可针对特定需求简化和优化绘图。下面介绍三种技术:使用裁剪将文本限制在一个框内、使用原点轻松重用绘图代码,以及离屏绘制以高效渲染渐变。

2. 将文本限制在框内

Poco在调用 begin 方法时会定义更新区域,不会在该区域外进行绘制,它通过将初始裁剪区域设置为与更新区域相同来实现裁剪。代码也可在绘制过程中调整裁剪区域,但裁剪区域始终受 begin 方法定义的更新区域限制,只能缩小,不能超出初始绘制区域。

裁剪在诸如滚动文本消息(跑马灯效果)的场景中很有用,文本不能绘制在该区域边界外,但要绘制到边缘。以下是具体操作步骤:
1. 定义变量

let frame = 3;
let margin = 2;
let x = 10, y = 60;
let tickerWidth = 200;
let width = tickerWidth + frame * 2 + margin * 2;
let height = regular16.height + frame * 2 + margin * 2;
let text = "JavaScript is one of the world's most widely used programming languages.";
let textWidth = poco.getTextWidth(text, regular16);
let dx = tickerWidth;
  1. 绘制框架和背景
poco.fillRectangle(black, x, y, width, height);
poco.fillRectangle(yellow, x + frame, y + frame, tickerWidth + margin * 2, regular16.height + margin * 2);
  1. 绘制文本
poco.clip(x + frame + margin, y + frame + margin, tickerWidth, regular16.height);
poco.drawText(text, regular16, black, x + frame + margin + dx, y + frame);
poco.clip();
  1. 更新偏移量
dx -= 2;
if (dx < -textWidth)
    dx = tickerWidth;

以下是该过程的mermaid流程图:

graph TD;
    A[定义变量] --> B[绘制框架和背景];
    B --> C[绘制文本];
    C --> D[更新偏移量];
    D --> C;
3. 轻松重用绘图代码

调用Poco的 begin 方法后,绘图原点 (0, 0) 是屏幕左上角。可使用 origin 方法偏移原点,这简化了在屏幕不同位置绘制用户界面元素的函数编写。以下是具体示例:
1. 定义绘图函数

function drawFrame() {
    poco.fillRectangle(black, 0, 0, 20, 20);
    poco.fillRectangle(yellow, 2, 2, 16, 16);
}
  1. 调用绘图函数并偏移原点
drawFrame();
poco.origin(20, 20);
drawFrame();
poco.origin(20, 20);
drawFrame();
poco.origin();
poco.origin();
poco.origin(0, 65);
drawFrame();
poco.origin();

origin 方法会将当前原点存储在栈中,调用无参数的 origin 方法会弹出栈并恢复上一个原点。在调用 end 方法前,必须完全清除原点或裁剪栈,否则会报错。

4. 高效渲染渐变

项目不仅限于构建时创建的位图,还可在运行时创建。可使用 BufferOut 类在运行时创建位图,它会为位图创建一个虚拟屏幕,从而能像在物理屏幕上一样使用Poco绘制离屏位图。以下是具体步骤:
1. 导入类并创建离屏位图

import BufferOut from "commodetto/BufferOut";
let offscreen = new BufferOut({width: 64, height: 64, pixelFormat: poco.pixelsOut.pixelFormat});
let pocoOff = new Poco(offscreen);
  1. 绘制渐变
pocoOff.begin();
for (let i = 64; i >= 1; i--) {
    let gray = (i * 4) - 1;
    let color = pocoOff.makeColor(gray, gray, gray);
    pocoOff.fillRectangle(color, 0, 0, i, i);
}
pocoOff.end();
  1. 将离屏位图绘制到屏幕
poco.drawBitmap(offscreen.bitmap, 0, 0);
  1. 动画显示
let step = 1;
let direction = +1;
Timer.repeat(function() {
    poco.begin(0, 0, 240, 240);
    poco.fillRectangle(white, 0, 0, poco.width, poco.height);
    for (let i = 0; i < 19; i += 1)
        poco.drawBitmap(offscreen.bitmap, i * step, i * 10);
    step += direction;
    if (step > 40) {
        step = 40;
        direction = -1;
    }
    else if (step < 1) {
        step = 0;
        direction = +1;
    }
    poco.end();
}, 33);
5. 触摸输入

若使用Poco绘制产品用户界面并想加入触摸功能,需直接从触摸输入驱动读取数据来实现触摸输入支持。

5.1 访问触摸驱动

常见的电容式触摸输入设备是FocalTech FT6206,用于Moddable One和Moddable Two开发板;较旧的电阻式触摸屏常用XPT2046触摸控制器。以下是导入和实例化的代码:

// 电容式触摸输入
import FT6206 from "ft6206";
let touch = new FT6206;

// 电阻式触摸输入
import XPT2046 from "xpt2046";
let touch = new XPT2046;
5.2 读取触摸输入

调用 read 方法从触摸驱动获取触摸点,需传入触摸点数组,驱动会更新这些点。通常在实例化触摸驱动后一次性分配触摸点数组,以减少内存管理和垃圾回收的工作。以下是具体操作:
1. 分配触摸点数组

touch.points = [{}];
  1. 读取触摸点
touch.read(touch.points);

触摸点的 state 属性值含义如下:
| 状态值 | 含义 |
| ---- | ---- |
| 0 | 无触摸 |
| 1 | 触摸开始(手指按下) |
| 2 | 触摸持续(手指未抬起) |
| 3 | 触摸结束(手指抬起) |

以下是示例代码:

Timer.repeat(function() {
    let points = touch.points;
    let point = points[0];
    touch.read(points);
    switch (point.state) {
        case 0:
            trace("no touch\n");
            break;
        case 1:
            trace(`touch begin @ ${point.x}, ${point.y}\n`);
            break;
        case 2:
            trace(`touch continue @ ${point.x}, ${point.y}\n`);
            break;
        case 3:
            trace(`touch end @ ${point.x}, ${point.y}\n`);
            break;
    }
}, 33);
5.3 使用多点触摸

read 方法接受数组而非单个点是为支持多点触摸。FT6206电容式触摸传感器支持两个同时触摸点(只要距离不太近)。使用多点触摸只需传入包含两个点的数组:

touch.points = [{}, {}];
touch.read(touch.points);
5.4 应用旋转

触摸驱动提供的点未应用硬件或软件旋转,若使用旋转,需对触摸点进行相应转换。以下是旋转90、180和270度的坐标转换代码:

if (90 === rotation) {
    const x = point.x;
    point.x = point.y;
    point.y = screen.height - x;
}
else if (180 === rotation) {
    point.x = screen.width - point.x;
    point.y = screen.height - point.y;
}
else if (270 === rotation) {
    const x = point.x;
    point.x = screen.width - point.y;
    point.y = x;
}

Poco绘图与Piu用户界面框架开发指南

6. Piu用户界面框架概述

Piu是一个面向对象的用户界面框架,它简化了创建复杂用户界面的过程,使用Poco渲染器进行绘制。学习新的用户界面框架可能具有挑战性,每个框架都有自己解决构建用户界面问题的方式和API套件。下面将介绍Piu的一些关键概念和使用方法。

7. 关键概念
7.1 一切皆对象

Piu应用程序中用户界面的每个元素都有对应的JavaScript对象,这些对象是Piu提供的类的实例。与其他开发工具不同,大多数Piu类无需导入,Piu将常用类的构造函数存储在全局变量中,方便在应用程序的任何模块中使用。

每个Piu应用程序都从 Piu Application 类的实例开始。以下是创建 Application 实例的代码:

new Application(null, {
    displayListLength: 8192,
    commandListLength: 4096,
    skin: new Skin({fill: "white"}),
    Behavior: AppBehavior
});

Piu会将 Application 实例存储在全局变量 application 中,可通过该变量访问应用程序实例。应用程序对象是Piu应用的根,可将图形元素(内容对象)添加到其中以显示在屏幕上,也可将其移除。

以下是创建和添加内容对象(标签)的示例:

let sampleLabel = new Label(null, {
    style: textStyle,
    string: "Hello"
});
application.add(sampleLabel);
7.2 每个用户界面元素都是内容对象

Piu应用程序中每个用户界面元素都与一个内容对象相关联,具体来说,是与继承自 Content 类的类的实例相关联,如 Label 类。创建内容对象时,需在JavaScript字典中指定其属性,这些属性可随时更改。

let sampleLabel = new Label(null, {
    style: textStyle,
    string: "Hello"
});
sampleLabel.style = OpenSansBold12;
sampleLabel.string = "Goodbye";
8. 总结

Poco渲染器提供了构建物联网产品用户界面所需的基本工具,可绘制矩形、位图和文本等,还能通过裁剪优化渲染性能。但使用Poco时,需要手动加载资源、计算更新区域和处理旋转等细节。

而Piu用户界面框架则在此基础上进行了扩展,它简化了用户界面的创建过程,通过面向对象的方式管理用户界面元素,让开发者可以更专注于界面的设计和交互逻辑。以下是Poco和Piu的特点对比表格:
| 特性 | Poco | Piu |
| ---- | ---- | ---- |
| 绘图功能 | 提供基本绘图工具 | 基于Poco绘图,简化界面创建 |
| 资源管理 | 需要手动加载和解析资源 | 部分资源管理自动化 |
| 界面元素管理 | 需手动控制绘制和更新 | 通过对象管理界面元素 |
| 旋转处理 | 需要手动处理 | 部分旋转处理自动化 |

以下是Poco和Piu开发流程的mermaid流程图:

graph LR;
    A[开始] --> B{Poco或Piu};
    B --> C1[Poco: 加载资源];
    B --> C2[Piu: 创建应用实例];
    C1 --> D1[Poco: 计算更新区域];
    C2 --> D2[Piu: 创建内容对象];
    D1 --> E1[Poco: 绘制图形元素];
    D2 --> E2[Piu: 添加内容对象到应用];
    E1 --> F1[Poco: 处理旋转等细节];
    E2 --> F2[Piu: 自动管理绘制和更新];
    F1 --> G[结束];
    F2 --> G;

通过合理使用Poco和Piu,开发者可以高效地创建出功能丰富、交互性强的物联网产品用户界面。

源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值