资讯专栏INFORMATION COLUMN

将你的 Virtual dom 渲染成 Canvas

adie / 489人阅读

摘要:项目概述一个基于的插件库,按照函数的写法,直接将生成的渲染到中。支持常规的滚动操作和一些基础的元素事件绑定。受益于立即模式允许直接发送绘图命令到。渲染是一种保留模式,保留模式是一种声明性,用于维护绘制到其中的对象的层次结构。

项目概述

一个基于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元素(举个

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96222.html

相关文章

  • 程序员练级攻略(2018):前端基础和底层原理

    摘要:下面我们从前端基础和底层原理开始讲起。对于和这三个对应于矢量图位图和图的渲染来说,给前端开发带来了重武器,很多小游戏也因此蓬勃发展。这篇文章受众之大,后来被人重新整理并发布为,其中还包括中文版。 showImg(https://segmentfault.com/img/bVbjM5r?w=1142&h=640); 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 这...

    widuu 评论0 收藏0
  • 用最科学的方法展示最形象的图表——前段数据可视化选型实践

    摘要:提供的图表的确可以满足大部分的需求,遵循了数据可视化的一些经典范式。数据可视化已然成为了新的风向标。数据团队的前端要做的就是用最科学的方法向用户展示最形象的图表,而这,也是我们前行的目标。 前言 也许很多人都会觉得奇怪,在这样一个更多以后台数据分析为主的公司,为什么需要一个专注于前端的团队?今天这篇文章就来讲述那些年我们错过的前端数据可视化,以此来解答这个问题。 需求 那么,在我们的项...

    Eminjannn 评论0 收藏0
  • 【黑科技】React-canvas助力HTML5

    摘要:值得一提的是,微信浏览器的内核,也即是浏览器内核已经内置了很多游戏引擎比如白鹭游戏引擎与,供开发者开发游戏,所以长时间来看,微信浏览器的画布性能将会越来越强大。showImg(https://user-gold-cdn.xitu.io/2019/5/17/16ac3f6acd651e01); 1、什么是流畅的用户体验? 游戏的开发界有一个理论,就是当动画或者交互响应达到60FPS(60帧每秒...

    MorePainMoreGain 评论0 收藏0
  • 【React进阶系列】从零开始手把手教你实现一个Virtual DOM(三)

    摘要:函数依次做了这几件事调用函数,对比新旧两个,根据两者的不同得到需要修改的补丁将补丁到真实上当计数器小于等于的时候,将加,再继续下一次当计数器大于的时候,结束下面我们来实现函数和函数。 上集回顾 【React进阶系列】从零开始手把手教你实现一个Virtual DOM(二) 上集我们实现了首次渲染从JSX=>Hyperscript=>VDOM=>DOM的过程,今天我们来看一下当数据变动的时...

    qqlcbb 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<