-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
将你的 Virtual dom 渲染成 Canvas #32
Comments
很有创意,居然还可以这么玩 |
有兴趣可以一起来玩玩 |
很有意思,这个想法~ |
@guimeisang 哈哈,感觉蛮好玩的,我也只是实现了很基本的一些功能,做到后面就会越来越复杂。考虑的点就会更多~ 算是抛砖引玉吧。 |
react-konva可以了解下,实现思路“应该”和你差不多,并且渲染性能挺稳定的 |
@guimeisang 看了一下,很有参考价值!😊。后面可以考虑看看他的一些实现,或许有更好的帮助!🤔 |
@muwoo 可以的,拉我进入组织吧 |
@guimeisang 加我qq吧: 2424880409 |
的确是一种新的思路,感觉不错 |
# for free
to join this conversation on GitHub.
Already have an account?
# to comment
项目概述
一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中。支持常规的滚动操作和一些基础的元素事件绑定。
github 地址: github
demo实例:demo
背景
从一个小的需求说起:某一天,产品提了一个这样的需求,需要制作一个微信活动页,活动页可以分享包含用户相关信息的图片。这些信息是需要从接口取的,而且每个人都不一样。第一次碰到这种需求的时候,基本上都会去手撸canvasAPI去做渲染功能,这种情况的步骤大致如下:
面临的主要问题是复用性太差,其次是性能上也有问题,用户看到的界面不一定和正式渲染出的界面一致,可能存在渲染差异。作为一个有追求的前端,当然得想想看有没有更好的法子。于是乎了解到了一个html2canvas 这样一个库。但是总是感觉还是要转成dom再去绘制,而且感觉性能和稳定性也不是很好。
我们知道vue通过vnode实现了对不同端的渲染工作,那有没有可能通过vnode实现对canvas的渲染呢?也就是说,没有vnode -> html -> canvas 而是直接vnode -> canvas。 同时利用vue的数据驱动,来达到绘制的数据驱动。想法有了,下面开始实施。
调研
这篇文章对此有详细的介绍:60 FPS on the mobile web 这里简单的概括一下:
看来canvas绘制页面的研究,很久之前就已经有人付出过研究了。而且性能还是很不错的。那我们更要试试看,到底我们的想法能不能实现了!越来越期待....
开始
canvas 的渲染其实也是一种尝试,既然前人以及做了充分的实践,那么我们便站在巨人的肩膀上去基于vue来实现一个数据驱动的canvas渲染。说做就做!(我们这里只提供思路,不做具体实现细节的讨论,因为实现起来有点复杂,如果有兴趣可以参考我的项目实现,或者一起交流探讨 )
处理vnode
熟悉Vue源码的应该都知道,Vue通过
render
函数,传入createElement
方法来构造出一个vnode
,通过发布--订阅
模式来实现对数据的监听,重新生成vnode
。我们要做的就是在vnode
这一层开始。所以,我们基于Vue源码的方式,实现一个监听函数,并混入Vue实例中:这样我们就可以愉快的在组件内部使用:
canvas 元素处理
render 的vnode我们需要做额外的一些约束,也就是说我们需要怎么样的渲染标签,来渲染对应的canvas元素(举个🌰):
其中这些元素类分别都继承于一个Super类,并且由于它们各有不同的展示方式,因此它们分别实现自己的draw方法,做定制化的展示。
绘制对象的布局机制实现
绘制 canvas 布局最基础的写法是为canvas 元素传入一系列坐标点和相关的基础宽高,这样写到实际项目中可能是这样的:
这样写确实有点不方便维护,目前有好几种解决方案,一种是使用
css-layout
去做管理。css-layout
支持的转换属性如下:这样也只是做了一层转换,帮我们更好的用css思维去写canvas,但是如果我们很不爽
css in js
的写法,其实我们还可以写一个webpack loader 来加载外部css:主要也就是将 css 文件转成
AST
语法树,之后再对语法树做转换,转成canvas
需要的定义形式。并以变量的形式注入到组件中。实现列表滚动
如果我们的元素很多,需要滚动时,我们必须解决
canvas
内部元素滚动的问题。这里我选择了使用Zynga Scroller 来模拟用户滚动方法,通过他返回的滚动坐标点,来对canvas进行重绘。详细的参考这里
事件模拟
对于
click,touch
等dom事件的模拟,我们采用的方案是根据点击区域进行检测,并找出最底层的元素,递归寻找父元素并触发对应事件处理程序,从而模拟事件冒泡。详细的实现可以参考这里
最后
canvas绘制页面也是一种创新的尝试,希望这里的研究对你有启发,也欢迎您的PR。这里也做了很多性能优化,限于篇幅不在赘述了,有兴趣也可以一起探讨。
最后:它并不意味着完全取代基于DOM的渲染,这仍然需要文本输入,复制/粘贴,可访问性和SEO。
出于这些原因,我们可以使用canvas和基于DOM的渲染的组合。
The text was updated successfully, but these errors were encountered: