给我一块画布,我可以造一个全新的跨端UI

一、源起
作者是名超大龄程序员,曾涉及了包括Web端、桌面端、移动端等各类前端技术,深受这些前端技术的苦,主要但不限于:
- 每种技术编写代码的语言及技术完全不同,同样呈现形式的组件各端无法通用;
- 大部分前端开发语言跟后端开发语言不同,不能共用一些数据结构;
前端UI的本质是在显示器上呈现由像素点组成的画面,并且响应外部输入事件作出相应的重绘。由于作者对Skia2D绘图引擎比较熟悉,又恰好可以借鉴一下Flutter引擎的跨端实现,所以作者动起了重新造一个跨端UI的念头。 阿基米德说过:“给我一个支点,我可以撬动地球”,那作者要说:"给我一块画布,我可以造一个全新的跨端UI"。
二、画布及画笔:
有了画布才能绘制用户界面,目前画布的来源主要是两类:
- Web端参考Flutter的实现,利用编译为WebAssembly的CanvasKit提供;
- 桌面端及移动端参考Xamarin的实现,利用原生操作系统的视窗结合Skia的SkCanvas提供;
每个窗体的画布分为两层,一层绘制Widget,另一层用于弹出层的绘制及一些组件装饰器的绘制。绘制引擎暂统一由Skia来处理,将来可能会考虑抽象绘制引擎。
三、组件树、布局及样式
Flutter有三棵树,作者嫌啰嗦所以只有一棵WidgetTree,好处是实现简单且方便维持组件实例的状态。每个界面都由组件树结构组成。有些组件为布局类的(eg: Column、Stack等),具备单或多子组件;有些组件为叶子节点(eg: Text、PieChart等),通过设置相应的属性后直接绘制至画布。

四、组件状态
实现组件时如果需要外部状态驱动,可以定义状态变量并绑定至组件的相关属性,这样当状态值发生变更时,绑定的组件根据状态影响进行重新布局或仅重新绘制。
public class DemoCounter : View
{
private readonly State<int> _counter = 0; //定义状态
public DemoCounter()
{
Child = new Column
{
Children = new Widget[]
{
new Text(_counter.AsStateOfString()/*绑定至组件*/),
new Button("+") { OnTap = e => _counter.Value+=1/*改变状态值*/ }
}
};
}
}
五、组件动画
动画实现基本照搬Flutter的实现方式,由AnimationController在指定时间段内驱动各Animation的动画值变化,从而连续改变组件的状态值。
public class DemoAnimation : View
{
private readonly AnimationController _controller;
private readonly Animation<Offset> _offsetAnimation;
public DemoAnimation()
{
_controller = new AnimationController(1000/*动画时长*/);
_offsetAnimation = new OffsetTween(new Offset(-1, 0), new Offset(1, 0))
.Animate(_controller); //位移变换并绑定至动画控制器
Child = new Column
{
Children = new Widget[]
{
new Button("播放动画") { OnTap = e => _controller.Forward() },
new SlideTransition(_offsetAnimation)
{
Child = new Text("动画")
}
}
};
}
}

六、后续
力量有限,在此抛砖引玉希望更多感兴趣的伙伴加入完善,也希望成为跟华为ArkUI类似的国产UI,对了暂时就叫PixUI吧。
给我一块画布,我可以造一个全新的跨端UI的更多相关文章
- RPC基础以及造一个RPC的轮子需要注意些什么
RPC基础以及造一个RPC的轮子需要注意些什么 前言 rpc即远程过程调用,是分布式系统常用的通信方法.远程可以是在一台机器上的不同进程或在不同一个机器上的不同进程.rpc更看重速度,像调用本地方法一 ...
- 【记录】如何造一个vite插件(1)
在看文章前,先做个定位,这不是一篇纯粹的技术性文章,可以把它理解成一个叙述文章,记录我开发插件的过程. 开始前简单的吹个牛 vue2 也写了很多年了,多人合作始终避不开用到别人的组件.关键是有些组件没 ...
- dva的effect那么难用,自己造一个轮子吧
背景 对于dva这个开发框架,国内从事react的前端工程师多半不会感到陌生,dva完善的开发体系和简单的api,让其被广泛运用到实际工作中.我所在的公司也是长期使用dva作为基础的开发框架,虽然好用 ...
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 3 部分: Systemtap
Systemtap的原理,Systemtap与DTrace比较,以及安装要求和安装步骤本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprob ...
- 【转】发布一个基于NGUI编写的UI框架
发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...
- 一个强大的LogParser的UI工具--logparserlizard简介
日志分析,特别是IIS日志,一般人都会想到LogParser工具,的确很强.但是命令行的操作界面令很多非专业的管理人员望而生畏,现在好了,有一个可视化的LogParser的UI工具可以使用了! Log ...
- 一个强大的LogParser的UI工具--logparserlizard简介(开源IIS日志分析工具)
原文地址:http://blog.csdn.net/downmoon/article/details/4509513 日志分析,特别是IIS日志,一般人都会想到LogParser工具,的确很强.但是命 ...
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 2 部分: DTrace
DTrace的原理本系列文章详细地介绍了一个 Linux 下的全新的调式.诊断和性能测量工具 Systemtap 和它所依赖的基础 kprobe 以及促使开发该工具的先驱 DTrace 并给出实际使用 ...
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap,第 1 部分: kprobe
kprobe 的原理.编程接口.局限性和使用注意事项 本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprobe以及促使开发该工具的先驱DTr ...
- 从零讲解搭建一个NIO消息服务端
本文首发于本博客,如需转载,请申明出处. 假设 假设你已经了解并实现过了一些OIO消息服务端,并对异步消息服务端更有兴趣,那么本文或许能带你更好的入门,并了解JDK部分源码的关系流程,正如题目所说,笔 ...
随机推荐
- python_列表和元组的转换
1, 通过list函数将元组的数据获取到,保存到新定义的列表里面.备注:元组的数据不会更改. info_tuple = ("小明", 24, 1.75) info_list = l ...
- js对象中的set和get方法
在js中,每个对象都有set和get方法,也可以自己进行定义,这里先简单说下用法 var person = { _name:'小花', get name() { return this._name + ...
- 构建自动发现的Docker服务架构
------------恢复内容开始------------ 建立consul服务 在建立consul服务中,每个提供服务的节点(在Docker主机上)都要部署和运行consul的client,ser ...
- git 产生冲突的处理方式
理解你操作图形化的时候, git 在什么? 了解你在做的文件的git状态? 1. 添加文件 git add . -A git commit -m "your commit here" ...
- css如何实现(animation)跑马灯效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 排球计分程序的uml图
- linux命令关机和重启命令及文件查找管道符用法linux grep
关机和重启命令 Shutdown Reboot Halt poweroff grep和管道符 昨天的时候 leader 给我出了道问题: 找出文件夹下包含 "aaa" 同时不包含 ...
- DER编码
1. Attribute Type编码 对于标识串,采用低标识编码方式,只需1个字节.OBJECT IDENTIFIER的 tag为Ox06;class选择universal,则位8和位7为0,O ...
- FastReport报表金额数字转大写问题
在使用FastReport报表打印的时候涉及到财务结算金额时,会用到大写,系统保存的都为数字,将数字转换为大写没有默认的系统内置函数,经过查阅资料,可通过对FastReport的页面设计代码修改实现: ...
- AS3.0和php数据交互POST方式
AS3.0和php数据交互POST方式首先打开flash建立一个as3.0的文件拖 textarea和button组建到舞台上分别给两个组件命名:txtcontent和addcontent然后点第一帧 ...