canvas 绘制直线 并选中_canvas绘制飞线效果
在我们做的可视化大屏项目中,经常会遇到飞线的效果。 在我们的大屏编辑器中,可以通过拖拽+配置参数的方式很快就能够实现。下面是我们使用大屏编辑器实现的一个项目效果:
效果
中间地图就有飞线的效果。
抛开编辑器的快速实现不说,我们大致来说下canvas绘制飞线的大致原理。
贝塞尔曲线
飞线的路径主要是一个贝塞尔曲线,canvas绘制贝塞尔曲线比较容易。canvas支持绘制二次和三次,在本次示例中,主要还是绘制二次贝塞尔曲线为主。canvas中指定二次贝塞尔曲线路径的函数如下:
ctx.quadraticCurveTo(cpx, cpy, x, y);
有关贝塞尔曲线的基础知识,读者可以自行学习,此处不再赘述。
渐变实现
从图中,可以看出飞线的效果是淡入的效果,颜色并不是一致的,起点处颜色很淡,终点处颜色就比较浓厚。
怎么样能够实现这种效果呢? 答案就是渐变,我们知道,canvas支持线性渐变和放射渐变。但是这两种渐变似乎都不太适合曲线的路径。
事实上,我们会考虑使用线性渐变。因为飞线效果中,曲线的弯曲程度都不太大,所以使用线性渐变,曲线造成的差异,人眼是感觉不出来的。
嗯嗯,图形学就是欺骗的艺术。
只要在线的起点和终点创建一个线性渐变,起点的颜色非透明度是0,终点的非透明度是1即可达到目标。
示例代码如下:
function createGradient(ctx,p0,p1){var grd = ctx.createLinearGradient(p0.x,p0.y,p1.x,p1.y);grd.addColorStop(0,'rgba(255,0,255,0)');grd.addColorStop(1,'rgba(255,0,255,1)');return grd;}ctx.beginPath();ctx.moveTo(P0.x,P0.y);ctx.quadraticCurveTo(Q01.x,Q01.y,B1.x,B1.y);ctx.lineCap = 'round';ctx.lineWidth =3;ctx.strokeStyle = createGradient(ctx,P0,P2);ctx.shadowColor = 'rgba(255,0,255,1)';ctx.shadowBlur = 5;ctx.stroke();
渐变效果
流动效果
流动效果就是线条从起点开始,慢慢飞到终点的效果。 技术角度来说,就是绘制二次曲线百分之几的一部分,百分比的数值从0增加到1,然后又回到0,周而复始。
代码如下:
let percent = 0.0; function render(){ctx.save();//按百分比绘制ctx.restore();percent += 0.005;if(percent > 1){percent = 0.;}requestAnimationFrame(render);}
问题的关键在于如何绘制贝塞尔曲线的一部分。 一种思路是使用二次贝塞尔曲线的公式,把曲线分成很多片段来进行模拟,然而这种方式的效率并不高。 其实可以使用插值的方式来获取一段贝塞尔曲线。代码如下:
// 参考https://xiaozhuanlan.com/topic/9506147283#section0tlet P0 = startPoint, P1 = controlPoint,P2 = endPoint;let Q01 = interpolation(P0,P1,percent),Q11 = interpolation(P1,P2,percent),B1 = interpolation(Q01,Q11,percent);
function interpolation(P0,P1,t) {var Q = {x: P0.x * (1 - t) + P1.x * (t),y: P0.y * (1 - t) + P1.y * (t),};return Q;}
有关上面插值的原理,可以参考下面的说明,摘取字文章:https://xiaozhuanlan.com/topic/9506147283#section-5
二次贝塞尔曲线
我们知道二次贝塞尔曲线有三个点P0、P1、P2。二次贝塞尔曲线的表达方程如下:
B(t) = (1-t)2 * P0 + 2t(1-t) * P1 + t2 * P2
其中: t 在0~1之间
借助上面一次贝塞尔曲线的计算方法,可以通过以下步骤来确定二次贝塞尔曲线的B(t)点:
- 选定 t [0,1]
- 通过插值运算法则,在P0和P1所组成的线段上,计算出P0和P1点之间的插值点Q0,其中插值的比例值是t。根据插值规则有:length( P0, Q0 ) = length( P0, P1 ) * t
- 通过插值运算法则,在P1和P2所组成的线段上,计算出P1和P2点之间的插值点Q1,其中插值的比例是t。
- 通过插值运算法则,在Q1和Q2所组成的线段上,计算出P1和P2点之间的插值点B,其中插值的比例是t。
上述过程中计算出来的点B就是在曲线上面点。上述过程如下图所示:
二次贝塞尔曲线的计算方法过程
从图中可以得出结论:
- 直线(Q0,Q1)和曲线相切于B点。
另外还有隐藏的结论:
- 曲线(P0,B)也是贝塞尔曲线,P0是曲线的起始点,B是曲线的终止点,而Q0是控制点
- 曲线(B,P2)也是贝塞尔曲线,B是曲线的起始点,P2是曲线的终止点,而Q1是控制点
上面两个结论会很有用,有了这个两个结论,前面“迭代(分片)”绘制部分贝塞尔的方法,可以用更加简单的方法替代,这在稍后详细说明。
如果将t的值从0过渡到1,不断计算点B,这些点的集合就可以组成一条二次贝塞尔曲线。下面图形动画复现了这个效果:
二次贝塞尔曲线的计算方法过程
通过上面的方式,就可以绘制流动的飞线效果了,如下图所示:
流动效果
加上阴影
默认线条的样式并不是很好看,如果加上阴影,可以让效果更加丰满。 加上阴影也很简单,代码如下:
ctx.shadowColor = 'rgba(255,0,255,1)';ctx.shadowBlur = 5;
最终的飞线效果参考下图:
效果
结语
如果对可视化感兴趣,可以和我交流,微信541002349. 如果你对我们的大屏编辑器产品或者3d组态编辑器感兴趣,可以加我微信交流,或者发邮件也可以,terry.tan@servasoft.com。 另外关注公众号“ITMan彪叔” 可以及时收到更多有价值的文章。
canvas 绘制直线 并选中_canvas绘制飞线效果相关推荐
- canvas绘制飞线效果
在我们做的可视化大屏项目中,经常会遇到飞线的效果. 在我们的大屏编辑器中,可以通过拖拽+配置参数的方式很快就能够实现.下面是我们使用大屏编辑器实现的一个项目效果: 中间地图就有飞线的效果. 抛开编辑器 ...
- echart实现3d地图_3D飞线效果——让线“飞”起来的秘密
在城市规划.统计.交通等行业,地图可视化已成为最直接也最吸引眼球的一种表达方式.例如人群迁徙.人口流动.OD出行.职住分析.客流来源等众多场景都需要用到飞线效果呈现. 2D飞线效果图 随着可视化技术的 ...
- shader实现飞线效果(three.js练习)
一.先看看效果 二.实现方法: 1.飞线的相关配置数据准备 // 飞线效果的相关配置数据 const flyData = [{start: { //起始点位置x: 0,y: 0,z: 0},end: ...
- Echarts实现3d 地图实现飞线效果
Echarts实现3d 地图实现飞线效果 注意:重点关注data中的数据格式 在lines3D中symbol不能设置指定样式,echarts官网也没有这个参数,所以对于lines3D飞线如何实现飞机航 ...
- canvas 绘制直线 并选中_在画布中使用路径-Canvas的基本操作
一.在画布中使用路径 beginPath() 新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径moveTo(x, y) 把画笔移动到指定的坐标(x, y).相当于设置路径的起始点坐标 ...
- canvas 绘制直线 并选中_javascript自学记录:canvas绘图
由于学习js是为爬虫服务,所以canvas绘图学习并不完整. 第15章 使用Canvas绘图 15.1 基本用法 HTML文件中需要有canvas元素,两标签之间的文字是浏览器不支持时显示的. A d ...
- C# 画(绘制)直线 C#如何画直线 C#绘制直线 WPF 画(绘制)直线
C#画直线 1.winform 使用的是 Graphics private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g ...
- python如何绘制直线_成对绘制直线
我正在做一个网络项目,在这个项目中,我需要在成对的点(节点)之间绘制线(边).目前我正在使用matplotlib.pyplot但问题是pyplot.plot绘图(x,y)从(x[0],y[0])开始, ...
- html怎么绘制飞线,绘制飞线,echarts迁徙图原理
其实是在元素上绘制了一条线,然后利用canvas 的createLinearGradient函数不断移动线段的样式位置来实现. 因此首先绘制线段 ctx.beginPath(); ctx.moveTo ...
- - Canvas 简介- 使用 Canvas 绘制图形- Canvas 常用方法- SVG 简介- 使用 SVG 绘制基本图形
1 Canvas 简介 Canvas 表示画布,现实生活中的画布是用来作画的. HTML5 中的 Canvas :我们可以称它为"网页中的画布".默认情况下,Canvas 是一块 ...
最新文章
- OCA读书笔记(6) - 配置Oracle网络环境
- ECSHOP删除云服务
- 用AI分析食物成分,让你能更好地进行营养搭配!
- altium designer 原理图和PCB 多通道设计
- ACM_逆序数(归并排序)
- 涉及CDI和JSF的过期对话的定制错误页面
- 天然气表怎么看多少方_上海考大学难度怎么样?看2019上海高考“成绩分布表”和“本科分数线”就知道了!...
- django 定制admin
- 微信JS-SDK项目学习 --实现分享样式控制thinkphp
- pp助手苹果版本_曾经iOS一代越狱神奇器,PP助手宣布凉凉
- VSCode安装教程详细简单版
- 在 vue 中基于 tinymce 封装的一个富文本编辑器组件
- ASC19 初赛要求自翻译
- Android-SEAndroid权限问题指南
- 网站推广优化教程100条(完整版)-
- 2021年饶州中学高考成绩查询,鄱阳饶州中学2019高考成绩喜报、一本二本上线人数情况...
- Foo,getName题解分析
- 流程图用什么软件做?这篇文章告诉你(内附详细教程)
- stm32 cubemx 新建项目一直报错的问题终于解决了
- IT攻城狮常用英文-数据结构篇