canvas绘制折线路径动画
最近有读者加我微信咨询这个问题:

其中的效果是一个折线路径动画效果,如下图所示:

要实现以上路径动画,一般可以使用svg的动画功能。或者使用canvas绘制,结合路径数学计算来实现。
如果用canvas来绘制,其中的难点在于:
- 需要计算子路径,这块计算比较复杂。(当然是可以实现的)
- 渐变的计算, 从图中可以看出,动画的子路径是有渐变效果的,如果要分段计算渐变也很复杂。
本文介绍一种思路,使用clip方法,动态移动clip的区域,来达到近似的效果。具体怎么做。
绘制灰色路径
绘制路径的代码比较简单,此处就不详细说明,下面代码就模拟了了一个折线路径的绘制:
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(230,200);
ctx.lineTo(250,50);
ctx.lineTo(270,180);
ctx.lineTo(300,60);
ctx.lineTo(330,160);
ctx.lineTo(350,60);
ctx.lineTo(380,100);
ctx.lineTo(480,100);
ctx.strokeStyle = "gray";
ctx.lineJoin = "round";
ctx.stroke();
效果如下:

绘制亮色路径
绘制亮色路径的代码和绘制灰色路径的代码一样,只是样式是一个亮的颜色:
ctx.save();
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(230,200);
ctx.lineTo(250,50);
ctx.lineTo(270,180);
ctx.lineTo(300,60);
ctx.lineTo(330,160);
ctx.lineTo(350,60);
ctx.lineTo(380,100);
ctx.lineTo(480,100);
ctx.strokeStyle = "gray";
ctx.lineJoin = "round";
ctx.stroke();
效果如下:

clip控制亮色路径的绘制区域
canvas的clip方法可以控制绘制的区域,通过该方法,可以控制智绘制路径的一部分:
ctx.beginPath();
ctx.rect(offset,0,100,500); // offset 等于0
ctx.clip();
...
ctx.stroke();
clip之后,亮色路径就只会绘制一部分,如下图:

动画效果
通过不断变化offset的值,就可以大道亮色路径移动的效果,代码如下:
offset += 2;
if(offset > 600){
offset = 100;
}
requestAnimationFrame(animate);
最终效果如下:

渐变
我们知道渐变没法沿着任意路径,如果计算折线,分段计算渐变又很麻烦。 其实在本案例中,虽然是折线,但是整体的运动方向总是从左往右的,所以可以用从左往右的渐变来近似模拟既可以:
function createGradient(ctx,x0,y0,x1,y1){
var grd = ctx.createLinearGradient(x0,y0,x1,y1);
grd.addColorStop(0,'#129ab3');
grd.addColorStop(1,"#19b5fe");
return grd;
}
ctx.strokeStyle = createGradient(ctx,offset,0,offset + 100,0);
最终效果如下所示:

全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>line animate</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
var ctx = document.getElementById( 'canvas' ).getContext( '2d' );
var w = canvas.width,
h = canvas.height;
var x = w / 2,y = h / 2;
function setupCanvas(canvas) {
let width = canvas.width,
height = canvas.height,
dpr = window.devicePixelRatio || 1.0;
if (dpr != 1.0 ) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * dpr;
canvas.width = width * dpr;
ctx.scale(dpr, dpr);
}
}
setupCanvas(canvas);
var offset = 100;
function createGradient(ctx,x0,y0,x1,y1){
var grd = ctx.createLinearGradient(x0,y0,x1,y1);
grd.addColorStop(0,'#9a12b3');
grd.addColorStop(1,"#19b5fe");
return grd;
}
function animate(){
ctx.fillStyle = "black";
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.lineWidth = 3;
ctx.save();
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(230,200);
ctx.lineTo(250,50);
ctx.lineTo(270,180);
ctx.lineTo(300,60);
ctx.lineTo(330,160);
ctx.lineTo(350,60);
ctx.lineTo(380,100);
ctx.lineTo(480,100);
ctx.strokeStyle = "gray";
ctx.lineJoin = "round";
ctx.stroke();
ctx.beginPath();
ctx.rect(offset,0,150,500);
ctx.clip();
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(230,200);
ctx.lineTo(250,50);
ctx.lineTo(270,180);
ctx.lineTo(300,60);
ctx.lineTo(330,160);
ctx.lineTo(350,60);
ctx.lineTo(380,100);
ctx.lineTo(480,100);
ctx.lineWidth = 4;
ctx.strokeStyle = createGradient(ctx,offset,0,offset + 150,0);
ctx.lineCap = "round";
// ctx.globalCompositeOperation = 'lighter';
ctx.lineJoin = "round";
ctx.stroke();
ctx.restore();
offset += 2;
if(offset > 600){
offset = 100;
}
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
总结
其实整体思路是用了近似,而不是严格的控制路径长度和渐变效果,这样可以更方便实现以上功能。 其实人眼有时候是分辨不出来一些细节,可视化,有的时候只有能够达到让人“觉得”是那么回事,其实目的也就达到了。
以上方案只能适用于,折线路径的整体方向是一致的。如果整体方向是先水平向右,然后在垂直向下,或者甚至出现往回拐的情况,就不适合了。
关注公众号“ITMan彪叔” 可以及时收到更多有价值的文章。另外如果对可视化感兴趣,可以和我交流,微信541002349.
canvas绘制折线路径动画的更多相关文章
- ArcGIS API for Silverlight 绘制降雨路径动画
原文:ArcGIS API for Silverlight 绘制降雨路径动画 #region 降雨动画演示 2014-04-16 List<Graphic> graphics = new ...
- 用canvas绘制折线图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android自己定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了非常多插件,可是非常多时候我们须要依据详细项目自己定义这些图表,这一篇文章我们一起来看看怎样在Android中使用Can ...
- 第165天:canvas绘制圆环旋转动画
canvas绘制圆环旋转动画——面向对象版 1.HTML 注意引入Konva.js库 <!DOCTYPE html> <html lang="en"> &l ...
- Android自定义控件 -Canvas绘制折线图(实现动态报表效果)
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...
- Android自定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...
- canvas绘制折线图
效果图: 重难点: 1.画布左上角的顶点的坐标为(0 ,0),右下角的坐标最大,与平常思维相反 2.数据的处理 html代码: <!DOCTYPE html><html lang=& ...
- HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)
看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现:虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难 ...
- canvas绘制折线图(仿echarts)
遇到的问题:Retina屏上字体线条模糊问题 解决方案:放大canvas的大小,然后用css压缩回原大小,例如:想要900*400的画布,先将画布设置为 width="1800px" ...
随机推荐
- 【linux】驱动-2-内核模块
目录 前言 2. 内核模块 2.1 内核模块概念 2.1.1 内核 2.1.2 内核模块机制的引入 2.2 内核模块 2.2.1 内核模块参考例程 2.2.2 内核模块命令 2.2.3 系统自动加载模 ...
- 使用C# (.NET Core) 实现装饰模式 (Decorator Pattern) 并介绍 .NET/Core的Stream
该文章综合了几本书的内容. 某咖啡店项目的解决方案 某咖啡店供应咖啡, 客户买咖啡的时候可以添加若干调味料, 最后要求算出总价钱. Beverage是所有咖啡饮料的抽象类, 里面的cost方法是抽象的 ...
- Java中的映射Map - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的映射Map - 入门篇>,希望对大家有帮助,谢谢 简介 前面介绍了集合List,这里开始简单介绍下映射Map,相关类如下图所示 正 ...
- nsqlookupd:高性能消息中间件 NSQ 解析
摘要:本篇将会结合源码介绍 nsqlookupd 的实现细节. 本篇将会结合源码介绍 nsqlookupd 的实现细节.nsqlookupd 主要流程与nsqd 执行逻辑相似,区别在于具体运行的任务不 ...
- ionic3+angular 倒计时效果
// 声明变量 applicationInterval: any; // 定时器 nextBtnText: String; nextBtnBool: Boolean; // 使用定时器,每秒执行一次 ...
- [Fundamental of Power Electronics]-PART II-8. 变换器传递函数-8.2 变换器传递函数分析
8.2 变换器传递函数分析 接下来,让我们推导基本变换器传递函数中的极点,零点和渐近线增益的解析表达式. 8.2.1 示例:Buck-boost变换器的传递函数 Buck-boost变换器的小信号等效 ...
- 【软件推荐】使用Cmder替换Windows自带的控制台
安装地址 进入cmder官网,下载相应版本. 如果本地已经安装了git,可以选择mini版本. 将 λ 替换为 $ 当前cmder默认的提示符是λ,看上去总是有点不习惯. 打开cmder目录下的ven ...
- OO第三单元个人总结
OO第三单元个人总结 JML理论与基础与应用工具链 JML是什么? Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约设计方法 和Larch ...
- oo第四单元——UML图解析
本单元是在理解UML图的基础上实现对图的解析和检查.UML图是新接触的一种建模工具,一开始接触UML的时候觉得理解起来比较困难,并不能单纯从代码的角度按照类.方法这样来理解,这只是从类图的角度,还有从 ...
- XSS-change通关历程
Level1:没有过滤. <script>alert(1)</script> <svg/onload=alert(1)> <script>confirm ...