canvas教程

JSP_strut2架构下前台使用canvas对接收到的后台数据画图的一种

字号+ 作者:H5之家 来源:H5之家 2017-07-16 17:15 我要评论( )

前台使用canvas根据后台传入的数据画图session;java;jsp;jQuery;javascript;HTML5;canvas;需求介绍:后台传入节点个数,结点间的连线关系,节点名称等,前台模拟

前台使用canvas根据后台传入的数据画图

session; java; jsp; jQuery; javascript; HTML5; canvas;

需求介绍:

后台传入节点个数,结点间的连线关系,节点名称等,前台模拟后台算法动态演示连线过程,最后根据后台传过来的连线
关系绘制最终的结点间连线结果。细节要求,根据后台传入节点个数绘制节点,节点圆形分布。

对HTML5 canvas的一点理解
在画的图像比较复杂的情况下,建议使用多层画布,比如我,就是每个功能模块都单独设置一层画布。还有一点,就是stroke()十分耗费资源,如果不是特别需要,最后统一调用stroke函数,不要每次都调用。

功能划分与具体代码 变量初始化模块 <html> <script> //接收aaa数据,并处理之 var aaa="${aaa}"; testSet=aaa.split("-"); var node_set="${node_set}"; node_name_set=node_set.split("-");//节点名集合 //alert(node_name_set); //alert(node_name_set.length); //alert(node_name_set[0]); for(var i=0;i<testSet.length;i++) for(var j=0;j<node_name_set.length;j++) if(testSet[i]==node_name_set[j]) testSet[i]=j; //接收bbb数据,并处理之 var bbb="${bbb}"; dirTestSet=bbb.split("-"); //alert(dirTestSet); for(var i=0;i<dirTestSet.length;i++) for(var j=0;j<=node_name_set.length;j++) if(dirTestSet[i]==node_name_set[j]) dirTestSet[i]=j; //建立最底层画布canvas0/ctx0 var canvas0 = document.getElementById("canvas"); var canvasWidth = canvas0.width; var canvasHeight = canvas0.height; var ctx0 = canvas0.getContext("2d"); //初始化中间变量及其他 var x = new Array(); var y = new Array(); var testSetLength = testSet.length-1; var dirTestSetLength = dirTestSet.length-1; var dgr=0; var r=200;//设置圆弧半径 var n="${count}";//取出节点个数 var mx = 300; // 圆弧的中心点 x 坐标 var ny = 300; // 圆弧的中心点 y 坐标 </script> </html> 节点初始化模块 <html> <script> //初始化节点的位置 function initNodes(x,y,n){ for(var i = 0; i < n;i++) { x.push(0); y.push(0); } } //自动设定节点位置 function gyNodeSets(x,y,n){ var dgrInterval=Math.floor(360/n);//每两个节点之间增加的角度 while(n!=0){(Copyright All Rights Reserved) dgr+=dgrInterval;//每次加完节点后增加度数 for(var i = 0; i < n; i++) { x[i] = mx+Math.sin( dgr*Math.PI/180 ) * r; y[i] = ny+Math.cos( dgr*Math.PI/180 ) * r; } n--; } } //节点绘制 function drawNodes(x,y,n) { for(var i = 0; i < n; i++) { ctx0.beginPath(); ctx0.fillStyle = "#06a8f3"; ctx0.strokeStyle = "#000"; ctx0.lineWidth = 0.5; ctx0.arc(x[i], y[i], 6, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false); ctx0.fill(); ctx0.stroke(); ctx0.font = "normal 16px Arial"; ctx0.fillStyle="#000"; ctx0.textAlign="left"; ctx0.fillText(node_name_set[i],x[i],y[i]); ctx0.closePath(); } } </script> </html> 带箭头线条绘制模块 <html> <script> //canvas无箭头线标准函数,所以sgy我自己写一个函数,不过网上有不少参考,直接顶点坐标+角度+起点坐标+箭头短线长度就搞定了 function drawArrow(ctx, fromX, fromY, toX, toY,theta,headlen,width,color){ theta = typeof(theta) != 'undefined' ? theta : 30; headlen = typeof(theta) != 'undefined' ? headlen : 10; width = typeof(width) != 'undefined' ? width : 1; color = typeof(color) != 'color' ? color : '#000'; // 计算各角度和对应的P2,P3坐标 var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, angle1 = (angle + theta) * Math.PI / 180, angle2 = (angle - theta) * Math.PI / 180, topX = headlen * Math.cos(angle1), topY = headlen * Math.sin(angle1), botX = headlen * Math.cos(angle2), botY = headlen * Math.sin(angle2); ctx.save(); ctx.beginPath(); var arrowX = fromX - topX, arrowY = fromY - topY; ctx.moveTo(arrowX, arrowY); ctx.moveTo(fromX, fromY); ctx.lineTo(toX, toY); arrowX = toX + topX; arrowY = toY + topY; ctx.moveTo(arrowX, arrowY); ctx.lineTo(toX, toY); arrowX = toX + botX; arrowY = toY + botY; ctx.lineTo(arrowX, arrowY); ctx.strokeStyle = color; ctx.lineWidth = width; ctx.stroke(); ctx.restore(); } </script> </html> 动态画图演示模块 <html> <script> //应用技术为setInterval,定时执行代码,结束条件自动为到达数组末尾。 //javascript的定时器与循环有难以解释的逻辑冲突,或者说是sgy我暂时没深入想的编写失误,反正每次把定时器和循环写在一起必然得不出想要实现的结果。后面我会再写一篇博客来详细展示javascript中的两个定时器的用法与区别。 setInterval("dynamicDrawLines_1(x,y,n)",300); var i1=1; function dynamicDrawLines_1(x,y,n){ var itvl=1;(Copyright All Rights Reserved) var canvas1 = document.getElementById("canvas"); var ctx1 = canvas1.getContext("2d"); ctx1.beginPath(); ctx1.strokeStyle="#FFA500";//orange ctx1.moveTo(x[i1],y[i1]); ctx1.lineTo(x[i1+itvl],y[i1+itvl]); ctx1.stroke(); ctx1.closePath(); itvl++; i1++; } setInterval("dynamicDrawLines_2(x,y,n)",300); var i2=1; function dynamicDrawLines_2(x,y,n){ var itvl=1; var canvas2 = document.getElementById("canvas"); var ctx2 = canvas2.getContext("2d"); ctx2.beginPath(); ctx2.strokeStyle="#00FF00";//green ctx2.moveTo(x[i2],y[i2]); //ctx2.lineTo(x[i2+2],y[i2+2]); ctx2.lineTo(x[i2+itvl+1],y[i2+itvl+1]); ctx2.stroke(); ctx2.closePath(); itvl++; i2++; } </script> </html> 清理画布模块 <html> <script> //应用到的技术是xor //多次调用setTimeout函数实现伪动态清理 setTimeout("xorLines(x,y,n)",n*500); setTimeout("xorLines(x,y,n)",n*500+500); function xorLines(x,y,n){ (Copyright All Rights Reserved) var canvas9 = document.getElementById("canvas"); var ctx9 = canvas9.getContext("2d"); for(var i = 2;i<n;i++){ for(var j=i+1;j<=n;j++){ ctx9.beginPath(); ctx9.strokeStyle="#FFFFFF"; ctx9.globalCompositeOperation="xor"; ctx9.moveTo(x[i],y[i]); ctx9.lineTo(x[j],y[j]); ctx9.stroke(); ctx9.closePath(); } } } </script> </html> 最终结果之无向图模块 <html> <script> function drawUndirResult(x,y,testSet){ var canvas10 = document.getElementById("canvas"); var ctx10 = canvas10.getContext("2d"); for(var i = 0;i<testSetLength/2;i++){ ctx10.beginPath();(Copyright All Rights Reserved) ctx10.strokeStyle="#00008B"; ctx10.lineWidth="1.5"; var tmp_x = testSet[i] //alert(testSet[i]); //alert("tmp_x="+tmp_x); var tmp_y = testSet[(i+(testSetLength/2))] //alert("tmp_y="+tmp_y); // ctx10.moveTo(x[parseInt(testSet[i])],y[parseInt(testSet[i])]); // ctx10.lineTo(x[testSet[parseInt(i+(testSet.length/2))]],y[testSet[parseInt(i+(testSet.length/2))]]); ctx10.moveTo(x[tmp_x],y[tmp_x]); ctx10.lineTo(x[tmp_y],y[tmp_y]); ctx10.stroke(); ctx10.closePath(); } } </script> </html> 最终结果之有向图模块 <html> <script> function drawDirResult(x,y,dirTestSet){ var canvas11 = document.getElementById("canvas"); var ctx11 = canvas11.getContext("2d"); for(var i = 0;i<dirTestSetLength/2;i++){ (Copyright All Rights Reserved) ctx11.beginPath(); ctx11.strokeStyle="#000"; ctx11.lineWidth="1.5"; var tmp_x = dirTestSet[i] //alert("tmp_x="+tmp_x); var tmp_y = dirTestSet[(i+(dirTestSetLength/2))] drawArrow(ctx11, x[tmp_x],y[tmp_x],x[tmp_y],y[tmp_y],15,15,2,'#f36'); ctx11.closePath(); } } </script> </html>

最终的效果demo,gif图片的形式呈现:(Copyright All Rights Reserved)

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 微信小程序全面实战,架构设计 躲坑攻略

    微信小程序全面实战,架构设计 躲坑攻略

    2017-01-11 08:00

  • 在android中画圆形图片的几种办法

    在android中画圆形图片的几种办法

    2016-09-29 11:00

  • Guichan架构分析

    Guichan架构分析

    2015-10-16 11:06

  • 03. Canvas简介,Canvas的使用方法

    03. Canvas简介,Canvas的使用方法

    2015-09-29 18:00

网友点评
m