【ZRender 渲染引擎 - 贰】 | Vue 框架集成与绘制其他图元

article/2025/9/21 5:01:22

theme: cyanosis

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 8 天,点击查看活动详情


1. Vue 中使用 ZRender

上一篇中,我们通过最原始的方式体验了一下 ZRender 的使用。接下来,为了更方便管理绘制测试效果,使用 Vue 框架集成 ZRender 库。看完本篇应该能体会出这个管理的必要性,我们要完成如下的绘制样例展示效果:

image.png


如下,通过 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 回调中初始化。

image.png

``` ---->[PaperBox.vue]----

{{label}}

```


2. 遇到问题 -> 分析问题 -> 解决问题

在集成的过程中,没想到这么快就不得不瞄 ZRender 的源码。出现了一个问题 :

Renderer 'undefined' is not imported. Please import it first.

遇到问题,不要怕,分析问题是一项很重要的能力,自主解决问题 是累积经验的重要途径之一。错误出现时,往往都会伴随一些蛛丝马迹,如下所示,其中有错误时的栈信息:

image.png

点击栈信息,可以看到错误发生的位置:是在 ZRender 对象初始化时,可以在源码稍上一些点断掉调试一下:

image.png


重点是这段逻辑,核心对象是 painterCtorsrendererType,其中 rendererType 是个字符串,在设置为项中为空时,使用 canvaspainterCtors 是一个对象,通过 rendererType 可以获取个东西,如果获取不到会出问题。

image.png

所以现在的显示是 painterCtors 对象,在 19 行中对象声明的场合,默认是的空对象。通过观察可以看到它目前仍是一个空对象,也就是说,没有为 painterCtors 添加内容是这个错误的根源:

image.png


然后追踪 painterCtors 的赋值情况,可以看到在 registerPainter 中会为 painterCtors 根据 name 设置 Ctor 对象。也就是说需要使用 registerPainter 方法来注册绘制器,理论上来说 ZRender 应该会默认注册一个绘制器,但目前来看,实际上没有。

image.png

所以想要解决这个问题,最简单的方式是手动注册一下, 如下在 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

image.png

image.png

另外,在 zrenderall.ts 中可以看到注册的逻辑,但是实际好像不起作用。网上对 zrenderVue 中的集成文章都比较简单,没有出现这个问题,可能是 Vue3 或者是 TS 引起的。至于具体的原因,我们也不怎么清楚,希望懂行的可以解释一下。好在这个小问题可以解决。

image.png


3. 封装绘制单体

如下所示,现在的目标是让绘制的单体可以依次排列展示,也就是说根据 数组数据 遍历显示 单体组件 PaperBox 。所以实现需要定义数据的组织方式,从展示的形式上来看,主要需要两个数据:标题图元列表,通过 ExModel 类对数据进行组织管理:

image.png

``` 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 数组中的元素觉得一个样例的展示:

image.png

``` ---->[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 组件,即可完成显示:

image.png

```

```


这样,如果需在界面上添加一个图元的样例,只需要在 exModels 中添加数据即可。比如现在想在界面中添加圆弧的样例。

image.png

只要在 exModels 中添加一个元素即可:

image.png

``` 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 结构进行布局,一个个写出来将非常繁琐,而且难以维护。

image.png


5. 扇形区、多边形、正多边形、星形

扇形区多边形正多边形星形 分别通过 SectorPolygonIsogonStar 进行绘制。简单看下效果,这里就不细说属性了,想具体了解的可以参考官方文档:zrender-doc。官网的文档没有配图,这里就当给文档配图了:

image.png

扇形区: 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. 水滴、心形、玫瑰线、旋轮线、圆环

下面来看五个没啥大用的形状,水滴心形玫瑰线旋轮线圆环 分别通过 DropletHeartRoseTrochoidRing 进行绘制。

image.png

水滴: 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 的绘制这里暂时不介绍,将在后期单独说明。那本文就到这里,谢谢观看 ~

image.png

  • @张风捷特烈 2022.10.21 未允禁转
  • 我的 公众号: 编程之王
  • 我的 github 主页 :  toly1994328

http://chatgpt.dhexx.cn/article/4LgihTa3.shtml

相关文章

zrender实现图形缩放功能

zrender实现图形缩放功能 一、绘制一个矩形图 <div id"main-container"></div>#main-container {width: 500px;height: 300px;border: 1px solid #888; }import * as zrender from zrenderconst container document.querySelector(#main-container) c…

ECharts 3.0底层zrender 3.x源码分析1-总体架构

zrender是一个轻量级的Canvas类库&#xff0c;作为百度Echarts 3.0的底层基础。截至目前查看的zrender源码和文档&#xff0c;包括官网文档都还停留在2.x时代&#xff0c;我打算用一个系列介绍下zrender 3.x的使用和源码&#xff0c;一些demo和没有在博客中介绍的源码请进我的g…

ZRender (Canvas)简单使用(拖拽、缩放、旋转、文字、层级)

一、ZRender 是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器&#xff1b; 二、下面是以图片做的简单demo&#xff0c;分为左中右三部分&#xff0c;左边是需要的图片&#xff0c;中间是绘图部分&#xff0c;右边是添加文字…

源码解读之zrender-ZRender 类(3)

00 小结 当我们在 zrender.init(document.getElementById(“canvas”))时&#xff0c;首先实例化了一个 ZRender 实例&#xff0c;在这个实例化过程中&#xff0c;主要实例化了&#xff1a; Storage 类&#xff0c;作用类似于全局状态管理Painter 类&#xff0c;可以理解为画…

【ZRender 渲染引擎 - 壹】 | 基础图形元素绘制

theme: cyanosis 持续创作&#xff0c;加速成长&#xff01;这是我参与「掘金日新计划 10 月更文挑战」的第 7 天&#xff0c;点击查看活动详情 开篇前言 在掘金认识我的都知道&#xff0c;我主要是研究 Flutter 的。其实我一直希望开发出一套好用的 Flutter 的图表库&#xf…

zrender学习

这个是项目总结&#xff0c;不适合学习 <div id"canvas" style"background-image:url(./canvasbg.gif)"></div> 定义zrender初始化对象&#xff0c;背景是一个gif图 样式如下 ↓ 工程里&#xff0c; topo.html <div id "containe…

zrender源码学习笔记(一):认识zrender

本文内容 入门zrender绘制原理 入门zrender zrender是Echarts底层的2D绘图引擎&#xff0c;在搞懂其原理之前&#xff0c;我们先学会如何使用zrender&#xff0c;我们从绘制一个简单圆形入门。这里也给出官网入门教程 初始化 zrender.init(dom)初始化zrender实例&#xff0c…

zrender 知识:使用zrender搭建流程图工具

首先看下最终的效果图&#xff1a; 主要使用的技术是zrender.js和vue.js&#xff0c;zrender 用于实现流程图&#xff0c;vue搭建整体架构。 本篇文章主要面向对zrender有一定了解的同学。 本篇文章只讲解核心flowchart的实现方法。 一.分析 流程图主要包含节点node、联系e…

zrender基础入门,简单的案例图形绘制

一、简单介绍 ZRender是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender也是ECharts的渲染器。 流程图&#xff1a; 二、使用入口 (1)npm install zrender&#xff0c;因为zrender不是浏览器自带不同于前面的canvas与svg&#xff0c;需要先下载 …

二维绘图引擎ZRender

1、开始使用 描述 ZRender是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。 下载 ZRender 项目在 gitHub ,也可以使用 npm install zrender 下载。 在 dist 目录下找到 zrender.js 和 zrender.min.js&#xff0c;前者是开发…

MATLAB中求矩阵的特征值和特征向量

矩阵特征值的数学定义 设A是n阶方阵&#xff0c;如果存在常数λ和n维非零列向量x&#xff0c;使得等式Axλ x成立&#xff0c;则称λ为A的特征值&#xff0c;x是对应特征值λ的特征向量。 求特征值和特征向量&#xff1a; eig(A)&#xff1a;求矩阵A的全部特征值&#xff0c…

简单易懂的特征值与特征向量

特征值与特征向量是线性代数中一个很基础的知识&#xff0c;但是很多人对这两个概念没有一个直观的概念&#xff0c;从直觉上&#xff0c;很难理解这两个东西&#xff0c;只知道公式&#xff0c;但是不知道它代表的意义。当年上现代课的时候&#xff0c;老师根本不会去讲这些东…

特征值和特征向量的几何意义

1. 特征值和特征向量 我们首先回顾下特征值和特征向量的定义如下&#xff1a; A x λ x Ax\lambda x Axλx 其中A是一个 n n n\times n nn的实对称矩阵&#xff0c; x x x是一个n维向量&#xff0c;则我们说 λ \lambda λ是矩阵A的一个特征值&#xff0c;而 x x x是矩阵A的…

特征值和特征向量的通俗解释

我们知道&#xff0c;特征向量的公式是 ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ 其中A代表矩阵&#xff0c;x代表特征向量&#xff0c;代表特征值。 众所周知&#xff0c;特…

对特征值和特征向量的理解

Agenda 1. 特征值和特征向量1.1 特征值和特征向量的通俗解释1.2 如何计算矩阵的特征值和特征向量1.3 特征多项式1.4 特征值和特征向量的性质 1. 特征值和特征向量 在讨论特征值和特征向量之前&#xff0c;必须声明的是现在我们关注的是有限维 线性空间上的线性变换。这里两个关…

线性代数(五)特征值和特征向量

文章目录 一&#xff1a;特征值与特征向量二&#xff1a;特征方程2.1行列式求解的另一种方法--初等变换2.2可逆矩阵定理以及行列式性质的补充2.3特征方程/特征多项式2.4相似性 三&#xff1a;对角化3.1从例子出发3.2定理3.3例子 一&#xff1a;特征值与特征向量 1.定义&#x…

特征值和特征向量(三)

特征值和特征向量&#xff08;三&#xff09; 一、先看一下教科书上的定义&#xff1a;设A是n阶方阵&#xff0c;如果存在常数及非零n向量x&#xff0c;使得&#xff0c;则称是矩阵A的特征值&#xff0c;x是A属于特征值的特征向量。给定n阶矩阵A&#xff0c;行列式 的结果是关…

网页游戏脱机脚本制作视频教程

网页游戏脱机脚本制作视频教程 百度网盘 布脖练馅辰杖怖铱试疤促钩咏合躺酱澈纸罢旨谖谘帘婪尾拾碧鸥居丶骨碳捍饰炔幌干衫乖商衣临衣氛捍运阂妊痰煤籽媒移惶心谑源谑丫松橙湛叭坪佳蛊八婪毒鄙刮碧悠凳炔捍灰钩贺篮媒梅敝粱寡油倨制柿囊谐举婪贫婪奖堂虏啄腊谘剿镜感诺衣挥堂猎…

python可以制作游戏脚本吗_用Python写一个游戏脚本,你会吗?

学习python有一段时间了,由于python语言的强大和简洁,是一个不错的脚本语言,就准备做个游戏脚本练练手。如果你也想多练项目实战。可以去小编的Python交流.裙 :一久武其而而流一思(数字的谐音)转换下可以找到了,里面有最新Python教程项目 听说pywin32写脚本还不错 pyw…

逆水寒商业脚本制作视频

​一章 易语言基础 共6课时 1、关于易语言必须了解的基本知识 2、易语言基本组件(不包括超级列表框)讲解 3、易语言超级列表框详解 3、易语言核心支持库讲解之一 4、易语言核心支持库讲解之二 5、易语言模块制作和DLL制作 6、用制作的模块和DLL开发三个小软件 第二章…