Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >canvas绘制飞线效果

canvas绘制飞线效果

原创
作者头像
用户3158888
修改于 2020-11-11 06:18:47
修改于 2020-11-11 06:18:47
1.8K0
举报

在我们做的可视化大屏项目中,经常会遇到飞线的效果。 在我们的大屏编辑器中,可以通过拖拽+配置参数的方式很快就能够实现。下面是我们使用大屏编辑器实现的一个项目效果:

效果
效果

中间地图就有飞线的效果。

抛开编辑器的快速实现不说,我们大致来说下canvas绘制飞线的大致原理。

贝塞尔曲线

飞线的路径主要是一个贝塞尔曲线,canvas绘制贝塞尔曲线比较容易。canvas支持绘制二次和三次,在本次示例中,主要还是绘制二次贝塞尔曲线为主。canvas中指定二次贝塞尔曲线路径的函数如下:

代码语言:txt
AI代码解释
复制
ctx.quadraticCurveTo(cpx, cpy, x, y);

有关贝塞尔曲线的基础知识,读者可以自行学习,此处不再赘述。

渐变实现

从图中,可以看出飞线的效果是淡入的效果,颜色并不是一致的,起点处颜色很淡,终点处颜色就比较浓厚。

怎么样能够实现这种效果呢? 答案就是渐变,我们知道,canvas支持线性渐变和放射渐变。但是这两种渐变似乎都不太适合曲线的路径。

事实上,我们会考虑使用线性渐变。因为飞线效果中,曲线的弯曲程度都不太大,所以使用线性渐变,曲线造成的差异,人眼是感觉不出来的。

嗯嗯,图形学就是欺骗的艺术。

只要在线的起点和终点创建一个线性渐变,起点的颜色非透明度是0,终点的非透明度是1即可达到目标。

示例代码如下:

代码语言:txt
AI代码解释
复制
  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,周而复始。

代码如下:

代码语言:txt
AI代码解释
复制
        let percent = 0.0;       
        function render(){
            ctx.save();
            //按百分比绘制
            ctx.restore();
            percent += 0.005;
            if(percent > 1){
                percent = 0.;
            }
            requestAnimationFrame(render);
        }

问题的关键在于如何绘制贝塞尔曲线的一部分。 一种思路是使用二次贝塞尔曲线的公式,把曲线分成很多片段来进行模拟,然而这种方式的效率并不高。 其实可以使用插值的方式来获取一段贝塞尔曲线。代码如下:

代码语言:txt
复制
代码语言:txt
AI代码解释
复制
 // 参考https://xiaozhuanlan.com/topic/9506147283#section0t
代码语言:txt
AI代码解释
复制
        let P0 = startPoint, P1 = controlPoint,P2 = endPoint;
代码语言:txt
AI代码解释
复制
        let Q01 = interpolation(P0,P1,percent),
代码语言:txt
AI代码解释
复制
            Q11 = interpolation(P1,P2,percent),
代码语言:txt
AI代码解释
复制
            B1 = interpolation(Q01,Q11,percent);

function interpolation(P0,P1,t) {

代码语言:txt
AI代码解释
复制
        var Q = {
代码语言:txt
AI代码解释
复制
            x: P0.x * (1 - t) + P1.x * (t),
代码语言:txt
AI代码解释
复制
            y: P0.y * (1 - t) + P1.y * (t),
代码语言:txt
AI代码解释
复制
        };
代码语言:txt
AI代码解释
复制
        return Q;
代码语言:txt
AI代码解释
复制
    } 
代码语言:txt
AI代码解释
复制
#### 二次贝塞尔曲线
我们知道二次贝塞尔曲线有三个点P0、P1、P2。二次贝塞尔曲线的表达方程如下:
B(t) = (1-t)<sup>2</sup> * P0 + 2t(1-t) * P1 + t<sup>2</sup> * P2
其中: $t \in $[0,1]

借助上面一次贝塞尔曲线的计算方法,可以通过以下步骤来确定二次贝塞尔曲线的B(t)点:
* 选定 $t \in $[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就是在曲线上面点。上述过程如下图所示:

![二次贝塞尔曲线的计算方法过程](https://upload-images.jianshu.io/upload_images/6271001-773f3bc73bb803f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

从图中可以得出结论:
* 直线(Q0,Q1)和曲线相切于B点。

另外还有隐藏的结论:
* 曲线(P0,B)也是贝塞尔曲线,P0是曲线的起始点,B是曲线的终止点,而Q0是控制点
* 曲线(B,P2)也是贝塞尔曲线,B是曲线的起始点,P2是曲线的终止点,而Q1是控制点

上面两个结论会很有用,有了这个两个结论,前面“迭代(分片)”绘制部分贝塞尔的方法,可以用更加简单的方法替代,这在稍后详细说明。

如果将t的值从0过渡到1,不断计算点B,这些点的集合就可以组成一条二次贝塞尔曲线。下面图形动画复现了这个效果:
![二次贝塞尔曲线的计算方法过程](https://upload-images.jianshu.io/upload_images/6271001-f2133738c2ea60be.gif?imageMogr2/auto-orient/strip)





通过上面的方式,就可以绘制流动的飞线效果了,如下图所示:

![流动效果](https://upload-images.jianshu.io/upload_images/6271001-370710e91634ec07.gif?imageMogr2/auto-orient/strip)


## 加上阴影
默认线条的样式并不是很好看,如果加上阴影,可以让效果更加丰满。  加上阴影也很简单,代码如下:

ctx.shadowColor = 'rgba(255,0,255,1)';

ctx.shadowBlur = 5;

代码语言:txt
复制

最终的飞线效果参考下图:

效果
效果

结语

如果对可视化感兴趣,可以和我交流,微信541002349. 另外关注公众号“ITMan彪叔” 可以及时收到更多有价值的文章。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OpenGL ES 绘制贝塞尔曲线
最近要求为图像设计流线型曲线边框,想着可以用 OpenGL 绘制贝塞尔曲线,再加上模板测试来实现,趁机尝试一波。
字节流动
2020/06/02
1.4K0
Canvas入门到高级详解(中)
以上两个值都可以接受颜色名,16 进制数据,rgb 值,甚至 rgba. 一般先进行设置样式然后进行绘制。
老马
2019/05/25
2.1K0
AS3贝塞尔曲线类
贝塞尔曲线被广泛用于塔防类的游戏,当然一些特殊的缓动效果有些 也用 到这个 , 目前 这个没必要我们担心 , TweenMax 为我们提供了这些功能.
py3study
2020/01/07
5680
【Flutter 绘制与数学】探索线分支
一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。\n\n—\n\n##### 前情回顾:\n\n在上一篇 《Flutter 绘制番外篇 - 数学中的角度知识》 中,我们研究了两点连线的角度问题:\n\n
张风捷特烈
2022/05/09
4370
【Flutter 绘制与数学】探索线分支
游戏开发中的贝塞尔曲线,曲线和路径
贝塞尔曲线是自然几何形状的数学近似。我们使用它们来表示一条曲线,该曲线具有尽可能少的信息并具有很高的灵活性。
海拥
2021/08/23
1.3K0
数据可视化之下发图实践
随着互联网的快速发展,数据维度越来越广,呈现形式也越发丰富,具有多维度数据特点的相关业务实践都能通过可视化图表来展示,比如个推的下发图,从时间和区域两个维度,可以即时、直观地展现个推数据下发的过程。
个推
2019/04/18
1K0
数据可视化之下发图实践
可视化图表实现揭秘
1. 介绍 1.1 什么是数据可视化? 可视化是利用计算机图形学和图像处理技术,将数据转换成图形或者图像在屏幕上显示出来,再进行交互处理的理论、方法和技术。 数据可视化并不是简单的将数据变成图表,而是以数据为视角,看待世界。数据可视化就是将抽象概念形象化表达,将抽象语言具体化的过程。 1.2 为什么要用数据可视化 首先我们利用视觉获取的信息量绝对远远的比别的感官要多得多。 它能帮助分析的人对数据有更全面的认识,下面举个🌰 我们看下面几组数据: 对数据进行简单的数据分析,每组数据都有两个变量 X 和 Y,然
用户1097444
2022/06/29
1.3K0
可视化图表实现揭秘
一根飞线的故事-SVG篇
每年春运和双十一的统计图都因为有飞线动效才更加吸引眼球,今天我要为大家带来一根漂亮飞线要用什么姿势才能生成。
苏南
2020/12/16
1K0
一根飞线的故事-SVG篇
根据贝塞尔曲线上的点反算t值
这是一个项目中遇到的实际需求。 场景是一个智能仓库管理系统,场景里面有直线和曲线构成的环穿轨道。环穿轨道上面会有小车运动,后台推动小车的两个点位A和B,其中A和B都会在轨道上面,前端需要根据这两个推送点,自动播放小车从A点沿轨道到B点的动画。下面是项目截图:
用户3158888
2019/10/09
2.2K0
根据贝塞尔曲线上的点反算t值
第157天:canvas基础知识详解
    github地址: https://github.com/malun666/AndyJS2
半指温柔乐
2018/09/11
5.4K0
第157天:canvas基础知识详解
OpenGL 实践之贝塞尔曲线绘制
说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图。
音视频开发进阶
2019/08/23
1.8K0
OpenGL 实践之贝塞尔曲线绘制
【基础系列】Canvas专题
        为了在canvas上绘制,你必须先得到一个画布上下文对象的引用,用本方法即可完成这一操作,格式如下:
江中散人_Jun
2023/10/16
5180
【基础系列】Canvas专题
H5和微信小游戏 Canvas API 整理前言
这段时间闲下来,系统学习了微信小程序和微信小游戏,发现还是挺有意思的。现在微信小游戏的开发都离不开游戏引擎,用原生小游戏开发工具开发的很少很少。但是毕竟我不是专业游戏开发,所有游戏引擎就不搞了,我们就单纯来看原生微信小游戏开发。
大公爵
2018/10/10
3.1K0
H5和微信小游戏 Canvas API 整理前言
Android之贝赛尔曲线及其应用场景
导语 本文对贝赛尔曲线的公式及推导过程进行了深入学习,同时结合网上的资料,整理了一些其常用的应用场景。 前段时间做送礼动画需求的时候遇到送礼轨迹需要平滑的要求,因此对常用的平滑轨迹贝赛尔曲线进行了
MelonTeam
2018/01/04
1.8K0
Android之贝赛尔曲线及其应用场景
canvas绘图基本使用方法(二)
转载至博客http://blog.csdn.net/u014607184/article/details/51746384 诗渊
javascript艺术
2021/05/28
8640
canvas绘图基本使用方法(二)
使用Bezier曲线移动
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
keyle
2024/11/01
1970
使用Bezier曲线移动
用SVG实现一个优雅的提示框
Tooltips常被称为提示框(或信息提示框),提示框能够以较强的交互性、自由度为用户提供相应的提示信息。今天我们要聊的不是如何实现强大的交互行为,而是来看看如何以最好的方式来还原他们的视觉效果,并且能适用于不同的场景。
ConardLi
2020/06/10
2.7K0
用SVG实现一个优雅的提示框
Android绘图最终篇之大战贝塞尔三次曲线
零、前言 1.可以说贝塞尔曲线是一把 "石中剑",能够拔出它,会让你的绘图如虎添翼。 2.今天要与贝塞尔曲线大战三百回合,将它加入我的绘图大军麾下。 3.自此Android绘图五虎将:Canvas,Path,Paint,Color,贝塞尔便集结完成。 4.本项目源码见文尾捷文规范第一条,视图源码在view包,分析工具在analyze包 ---- 一、贝塞尔三次曲线初体验 1.无网格,不曲线,废话不多说,上网格+坐标系 /** * 作者:张风捷特烈<br/> * 时间:2018/11/16 0
张风捷特烈
2018/11/21
8170
震惊,canvas文字粒子效果,只需要100行代码,简单易懂。
1.了解一下基本的canvas的Api,像画点,画圆,以及填充颜色等等。2.文字打碎,记录每个文字所在画布中的位置,本文的重点。3.生成随机粒子,并且设置每个粒子的运动轨迹。4.移动到步骤二记录下来位置。5.使用requestAnimationFrame来绘制每一帧的画布
苏南
2020/12/16
1.2K0
震惊,canvas文字粒子效果,只需要100行代码,简单易懂。
【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现
  RT,马三最近在参与一款足球游戏的开发,其中涉及到足球的各种运动轨迹和路径,比如射门的轨迹,高吊球,香蕉球的轨迹。最早的版本中马三是使用物理引擎加力的方式实现的足球各种运动,后来的版本中使用了根据物理学公式手动计算位置和物体速度的方式实现,现在这个版本中使用的是DoTween+贝塞尔曲线调节来实现。(关于它们之间的各种优缺点我们会在以后单独开一篇博客来探讨,届时也会放出源代码互相学习下)好了,言归正传,今天马三就来和大家一起学习一下游戏中的贝塞尔曲线以及其在Unity中如何实现。
马三小伙儿
2018/09/12
4.6K0
【Unity3d游戏开发】游戏中的贝塞尔曲线以及其在Unity中的实现
相关推荐
OpenGL ES 绘制贝塞尔曲线
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档