项目概述

一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中。支持常规的滚动操作和一些基础的元素事件绑定。

github 地址: github

demo实例:demo

背景

从一个小的需求说起:某一天,产品提了一个这样的需求,需要制作一个微信活动页,活动页可以分享包含用户相关信息的图片。这些信息是需要从接口取的,而且每个人都不一样。第一次碰到这种需求的时候,基本上都会去手撸canvasAPI去做渲染功能,这种情况的步骤大致如下:

  1. 写一大串 dom template 标签
  2. 渲染template成dom标签
  3. 开始捕捉dom元素,绘制canvas
  4. 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的更多相关文章

  1. 如何理解Virtual DOM

    什么是虚拟DOM 接下来用vdom(Virtual DOM)来简称为虚拟DOM. 指的是用JS模拟的DOM结构,将DOM变化的对比放在JS层来做.换而言之,虚拟DOM就是JS对象.如下DOM结构: & ...

  2. React源码解析-Virtual DOM解析

    前言:最近一直在研究React,看了陈屹先生所著的深入React技术栈,以及自己使用了这么长时间.对React应该说有比较深的理解了,正好前阵子也把两本关于前端设计模式的书看完了,总感觉有一种知识错综 ...

  3. virtual dom & mvvm

    虚拟dom 用js对象来表示dom树的结构,然后用这个对象来构建一个真正的dom树插入文档中: 当状态有变时,重新构造一个新的对象树,然后比较新的和旧的树,记录两个数的差异: 把差异部分应用到真正的d ...

  4. 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?

    引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...

  5. PHP如何自动识别第三方Restful API的内容,自动渲染成 json、xml、html、serialize、csv、php等数据

    如题,PHP如何自动识别第三方Restful API的内容,自动渲染成 json.xml.html.serialize.csv.php等数据? 其实这也不难,因为Rest API也是基于http协议的 ...

  6. 个人对于Virtual DOM的一些理解

    之前一直认为react的Virtual DOM操作会比传统的操作DOM要快,这其实是错误的,React 从来没有说过 "React 比原生操作 DOM 快".如果没有 Virtua ...

  7. 抛开react,如何理解virtual dom和immutability

    去年以来,React的出现为前端框架设计和编程模式吹来了一阵春风.很多概念,无论是原本已有的.还是由React首先提出的,都因为React的流行而倍受关注,成为大家研究和学习的热点.本篇分享主要就聚焦 ...

  8. 深度剖析:如何实现一个 Virtual DOM 算法

    本文转载自:https://github.com/livoras/blog/issues/13 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步 ...

  9. Virtual DOM 算法

    前端 virtual-dom react.js javascript 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步骤一:用JS对象模拟DOM ...

随机推荐

  1. git关于文件权限修改引起的冲突及忽略文件权限的办法

    我们在使用git进行版本管理的时候,有时候只是修改了文件的权限,比如将pack.php修改为777,但其实文件内容并没有改变,但是git会认为此文件做了修改,原因是git把文件权限也算作文件差异的一部 ...

  2. Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!

    前几天写了一篇 Java 8 即将在 2019 年停止免费向企业提供更新的文章,企图迫使用户向更新一代的 Java 版本升级,但让人遗憾的是,小编今天收到了 Oracle Java 版本的升级推送,装 ...

  3. Liferay7 BPM门户开发之5: Activiti和Spring集成

    参考文档: https://github.com/jbarrez/spring-boot-with-activiti-examplehttps://github.com/sxyx2008/spring ...

  4. 列表list切片

    list1 = [1, 2, 3, 4, 5, 6] list1[::-1] >>>[6, 5, 4, 3, 2, 1] list1[:3:-1] >>>[6, 5 ...

  5. PHP-----浅谈垃圾回收机制

    前言 大多数编程语言都会有自身的垃圾回收机制,php也不例外.经常听很多人说gc,也就是垃圾回收器,全程为Garbage Collection. 在php5.3之前,是不包括垃圾回收机制的,也没有专门 ...

  6. Nginx + Keepalived负载均衡

    第一步: 下载keepalived地址:http://www.keepalived.org/download.html 解压安装: tar -zxvf keepalived-1.2.18.tar.gz ...

  7. Android 系统内核层与 Linux Kernel 的比较

    Android 内核具有和标准 Linux 内核一样的功能,主要实现了内存管理.进程调度.进程间通信等功能.但在文件系统.进程间通信.内存管理等方面存在差异. 1.文件系统.移动设备采用的大多不是硬盘 ...

  8. Java 8 新特性-菜鸟教程 (9) -Java8 Base64

    Java8 Base64 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编码的编码器和解码器. Base64工具类提供了一套静态方法获取下面三种B ...

  9. Linux给命令设置别名

    查看命令别名:alias alias 设置命令别名:alias 别名='命令' alias ll='ls -l' 取消命令别名:unalias 别名 unalias ll 命令永久生效 上面直接在sh ...

  10. iframe可通过postMessage解决跨域、跨窗口消息传递

    https://www.cnblogs.com/dorothyorsusie/p/6178599.html //iframe传参给父级页面 function give_info(){ console. ...