当前位置: 首页 > news >正文

【前端】【Echarts】【zrender】从入门到多路径信号流动动画实战

效果

效果
好的!下面这篇文章会引人入胜、通俗易懂地介绍 zrender,讲清它的核心配置与函数,最后结合之前的“多路径信号流动动画示例”做详细教学,帮助你快速上手并灵活运用。


全面解析 zrender — 从入门到多路径信号流动动画实战


目录

  1. 什么是 zrender?
  2. zrender 核心概念和主要配置
  3. 常用图形与接口介绍
  4. zrender 事件与动画机制
  5. 实战:基于 zrender 实现多路径信号流动动画
  6. 拓展与思考

1. 什么是 zrender?

zrender 是百度团队开源的一个轻量级 2D 渲染库,专注于高性能图形绘制。它是 ECharts 的底层渲染引擎,提供了丰富的图形类型、灵活的事件处理、动画支持,兼容 Canvas 和 SVG。

  • 为什么用 zrender?

    • 轻量、灵活,适合需要自定义图形和动画的场景
    • 兼容性好,支持主流浏览器
    • 支持丰富图形:矩形、圆形、线条、多边形、路径、文本等
    • 事件系统完善,支持拖拽、点击等交互
    • 支持图形分组与层级管理,方便复杂图形构建

简言之,zrender 是前端可视化的利器,适合做仪表盘、流程图、动画演示、交互设计等。


2. zrender 核心概念和主要配置

2.1 zrender 实例

调用:

const zr = zrender.init(domElement);

用于初始化渲染上下文,所有绘制都基于这个实例。

2.2 图形元素(Shape)

zrender 里的绘制单位是 图形元素,如 RectCirclePolylinePath 等。图形通过构造函数创建:

const circle = new zrender.Circle({shape: { cx: 100, cy: 100, r: 50 },style: { fill: 'red', stroke: 'black', lineWidth: 2 }
});
  • shape:定义图形的几何参数,如位置、尺寸
  • style:定义图形的渲染样式,如填充颜色、边框颜色、线宽、阴影等

2.3 图形类型及常用属性示例

图形类型主要 shape 属性备注
Rectx, y, width, height矩形
Circlecx, cy, r圆形
Linex1, y1, x2, y2直线
Polylinepoints: [[x1,y1], [x2,y2], …]折线
Polygonpoints: [[x1,y1], [x2,y2], …]多边形(闭合折线)
PathpathData: SVG 路径字符串任意复杂路径
Texttext, x, y, font文本

2.4 常用 style 属性

属性作用
fill填充颜色
stroke边框颜色
lineWidth边框线宽
opacity透明度
shadowColor阴影颜色
shadowBlur阴影模糊半径
font文字字体与大小
textAlign文字对齐

3. 常用接口和函数介绍

3.1 添加和删除图形

zr.add(shape);     // 添加图形
zr.remove(shape);  // 删除图形

3.2 设置图形属性

  • 修改形状参数
shape.attr('shape', { cx: 200, cy: 200 });
  • 修改样式
shape.setStyle({ fill: 'blue' });

3.3 事件绑定

支持常见事件:

shape.on('click', () => { console.log('点击了图形'); });
shape.on('mousemove', () => { /* 鼠标移动 */ });
shape.on('drag', () => { /* 拖拽 */ });

开启拖拽:

shape.draggable = true;

3.4 动画支持

shape.animateTo({ style: { fill: 'red' } }, {duration: 1000,easing: 'cubicOut'
});

3.5 线性渐变和径向渐变

  • 线性渐变
new zrender.LinearGradient(x0, y0, x1, y1, [{ offset: 0, color: 'red' },{ offset: 1, color: 'blue' }
])
  • 径向渐变
new zrender.RadialGradient(x, y, r, [{ offset: 0, color: 'white' },{ offset: 1, color: 'blue' }
])

4. zrender 事件与动画机制

zrender 通过内部动画帧驱动,支持全局动画事件监听:

zr.animation.on('frame', () => {// 每一帧执行,适合做流动动画、物体跟踪等
});

5. 实战教学:多路径信号流动动画


5.1 需求回顾

  • 多条路径
  • 每条路径独立小球流动
  • 小球带尾巴尾迹(拖尾渐变)
  • 可控制速度、颜色、半径、尾巴长度

5.2 代码结构及配置说明

示例把所有可修改配置放最前面,方便调整:

const configList = [{points: [[100, 200], [300, 250], [600, 180]],color: '#00FFFF',speed: 2,radius: 8,tailLength: 0.1},// 更多路径...
];
  • points:路径点数组,确定路径形状
  • color:路径和球颜色
  • speed:小球运动速度,单位像素/帧
  • radius:小球半径
  • tailLength:尾巴长度,按当前路径段比例计算

5.3 核心逻辑讲解

5.3.1 初始化每条路径
  • 画主线(低透明度)
  • 创建尾巴折线,使用线性渐变让尾巴逐渐消失
  • 创建带径向渐变的信号球
5.3.2 计算路径长度与分段长度

为了实现流动,先计算每条路径分段长度及总长度,方便定位小球位置。

5.3.3 帧动画更新

zr.animation.on('frame') 中,根据速度递增「进度」,再根据进度确定当前在哪条段及相对比例 t,然后计算当前小球的坐标。

尾巴位置计算同理,是当前进度向后(或向前)一定比例的点。


5.4 完整代码参考

详见我给你的代码示例【配置集中管理版】


6. 拓展思考

  • 结合拖拽事件,实时调整路径
  • 多点并行流动,模拟复杂管网
  • 节点状态高亮,添加交互信息弹窗
  • 融入数据驱动,实时更新信号状态

源码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><title>zrender 多路径信号流动(可配置)</title><style>html, body, #main {margin: 0;width: 100vw;height: 100vh;background: #111;}</style>
</head>
<body>
<div id="main"></div><script src="https://cdn.jsdelivr.net/npm/zrender@5.4.4/dist/zrender.min.js"></script>
<script>const zr = zrender.init(document.getElementById('main'));// 🛠️ === 全部配置集中在这里修改 ===const configList = [{points: [[100, 200], [300, 250], [600, 180]],color: '#00FFFF',speed: 2,radius: 8,tailLength: 0.1},{points: [[200, 500], [400, 400], [700, 480]],color: '#FF69B4',speed: .2,radius: 10,tailLength: 0.15},{points: [[150, 100], [250, 150], [350, 100], [500, 180]],color: '#FFD700',speed: 1.6,radius: 6,tailLength: 0.08}];const runners = [];for (const conf of configList) {const { points, color, speed, radius, tailLength } = conf;// 背景主路径const baseLine = new zrender.Polyline({shape: { points },style: {stroke: color,lineWidth: 2,opacity: 0.2}});zr.add(baseLine);// 尾巴线段const tailLine = new zrender.Polyline({shape: { points: [points[0], points[0]] },style: {lineWidth: 3,stroke: new zrender.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: color },{ offset: 1, color: 'rgba(0,0,0,0)' }])},z: 10});zr.add(tailLine);// 信号球体const ball = new zrender.Circle({shape: { cx: points[0][0], cy: points[0][1], r: radius },style: {fill: new zrender.RadialGradient(0.5, 0.5, 0.5, [{ offset: 0, color: '#fff' },{ offset: 1, color: color }]),shadowColor: color,shadowBlur: 12},z: 20});zr.add(ball);// 路径段长度计算const segmentLengths = [];let totalLength = 0;for (let i = 0; i < points.length - 1; i++) {const dx = points[i + 1][0] - points[i][0];const dy = points[i + 1][1] - points[i][1];const len = Math.sqrt(dx * dx + dy * dy);segmentLengths.push(len);totalLength += len;}runners.push({points,segmentLengths,totalLength,progress: 0,speed,ball,tailLine,tailLength});}// 帧动画:更新小球位置 & 尾巴拖影zr.animation.on('frame', () => {for (const runner of runners) {const { points, segmentLengths, totalLength, ball, tailLine, speed, tailLength } = runner;runner.progress += speed;if (runner.progress > totalLength) runner.progress = 0;let traveled = 0;for (let i = 0; i < segmentLengths.length; i++) {const len = segmentLengths[i];if (traveled + len >= runner.progress) {const t = (runner.progress - traveled) / len;const [x1, y1] = points[i];const [x2, y2] = points[i + 1];const x = x1 + (x2 - x1) * t;const y = y1 + (y2 - y1) * t;ball.attr('shape', { cx: x, cy: y });// 尾巴位置const tailT = Math.max(t - tailLength, 0);const tx = x1 + (x2 - x1) * tailT;const ty = y1 + (y2 - y1) * tailT;tailLine.attr('shape', { points: [[tx, ty], [x, y]] });break;}traveled += len;}}});
</script>
</body>
</html>

http://www.lryc.cn/news/584846.html

相关文章:

  • 飞算JavaAI:革新Java开发的智能助手
  • Linux kernel devm_gpiod_get()函数详解
  • 彻底解决JavaFx在Linux中文无法正常显示的问题(究其根本原因)
  • 飞书CEO谢欣:挑战巨头,打造AI新时代的Office
  • 锁的艺术:从Mutex到ReentrantLock,掌握并发编程的脉搏
  • 分布式系统高可用性设计-负载均衡与容错机制深度解析
  • Shader面试题100道之(81-100)
  • 模拟实现unordered_map
  • 如何使用 Python 删除 Excel 中的行、列和单元格 – 详解
  • 如何从0开始构建自己的第一个AI应用?(Prompt工程、Agent自定义、Tuning)
  • 格密码--数学基础--02基变换、幺模矩阵与 Hermite 标准形
  • AI金融风控:识别欺诈,量化风险的新利器
  • pandas销售数据分析
  • python 在 Linux CentOS 上安装 playwright 的完整步骤
  • Pandas:常见的转换函数(rename,set_index,reset_index)
  • MD2Doc转换器(基于Python)
  • [Reverse1] Tales of the Arrow
  • 飞算 JavaAI 深度体验:开启 Java 开发智能化新纪元
  • 闲庭信步使用图像验证平台加速FPGA的开发:第八课——图像数据的行缓存
  • Locust 负载测试工具使用教程
  • 为什么选择Selenium自动化测试?
  • [特殊字符]远程服务器配置pytorch环境
  • ajax和XMLHttpRequest以及fetch
  • STM32-DAC数模转换
  • day21——特殊文件:XML、Properties、以及日志框架
  • C#元组:从基础到实战的全方位解析
  • 实现在线预览pdf功能,后台下载PDF
  • 使用gdal读取shp及filegdb文件
  • 通过ETL工具,高效完成达梦数据库数据同步至数仓Oracle的具体实现
  • Primer Premier 5分子生物学引物设计软件 PCR引物设计工具