一、源起

  作者是名超大龄程序员,曾涉及了包括Web端、桌面端、移动端等各类前端技术,深受这些前端技术的苦,主要但不限于:

  1. 每种技术编写代码的语言及技术完全不同,同样呈现形式的组件各端无法通用;
  2. 大部分前端开发语言跟后端开发语言不同,不能共用一些数据结构;

  前端UI的本质是在显示器上呈现由像素点组成的画面,并且响应外部输入事件作出相应的重绘。由于作者对Skia2D绘图引擎比较熟悉,又恰好可以借鉴一下Flutter引擎的跨端实现,所以作者动起了重新造一个跨端UI的念头。 阿基米德说过:“给我一个支点,我可以撬动地球”,那作者要说:"给我一块画布,我可以造一个全新的跨端UI"。

二、画布及画笔:

  有了画布才能绘制用户界面,目前画布的来源主要是两类:

  1. Web端参考Flutter的实现,利用编译为WebAssembly的CanvasKit提供;
  2. 桌面端及移动端参考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的更多相关文章

  1. RPC基础以及造一个RPC的轮子需要注意些什么

    RPC基础以及造一个RPC的轮子需要注意些什么 前言 rpc即远程过程调用,是分布式系统常用的通信方法.远程可以是在一台机器上的不同进程或在不同一个机器上的不同进程.rpc更看重速度,像调用本地方法一 ...

  2. 【记录】如何造一个vite插件(1)

    在看文章前,先做个定位,这不是一篇纯粹的技术性文章,可以把它理解成一个叙述文章,记录我开发插件的过程. 开始前简单的吹个牛 vue2 也写了很多年了,多人合作始终避不开用到别人的组件.关键是有些组件没 ...

  3. dva的effect那么难用,自己造一个轮子吧

    背景 对于dva这个开发框架,国内从事react的前端工程师多半不会感到陌生,dva完善的开发体系和简单的api,让其被广泛运用到实际工作中.我所在的公司也是长期使用dva作为基础的开发框架,虽然好用 ...

  4. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 3 部分: Systemtap

    Systemtap的原理,Systemtap与DTrace比较,以及安装要求和安装步骤本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprob ...

  5. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  6. 一个强大的LogParser的UI工具--logparserlizard简介

    日志分析,特别是IIS日志,一般人都会想到LogParser工具,的确很强.但是命令行的操作界面令很多非专业的管理人员望而生畏,现在好了,有一个可视化的LogParser的UI工具可以使用了! Log ...

  7. 一个强大的LogParser的UI工具--logparserlizard简介(开源IIS日志分析工具)

    原文地址:http://blog.csdn.net/downmoon/article/details/4509513 日志分析,特别是IIS日志,一般人都会想到LogParser工具,的确很强.但是命 ...

  8. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 2 部分: DTrace

    DTrace的原理本系列文章详细地介绍了一个 Linux 下的全新的调式.诊断和性能测量工具 Systemtap 和它所依赖的基础 kprobe 以及促使开发该工具的先驱 DTrace 并给出实际使用 ...

  9. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap,第 1 部分: kprobe

    kprobe 的原理.编程接口.局限性和使用注意事项 本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprobe以及促使开发该工具的先驱DTr ...

  10. 从零讲解搭建一个NIO消息服务端

    本文首发于本博客,如需转载,请申明出处. 假设 假设你已经了解并实现过了一些OIO消息服务端,并对异步消息服务端更有兴趣,那么本文或许能带你更好的入门,并了解JDK部分源码的关系流程,正如题目所说,笔 ...

随机推荐

  1. python菜鸟学习: 4.购物车演练

    # -*- coding: utf-8 -*-'''1.启动程序后让用户输入消费额,然后打印商品列表'2.允许用户根据商品编码购买商品3.用户选择商品后,检测余额是否够,够则直接扣款,不够就提醒4.可 ...

  2. Delphi中var和out

    var: 传递的是参数的地址 out: 以返回值的形式返回结果,类似函数的效果:可以实现一个函数返回多个值

  3. 莫凡PYthon之keras 1

    莫凡PYthon 1 kearsregressionpython Regressor 回归 用神经网络去拟合数据. 主要代码 """ Regressor 回归 " ...

  4. CH32F103C8T6的USB开发(一)

    一.背景 项目用到单片机采集模拟量数据,原先使用USB转串口,速度嫌慢,还要转串口芯片,电脑还要安装驱动,现更改为采用USB的HID类来传输. 二.单片机选型 STM32F103的USB接口简单易用, ...

  5. Flutter基于Mac的环境配置

    1.下载Flutter SDK git clone https://github.com/flutter/flutter.git 2.配置Flutter镜像+Flutter环境变量 ( 先创建.bas ...

  6. Rancher 快速构建k8s容器管理平台解决方案(图片见原文链接)

    转载自Rancher 快速构建k8s容器管理平台解决方案_IT干货的博客-CSDN博客_k8s容器管理平台 一.Rancher 概述 Rancher 是企业级多集群Kubernetes管理平台,一个为 ...

  7. PLC入门笔记4

    逻辑指令及其应用 基本逻辑指令 续电器 PLC 公式 扩展逻辑指令 1.置位和复位线圈 置位ON/复位OFF (SET/RST) 不推荐置位复位线圈  可以用更好的方式去表达.. 2.能流取反开关 取 ...

  8. sqlite3 一条语句替换全表某个字符字段中的某个字符串

    update not_match_files set policy_id_tms = replace(policy_id_tms, substr(policy_id_tms,instr(policy_ ...

  9. scrollToFirstError失效解决方法

    ant design 使用 设置scrollToFirstError = true,表单验证失败后却没有滚动到第一个错误字段 解决方法: 在button按钮中加入 html-type = 'submi ...

  10. 【相邻父元素选择器】为啥p元素里面的h3也被选择了呢?求赐教

    <!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...