用 Canvas 绘制飞线
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用 Canvas 绘制飞线相关的知识,希望对你有一定的参考价值。
参考技术A 2016-05-12上一周完成了地图与飞线的实现,使用的是 d3.js + svg,后发现可能存在性能隐患。
当飞线数量多的时候,页面上则有多个 svg <path> 结点,并且每条飞线有头部、结束圆圈、蒙板等效果,则页面上的结点数是 飞线数*其他部件数。将会是一个较大的值。
画布罩在整个 html 上,共两层 Canvas 画布,底层绘制世界地图,表层绘制飞线。
二次贝塞尔曲线公式
(其中 起始点 p0, 控制点 p1, 终点 p2)
t 从 0 变到 1,每个 t 的变化时,就绘制一帧;
飞线的速度就取决于增量变化的大小,增量越小,动画就越细致。
如何表现 t ?
给每一个飞线对象单独一个 t 属性,每绘制完一帧,t = t + 增量(固定值);
requestAnimationFrame 动画
与 SVG 飞线 相比:
渐变消失: ctx.globalAlpha
使用 globalAlpha 和 临时 Canvas;
但有两个弊端:
模拟数据来源于B2B 外贸单日询盘量,总数共 596 条, 单次同时绘制 50 条 飞线情况下:
具体如下:
动画帧数保持在 42-60 左右,动画流畅;
动画帧数保持在 12-43 左右,视觉上仔细看略有卡顿;
CPU 占用率在 20%-30% 浮动
CPU 占用率高于 100%
皆无内存泄漏问题。 SVG 飞线的 JS heap 总大小略高于 Canvas 飞线。
测试了 Canvas 飞线,在同时绘 50 条、100 条、200 条、300 条、400 条 时的动画流畅度。
封装 用canvas绘制直线的函数--面向对象
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>用面向对象的思想 封装 在canvas绘制直线的函数</title> 6 </head> 7 <body> 8 <canvas id="cv"></canvas> 9 </body> 10 </html> 11 <script> 12 var cv = document.getElementById("cv"); 13 cv.width = 600; 14 cv.height = 300; 15 cv.style.border = "1px solid red"; 16 var ctx = cv.getContext("2d"); 17 18 //面向对象编程 19 //1 创建构造函数 20 //2 构造函数的原型设置 21 //3 调用的时候,通过 new+构造函数 来创建一个对象(实例) 22 23 //构造绘制直线的函数 24 function drawLine(parameters) { 25 this.init(parameters); 26 } 27 //替换原型对象实现继承 28 drawLine.prototype = { 29 constructor: drawLine, 30 init: function (parameters) { 31 this.ctx = parameters.ctx; 32 this.startX = parameters.points[0]; 33 this.startY = parameters.points[1]; 34 this.endX = parameters.points[2]; 35 this.endY = parameters.points[3]; 36 //以下3个属性,可以不设置,用短路运算实现添加默认属性值 37 this.lineWidth = parameters.lineWidth || 1; 38 this.lineDash = parameters.lineDash || []; 39 this.strokeStyle = parameters.strokeStyle || "#000"; 40 }, 41 //原型中,一般用来储存对象的方法或者共有的属性 42 stroke: function () { 43 this.ctx.beginPath(); 44 this.ctx.moveTo(this.startX, this.startY); 45 this.ctx.lineTo(this.endX, this.endY); 46 this.ctx.lineWidth = this.lineWidth; 47 this.ctx.setLineDash(this.lineDash); 48 this.ctx.strokeStyle = this.strokeStyle; 49 this.ctx.stroke(); 50 } 51 }; 52 53 //调用构造函数,传入参数 54 var line = new drawLine({ 55 ctx: ctx, 56 points: [100, 100, 300, 100], 57 lineDash: [4, 2], 58 strokeStyle: "red" 59 }); 60 line.stroke(); 61 var line2 = new drawLine({ 62 ctx: ctx, 63 points: [100, 200, 300, 200], 64 lineWidth: 6 65 }); 66 line2.stroke(); 67 </script>
效果图:
以上是关于用 Canvas 绘制飞线的主要内容,如果未能解决你的问题,请参考以下文章