引言
一直以来,前端在编写可视化图形或图表时会使用各种各样的库。常见的无外乎hightcharts、echarts,还有图形语法的g2。
它们的特性和优劣这里不作讨论,我只想谈谈自己在平常遇到的场景中使用遇到的问题,以及针对这些提出的想法。
库要解决的几个问题,首先是跨平台。这里的平台是指canvas和svg平台。只要2者可以简单无缝切换,那么pc、移动、小程序……理论就都没问题了。其实主要是小程序不支持svg。另外根据实际情况不同,cavans和svg的性能表现会有差异。
echarts曾经总结过一篇:
![855dd2d02e7a7994130de4ef2d40d375.png](https://i-blog.csdnimg.cn/blog_migrate/fb02b94d1d355a0d7ad82b13d42cb0d3.jpeg)
库都是直接被使用,这就意味着复杂多变的需求很难定制化,千奇百怪的ui设计更是难以满足。于是使用这些库的同时,功能也就被彻底限制住了。想要自定义?通读源码自己修改的成本有多大……
于是库便会出现越来越多的配置,眼花缭乱的同时未必还能满足。
图形语法似乎能解决一些问题,它采用一系列如公式般的短语描述图形,然后绘制。但是这只能解决几何图形对应数据关系的问题,其它大量功能还是需要配置。并且它的理解学习成本也很高,自定义需求仍未解决。
什么是csx?
csx取名借鉴自jsx,Canvas-Svg-Xml,根据根节点的不同,自动切换为canvas或svg类型,两者功能完全等价。
按照传统,这里有Hello World的第一个例子:
<canvas width="360" height="360">
<span>Hello world!</span>
</canvas>
<svg width="360" height="360">
<span>Hello world!</span>
</svg>
csx所做的核心事情有3件:
- 实现一个精简的css布局引擎,统一表现模式;
- 实现css标准样式渲染,抹平canvas和svg的差异;
- 借鉴svg标准增加基本图形节点语法,实现几何绘图。
如此解决了绘图中布局处理困难、学习维护成本高、兼容实现麻烦、复用难统一标准的问题。
依旧是个简单的例子,展示了block和inline元素在canvas/svg中布局后绘制的结果:
说到布局,弹性布局flex就不得不提起,其在css3中被引入,是个十分强大的布局方式,已成为如今首选的主流方式。
作为css布局的核心功能之一,是必须要被支持的:
其它诸如绝对定位、相对定位、边框、边距、颜色、背景色、大小、字号、行高、渐变、变形等不一一赘述。我写了个简单的入门教程demo系列,链接在末尾,可以点进去看下。
事件的支持同jsx一样,采用on{Event}形式书写,被顶层canvas/svg劫持,内部计算适配后响应。
至于为什么,canvas只是一张二维图像,svg也只是个绝对定位的dom,必须经过计算后才能得知到底哪个事件应该正确响应。
接下来是个重要组成部分,dom+css解决了结构描述和布局样式的问题,那么那些矢量几何图形呢?
别慌,csx规定了以$开头的标签为图形标签,并且借鉴svg标准内置了基本的形状:
仅仅是基本形状还不够,假如用到其它没有的怎么办?想要复用自定义的形状怎么办?
继承形状基类并实现它即可:
数据或样式改变需要重绘。对于canvas来说很简单,清除后再绘制即可;对于svg来说不能这样做,因为整段重新生成html来说成本太大,解法就是常见的dom-diff。
这个例子还额外演示了js动画的效果:
内部事件计算适配响应已经很精准,不仅考虑的实际位置,还包括各种形变。
对于自定义图形,如果有更精确或其它自定义需求,可以覆盖willResponseEvent方法。
下面是一个展示点击必须在圆内而不是圆所在矩形的例子:
ui测试是个非常麻烦的事情,这里提供了一种用virtual-dom来测试的方法:
testarmy8735.me折线图是最常见的图表之一。这里以其为例,展示了如何编写一个折线图,体现出代码量少、css规范、零学习成本、易维护的特点。
图表中除了折线部分是几何图形外,其它均可表现为普通的dom+css,零成本对前端开发人员极为友好。 即便是几何图形标签,也很贴合dom和svg标准,只有几个简单的属性配置。
想要3d效果?
没问题,css中transform可以简单地办到(伪):
更加绚丽的还有火苗燃动效果。
一句话,有了css,ui真的变得又简单又强大:
其他
目前实现csx的框架karasjs还很初级,许多高级功能尚未实现。许多设计想法如有不成熟的地方,请多多指教。
除了几何图形,代码的复用还需更多,比如组件Component。
android和ios也支持canvas/svg,扩展至native是否可以完成复用同一套代码?
而对于动画而言,js动画比较自定义但是麻烦,css的transition和animate会是更好的方案吗?
一切都在未来继续……
后续文章:
阿侎:CSX:一种编写可视化图形的新方式(二)zhuanlan.zhihu.com整个教程demo系列地址:http://army8735.me/karasjs/karas/demo/
github仓库:https://github.com/karasjs/karas
csx语法预编译转换器yurine:https://github.com/karasjs/yurine
依赖的词法语法分析器homunculus:https://github.com/army8735/homunculus