【ZRender 渲染引擎 - 贰】 | Vue 框架集成与绘制其他图元
theme: cyanosis
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 8 天,点击查看活动详情
1. Vue 中使用 ZRender
上一篇中,我们通过最原始的方式体验了一下 ZRender
的使用。接下来,为了更方便管理绘制测试效果,使用 Vue
框架集成 ZRender
库。看完本篇应该能体会出这个管理的必要性,我们要完成如下的绘制样例展示效果:
如下,通过 vue cli
创建一个 zrender-player
的项目,这里组件使用类的形式 : class-component
```sh ----> vue -V
@vue/cli 5.0.8
----> vue create zrender-player ```
然后通过通过 npm
安装 zrender
:
sh ----> npm install zrender
如下所示,定义一个 PaperBox
组件来展示绘制的单体,其中组件的布局结构和样式基于 【上一篇】 实现,定义 PaperBox
继承自 Vue
,作为独立的组件使用。定义 ZRenderType
类型的 render2d
私有成员,在 mounted
回调中初始化。
``` ---->[PaperBox.vue]----
//同上篇 ```
2. 遇到问题 -> 分析问题 -> 解决问题
在集成的过程中,没想到这么快就不得不瞄 ZRender
的源码。出现了一个问题 :
Renderer 'undefined' is not imported. Please import it first.
遇到问题,不要怕,分析问题是一项很重要的能力,自主解决问题
是累积经验的重要途径之一。错误出现时,往往都会伴随一些蛛丝马迹,如下所示,其中有错误时的栈信息:
点击栈信息,可以看到错误发生的位置:是在 ZRender
对象初始化时,可以在源码稍上一些点断掉调试一下:
重点是这段逻辑,核心对象是 painterCtors
和 rendererType
,其中 rendererType
是个字符串,在设置为项中为空时,使用 canvas
。 painterCtors
是一个对象,通过 rendererType
可以获取个东西,如果获取不到会出问题。
所以现在的显示是 painterCtors
对象,在 19
行中对象声明的场合,默认是的空对象。通过观察可以看到它目前仍是一个空对象,也就是说,没有为 painterCtors
添加内容是这个错误的根源:
然后追踪 painterCtors
的赋值情况,可以看到在 registerPainter
中会为 painterCtors
根据 name
设置 Ctor
对象。也就是说需要使用 registerPainter
方法来注册绘制器,理论上来说 ZRender
应该会默认注册一个绘制器,但目前来看,实际上没有。
所以想要解决这个问题,最简单的方式是手动注册一下, 如下在 mian.ts
中注册一下。
``` ---->[main.ts]---- import { createApp } from 'vue' import App from './App.vue' import CanvasPainter from "zrender/lib/canvas/Painter"; // 引入 Canvas 绘制器 import * as zrender from "zrender"; // 引入 zrender 绘制器
zrender.registerPainter('canvas', CanvasPainter); // 注册绘制器 createApp(App).mount('#app') ```
这样再调试时,就可以看到 painterCtors
对象在存在键值对,在网页中也可以正常显示绘制的内容。另外如果需要绘制 svg
的话,也可以注册一下 SVGPainter
。
另外,在 zrender
的 all.ts
中可以看到注册的逻辑,但是实际好像不起作用。网上对 zrender
在 Vue
中的集成文章都比较简单,没有出现这个问题,可能是 Vue3
或者是 TS
引起的。至于具体的原因,我们也不怎么清楚,希望懂行的可以解释一下。好在这个小问题可以解决。
3. 封装绘制单体
如下所示,现在的目标是让绘制的单体可以依次排列展示,也就是说根据 数组数据
遍历显示 单体组件 PaperBox
。所以实现需要定义数据的组织方式,从展示的形式上来看,主要需要两个数据:标题
与 图元列表
,通过 ExModel
类对数据进行组织管理:
``` import * as zrender from "zrender";
export class ExModel { label: string; elements: zrender.Element[];
constructor(label: string, elements: zrender.Element[]) {this.label = label;this.elements = elements;
}
} ```
也就是说,ExModel
数据就是对绘制样例的封装, 就代表一个数据,决定一个单体的表现。如下,使用 PaperBox
组件的处理对 ExModel
对象进行渲染出现。
``` ---->[PaperBox]----
```
其中 Html
布局将之前的死数据通过 ExModel
对象进行呈现设置。其实从本质上来看,这和 Flutter
中的组件封装的思想并没有什么区别,都是通过 数据
来驱动 视图
。
<template> <div class="wrapper"> <div :id=model.label class="box"></div> <span class="label">{{model.label}}</span> </div> </template>
4. 数据的供应
单体组件封装完毕后,接下来需要考虑数据的来源问题,这里的数据自然是我们自己创造的。如下,通过一个文件来统一收录数据, 其中每个 exModels
数组中的元素觉得一个样例的展示:
``` ---->[examples/exData.ts]---- import polylineExs from './polyline'; import lineExs from './line'; import circleExs from './circle'; import rectExs from './rect'; import ellipsExs from './ellipse'; import { ExModel } from './ExModel';
const exModels = [ new ExModel('折线: Polyline',polylineExs), new ExModel('直线: Line',lineExs), new ExModel('圆形: CirCle',circleExs), new ExModel('矩形: Rect',rectExs), new ExModel('椭圆: Ellipse',ellipsExs), ];
export default exModels; ```
为了方便独立管理,这里将每个样例放在一个文件在,比如下面是 polyline
的图元对象:
``` ---->[examples/polyline.ts]---- import * as zrender from "zrender";
const polylineEx1 = new zrender.Polyline({ shape: { points: [ [0, 50], [10, 60,], [20, 40,], [30, 80,], [40, 20,], [50, 50,], [60, 40,], [100, 40,], ] }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
const polylineExs = [polylineEx1]
export default polylineExs; ```
5. 展示组件
这样数据和单体都准备完毕,接下来遍历渲染即可,如下定义 ZrenderPage
组件,通过 v-for
指令遍历 exModels
的数据渲染 PaperBox
组件,即可完成显示:
```
.container {display: flex;justify-items: center;justify-items: center;gap: 20px; } ```
这样,如果需在界面上添加一个图元的样例,只需要在 exModels
中添加数据即可。比如现在想在界面中添加圆弧的样例。
只要在 exModels
中添加一个元素即可:
``` import * as zrender from "zrender";
const arcEx1 = new zrender.Arc({ shape: { cx: 50, cy: 50, r: 40, startAngle: 0, endAngle: 135 * Math.PI / 180, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
const arcExs = [arcEx1]
export default arcExs; ```
这样就可以将上一篇中绘制的图元同屏展示,也方便接下来的绘制测试。所以 Vue
通过组件化实现 数据
和 界面
的映射关系,对于批量同类视图的显示是很有益的。如果使用原始的 html
结构进行布局,一个个写出来将非常繁琐,而且难以维护。
5. 扇形区、多边形、正多边形、星形
扇形区
、多边形
、正多边形
、星形
分别通过 Sector
、Polygon
、Isogon
、Star
进行绘制。简单看下效果,这里就不细说属性了,想具体了解的可以参考官方文档:zrender-doc。官网的文档没有配图,这里就当给文档配图了:
扇形区: Sector
扇形区域对于统计图中的 饼图
是非常重要的,它可以绘制内外半径间的部分圆环区域。上图中红色区域是 sectorEx1
,黄色区域是 sectorEx2
:
``` const sectorEx1 = new zrender.Sector({ shape: { cx: 50, cy: 50, r: 40, r0: 30, startAngle: 0, endAngle: 135 * Math.PI / 180, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
const sectorEx2 = new zrender.Sector({ shape: { cx: 50, cy: 50, r: 40, r0: 30, startAngle: -90 * Math.PI / 180, endAngle: -165 * Math.PI / 180, clockwise: false }, style: { stroke: 'blue', lineWidth: 1, fill: 'yellow', }, }) ```
多边形: Polygon
多边形就是一个会自动封闭首尾的折线,也是指定 shape
中的点集进行连线:
const polygonEx1 = new zrender.Polygon({ shape: { points: [ [0, 50], [10, 60,], [20, 40,], [30, 80,], [40, 20,], [50, 50,], [60, 40,], [100, 40,], ] }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
正多边形: Isogon
const isogonEx1 = new zrender.Isogon({ shape: { x: 50, y: 50, r: 40, n: 8 }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
星形: Star
const starEx1 = new zrender.Star({ shape: { cx: 50, cy: 50, r: 40, n: 7, r0: 20, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
6. 水滴、心形、玫瑰线、旋轮线、圆环
下面来看五个没啥大用的形状,水滴
、心形
、玫瑰线
、旋轮线
、圆环
分别通过 Droplet
、Heart
、Rose
、Trochoid
、Ring
进行绘制。
水滴: Droplet
const dropletEx1 = new zrender.Droplet({ shape: { cx: 50 , cy: 65, width: 25, height: 60, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
心形: Heart
const heartEx1 = new zrender.Heart({ shape: { cx: 50 , cy: 30, width: 35, height: 60, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
玫瑰线: Rose
``` const roseEx1 = new zrender.Rose({ shape: { cx: 50, cy: 50, r: [50], k: 2, n: 15 }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
```
玫瑰线: Trochoid
其中 location 为out
表示外旋轮
,图中红线所示;in
表示内旋轮
,图中蓝线所示。
``` const trochoidEx1 = new zrender.Trochoid({ shape: { cx: 50, cy: 50, r: 40, r0: 5, d:6 , location: 'out' }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
const trochoidEx2 = new zrender.Trochoid({ shape: { cx: 50, cy: 50, r: 40, r0: 5, d:6 , location: 'in' }, style: { stroke: 'blue', lineWidth: 1, fill: 'none', }, }) ```
圆环: Ring
const ringEx1 = new zrender.Ring({ shape: { cx: 50, cy: 50, r: 40, r0: 30, }, style: { stroke: 'red', lineWidth: 1, fill: 'none', }, })
到这里,ZRender
中的 18
的基本图元的绘制了解完毕,而且通过 Vue
框架搭建了一个方便测试的环境。另外还有路径 Path
的绘制这里暂时不介绍,将在后期单独说明。那本文就到这里,谢谢观看 ~
@张风捷特烈 2022.10.21 未允禁转
我的 公众号: 编程之王
我的 github 主页
: toly1994328
【ZRender 渲染引擎 - 贰】 | Vue 框架集成与绘制其他图元相关推荐
- vue+three.js展示nrrd+vtk3D模型-vue框架集成(下)
nrrd3D模型文件.vtk3D模型文件vue如何使用 话不多说,直接上图 小白的坎坷路程 网上资源视频关于nrrd模型和vtk模型是真的少,公司都没有接触过这方面,职场小白, 累死了要.大家有同感可 ...
- 渲染引擎开发之框架搭建
本来只是想学习一下最新的图形API,并在基础上做一些图形相关的技术尝试.但是后来发现,要想深入学习这两块知识,必须自己动手搭建一个渲染引擎,渲染引擎大部分的工作其实和图形技术无关,更多的是合理的规划资 ...
- 浏览器渲染引擎学习总结
简单介绍浏览器渲染引擎情况 很多人就只会用浏览器,不知道浏览器的工作原理或者说浏览器最核心的东西,浏览器的内核是最核 心的东西,也叫做渲染引擎,那这个东西到底是干嘛的呢,下面本教程就为大家好好介绍一下 ...
- 01-什么是渲染引擎
前情回顾:2021 技术新番 - 从零打造渲染引擎系列 在开始写代码之前,要先明确渲染引擎到底是什么东西,才能知道要写什么东西. 在 Google 里面搜索 ???? 渲染引擎关键字,出来的结果都是关 ...
- Hieroglyph3(基于DirectX 11的开源渲染引擎) 框架分析
Hieroglyph3是一个基于微软最新图形API:DirectX 11的渲染引擎,同时也是<Practical Rendering and Computation with Direct3D ...
- [转][osg]osg渲染引擎框架图,流程图(根据《最长一帧》整理)
转自:http://m.blog.csdn.net/article/details?id=49679731 本文参考<<osg最长一帧>>, <<OpenScene ...
- html集成到小程序1011无标题,GitHub - billee1011/cax: 小程序、小游戏以及 Web 通用 Canvas 渲染引擎...
Cax 小程序.小游戏以及 Web 通用 Canvas 渲染引擎 小程序 DEMO 正在审核中敬请期待 小游戏 DEMO 正在审核中敬请期待 特性 Learn Once, Write Anywhere ...
- vue中集合取第一个_快速学习Vue框架(知识点集合)
学习Vue的小伙伴速度看过来,快速学习Vue框架知识点集合贴来啦.建议收藏,尤其基础并不是很扎实的同学,本篇集合贴就是你日后工作的参考手册. 基础知识: ·vue的生命周期:beforeCreate/ ...
- 基于 Flutter 的 Web 渲染引擎「北海」正式开源!
简介: 阿里巴巴历时 3 年自研开发的 Web 渲染引擎北海(英文名:Kraken)正式开源,致力打造易扩展,跨平台,高性能的渲染引擎,并已在优酷.大麦.天猫等业务场景中使用. 作者 | 染陌 来源 ...
最新文章
- c, c++函数名编译符号修饰符说明
- USACO 1.0_Friday the Thirteenth
- python爬虫入门实例-Python爬虫快速入门:基本结构简单实例
- 以Attribute加上Header验证
- java组件化的优势_组件化编程开发如何判断组件的优劣性
- python 网盘上传_python学习笔记 day32 实现网盘上传下载功能
- 网站服务器需要定期重启吗,定期服务器重启的好处和障碍
- oracle stream 主键,oracle stream配置向导
- SharePoint关于publish page, WiKi page, Web part page区别
- python里什么叫子图_Python中的两个子图(matplotlib)
- 潘石屹没跑,他去学 Python 了
- html5在线制作教程,HTML5 Canvas 制作动画
- Domino(群组工作软件)
- OpenGL学习(二)用户与交互
- 手机端app存取session问题(tp5框架)
- centos7安装polygraph
- 洗头冲水时冲下好些头发,我是要秃了吗?
- linux安装nginx并配置域名映射和图片服务器
- matlab绘制世界地图(含国界)、中国地图(含省界),可下载m_map和shp文件
- 光脚丫思考Vue3与实战:第04章 模板语法 第03节 指令的修饰符
热门文章
- 信号与系统(3)---男生、女生声音信号的混合与分离
- 16. cpu的型号决定了计算机的基本性能,CPU的型号决定了计算机的基本性能。
- 矩阵键盘逐行扫描C语言,矩阵键盘C语言编程.pdf
- opencv python考勤_Python+Opencv+Tkinter指纹识别与人脸识别的门禁兼考勤(二)
- MySQL 之 数据操作
- 红象云腾童小军:建立开放联盟,加速大数据处理,完善大数据生态
- 百度百科词条创建技巧及经验之谈,如何顺利创建百科
- WEB漏洞测试(二)——HTML注入 XSS攻击
- Autodesk 3dsmax 下载!亲测有效!
- Java入门简单小游戏有哪些?