将你的 Virtual dom 渲染成 Canvas
项目概述
一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中。支持常规的滚动操作和一些基础的元素事件绑定。
github 地址: github
demo实例:demo
背景
从一个小的需求说起:某一天,产品提了一个这样的需求,需要制作一个微信活动页,活动页可以分享包含用户相关信息的图片。这些信息是需要从接口取的,而且每个人都不一样。第一次碰到这种需求的时候,基本上都会去手撸canvasAPI去做渲染功能,这种情况的步骤大致如下:
- 写一大串 dom template 标签
- 渲染template成dom标签
- 开始捕捉dom元素,绘制canvas
- canvas 渲染图片
面临的主要问题是复用性太差,其次是性能上也有问题,用户看到的界面不一定和正式渲染出的界面一致,可能存在渲染差异。作为一个有追求的前端,当然得想想看有没有更好的法子。于是乎了解到了一个html2canvas 这样一个库。但是总是感觉还是要转成dom再去绘制,而且感觉性能和稳定性也不是很好。
我们知道vue通过vnode实现了对不同端的渲染工作,那有没有可能通过vnode实现对canvas的渲染呢?也就是说,没有vnode -> html -> canvas 而是直接vnode -> canvas。 同时利用vue的数据驱动,来达到绘制的数据驱动。想法有了,下面开始实施。
调研
这篇文章对此有详细的介绍:60 FPS on the mobile web 这里简单的概括一下:
canvas是一种立即模式的渲染方式,不会存储额外的渲染信息。Canvas 受益于立即模式,允许直接发送绘图命令到 GPU。但若用它来构建用户界面,需要进行一个更高层次的抽象。例如一些简单的处理,比如当绘制一个异步加载的资源到一个元素上时会出现问题,如在图片上绘制文本。在HTML中,由于元素存在顺序,以及 CSS 中存在 z-index,因此是很容易实现的。
dom渲染是一种保留模式,保留模式是一种声明性API,用于维护绘制到其中的对象的层次结构。保留模式 API 的优点是,对于你的应用程序,他们通常更容易构建复杂的场景,例如 DOM。通常这都会带来性能成本,需要额外的内存来保存场景和更新场景,这可能会很慢。
看来canvas绘制页面的研究,很久之前就已经有人付出过研究了。而且性能还是很不错的。那我们更要试试看,到底我们的想法能不能实现了!越来越期待....
开始
canvas 的渲染其实也是一种尝试,既然前人以及做了充分的实践,那么我们便站在巨人的肩膀上去基于vue来实现一个数据驱动的canvas渲染。说做就做!(我们这里只提供思路,不做具体实现细节的讨论,因为实现起来有点复杂,如果有兴趣可以参考我的项目实现,或者一起交流探讨 )
处理vnode
熟悉Vue源码的应该都知道,Vue通过render
函数,传入createElement
方法来构造出一个vnode
,通过发布--订阅
模式来实现对数据的监听,重新生成vnode
。我们要做的就是在vnode
这一层开始。所以,我们基于Vue源码的方式,实现一个监听函数,并混入Vue实例中:
Vue.mixin({
// ...
created() {
if (this.$options.renderCanvas) {
// ...
// 监听vnode中引用的变化,重新渲染
this.$watch(this.updateCanvas, this.noop)
// ...
}
},
methods: {
updateCanvas() {
// 模拟Vue render 函数
// 寻找实例中定义的 renderCanvas 方法,并传入createElement方法
let vnode = this.$options.renderCanvas.call(this._renderProxy, this.$createElement)
}
})
这样我们就可以愉快的在组件内部使用:
renderCanvas (h) {
return h(...)
}
canvas 元素处理
render 的vnode我们需要做额外的一些约束,也就是说我们需要怎么样的渲染标签,来渲染对应的canvas元素(举个
将你的 Virtual dom 渲染成 Canvas的更多相关文章
- 如何理解Virtual DOM
什么是虚拟DOM 接下来用vdom(Virtual DOM)来简称为虚拟DOM. 指的是用JS模拟的DOM结构,将DOM变化的对比放在JS层来做.换而言之,虚拟DOM就是JS对象.如下DOM结构: & ...
- React源码解析-Virtual DOM解析
前言:最近一直在研究React,看了陈屹先生所著的深入React技术栈,以及自己使用了这么长时间.对React应该说有比较深的理解了,正好前阵子也把两本关于前端设计模式的书看完了,总感觉有一种知识错综 ...
- virtual dom & mvvm
虚拟dom 用js对象来表示dom树的结构,然后用这个对象来构建一个真正的dom树插入文档中: 当状态有变时,重新构造一个新的对象树,然后比较新的和旧的树,记录两个数的差异: 把差异部分应用到真正的d ...
- 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?
引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...
- PHP如何自动识别第三方Restful API的内容,自动渲染成 json、xml、html、serialize、csv、php等数据
如题,PHP如何自动识别第三方Restful API的内容,自动渲染成 json.xml.html.serialize.csv.php等数据? 其实这也不难,因为Rest API也是基于http协议的 ...
- 个人对于Virtual DOM的一些理解
之前一直认为react的Virtual DOM操作会比传统的操作DOM要快,这其实是错误的,React 从来没有说过 "React 比原生操作 DOM 快".如果没有 Virtua ...
- 抛开react,如何理解virtual dom和immutability
去年以来,React的出现为前端框架设计和编程模式吹来了一阵春风.很多概念,无论是原本已有的.还是由React首先提出的,都因为React的流行而倍受关注,成为大家研究和学习的热点.本篇分享主要就聚焦 ...
- 深度剖析:如何实现一个 Virtual DOM 算法
本文转载自:https://github.com/livoras/blog/issues/13 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步 ...
- Virtual DOM 算法
前端 virtual-dom react.js javascript 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步骤一:用JS对象模拟DOM ...
随机推荐
- Java的面向对象(初涉)
Java的面向对象(初涉) 面向对象的分析根据抽象关键的问题域来分解系统.面向对象的设计是一种提供符号设计系统的面向对象的实现过程,它用非常接近实际领域术语的方法把系统构造成"现实世界&qu ...
- Testing - 软件测试知识梳理 - 软件性能测试
软件性能测试的基本概念 软件的性能是软件的一种非功能特性,它关注的不是软件是否能够完成特定的功能,而是软件在完成该功能时展示出来的及时性. 软件性能的指标 响应时间:是指系统对请求作出响应的时间,并且 ...
- Linux编程 2 (遍历目录cd与查看文件和目录ls)
一. 遍历目录 在 linux系统上,可以使用cd切换目录命令. 分二种路径,一是绝对文件路径,另一种是相对文件路径. 1. 绝对文件路径 在虚拟目录中采用文件路径,以虚拟目录根目录开始,相当于 ...
- 使用okHttp3 的坑!!
1.使用同步阻塞调用: 需要自己创建线程,否则会报主线程使用网络的error: 2.使用非阻塞异步调用: 1.返回的Response,response.body().string()获取json只能读 ...
- 安装mysql.zip文件教程(包含常见问题修复)
参考链接: https://jingyan.baidu.com/article/63f236284aca280208ab3dcc.html https://jingyan.baidu.com/arti ...
- LearnOpenGL学习笔记(四)——着色器类编写
之前我们将着色器的代码用glsl写好之后,保存为字符串指针,然后用一个函数去编译它,这是一种手段,对于简单的着色器代码可以这样.但当我们针对复杂的着色器,我们发现编写.编译.管理着色器是一件麻烦事.我 ...
- sql 表连接
join (inner join ) 注释:INNER JOIN 关键字在表中存在至少一个匹配时返回行. left join 注释:LEFT JOIN 关键字从左表(table1)返回所有的行,即 ...
- 【CSS学习】--- z-index属性
一.前言 网页显示实际上是三维的,我们直观看到的有x轴和y轴,但在网页布局上还有一个z轴. 对于定位元素,我们使用top.right.left.bottom来实现元素在x-y平面上的定位,但为了表示布 ...
- Angular2入门:TypeScript的类 - 定义、继承和作用域
一.定义和继承 二.public.private和protected
- filezilla通过root账户远程连接管理ubuntu server服务器文件
前言: 准备重温一下今天在工作中遇见的一个问题,在刚刚安装上的server上测试,做好的文件不是很好传到server项目目录,于是使用了filezilla这个工具,它可以使用ssh来连接,于是乎就引入 ...