手把手教你用canvas画动态直线

来源:互联网 发布:sql 2008 sa 默认密码 编辑:程序博客网 时间:2024/05/09 01:49

自己闲来无事的时候,就想学学热火了好久的H5

然后就看了下canvas

不看不知道,一看下一条,H5我以为没啥,原来都开始提供各种接口和函数了,我滴乖乖

canvas主要是用来画图的,结合定时器(setInterval)函数能够作出精美的动画

下面我就简单的给大家介绍下canvas怎么使用

vanvas的介绍这里就不多说了,大家可以自行百度。


1.jsp页面

首先,jsp页面很简单

<body><div class="container">输入汉字<input id="inputSomeThing" oninput="getInput(this.value)"></input>输入个数<input id="numOfTranIO"></input><input onclick="draw()" value="生成" type="button" /><canvas id="myCanvas" width="1150" height="500"style="border:1px solid #000000;"></canvas><input onclick="draw()" value="111" type="button" /></div></body>

我们添加了一个输入汉字的input和一个输入个数的input,还有一个id为myCanvas的画布

2.js部分

首先看js代码第一部分

2.1 全局变量

全局变量定义如下所示

var ctx;//全局的画布标识var width=1150; //设置线条获得区域宽度var height=500; //设置线条获得区域高度var x; //设置线条起点var i = 0; //记录线条长度var exp=1; //设置线条每次移动像素大小var string;//用来存储用户输入的值var tranIOLenth; //第二段横线之间的间隔var tranIOZuoBiao = {}; //用来存储第二段横线的起始点坐标,用map形式存储var tnumOfTranIO; //保存第二段输入的值的个数
每个参数的代表的含义如注释所示

2.2 document.ready

页面初始化,当加载完成后,获取画布信息,并初始化一些参数

$(document).ready(function(){/*var numOfTranIO = 4;*/var c=document.getElementById("myCanvas");ctx=c.getContext("2d");ctx.strokeStyle = "blue"; //定义颜色});

2.3 监控用户输入

当用户在输入汉字的时候,调用了oninput里定义的getInput()方法,实现如下

function getInput(something){string = something;ctx.clearRect(0,0,width,height); ctx.textBaseline="middle"; ctx.font="30px sans-serif";ctx.fillText(something,10,250);x = ctx.measureText(something).width+10;}
这样就实现了,用户输入时,能够实时显示到屏幕中间

注意:有些人会说,为什么这么麻烦,不直接在canvas中嵌套html,其实这样是行不通的,因为canvas不支持嵌套html,会将其覆盖,所以我们使用

<span style="color:#000000;">fillText()</span>

方法来进行写汉字。

这样就出现了如下图所示的效果,我们输入HELLO

我们将输入的字符显示到了画布上


2.4 动态显示画横线

废话不多说,直接看代码

//动态画横线function drawRowLine(startX,startY,length){var iLen = 0;var flag = 0;function rowLine(){if(iLen<=length){ctx.moveTo(startX,startY);ctx.lineTo(++startX,startY);iLen++;ctx.stroke();}else{}}setInterval(rowLine,5);}
传入参数x,y和长度,通过setInterval函数来进行动态画图,我们设定5ms就执行一次rowLine函数,记住这里参数里面rowLine不能加(),不然代表函数执行,不是函数。

在rowLine函数里面,我们通过iLen<=Length来判断是否到达长度,没到达继续画,到达了则停止,停止我这里为了方便没写,大家可以自行在else里面加上clearInterval()函数

接着,moveto设置起点,lineto设置终点,这里因为是画横线,所以纵坐标不动,横坐标每次加1,再调用ctx.stroke()再次画图即可。

2.5 动态显示画竖线

和上面画横线一样,我们这里分成画竖线,分别是向上画竖线和向下画竖线,函数如下所示

//动态画向上竖线function drawColUpLine(startX,startY,length){var iLen = 0;function colUpLine(){if(iLen<=length){ctx.moveTo(startX,startY);ctx.lineTo(startX,--startY);iLen++;ctx.stroke();}}setInterval(colUpLine,5);}//动态画向下竖线function drawColDownLine(startX,startY,length){var iLen = 0;function colDownLine(){if(iLen<=length){ctx.moveTo(startX,startY);ctx.lineTo(startX,++startY);iLen++;ctx.stroke();}}setInterval(colDownLine,5);}

无非就是横纵坐标是否变,长度如何控制之类的方法。

到这里,我们基本上需要的方法都有了

2.6 根据用户输入的个数来计算间距

这里,为了更加具有扩展性,我们根据用户输入的个数来计算纵向的间距,并平均分布,再向右延伸,造成如下所示的效果


可见,当我输入4以后,又出现了4条横线,并向右延伸~

这里所有的画线都是动态的

那么如何动态的计算这个间距呢/

我封装到一个函数了,函数如下所示’

function calcTranIO(TranIOX,numOfTranIO){tranIOLenth = 500/(numOfTranIO+1);var m = new Array();for(i=0;i<numOfTranIO;i++){m =[];m.push(TranIOX);m.push(tranIOLenth*(1+i));tranIOZuoBiao[i] = m;}}
传入的参数分别是x,和个数,x这里是横坐标,我么不变,主要对个数进行处理

通过循环,我们把起始点的坐标存到tranIOZuoBiao的map里面,每个key是序号,如0,1,2之类,value就是坐标,如[10,12],[10,22],[10,33]这样的方式,简单来说就是map存储如下所示

{“0”:[10,12,“1”:[10,12],[10,22],......}这样的

其中tranIOLenth这个全局变量就是存储的每一段的长度,注意这里计算是用500/(个数+1),为什么加1,大家可以自己想一下

得到了这个以后就好办了,我们就开始装配这些零件,进行画图了

2.7 装配零件,进行画图

同样的直接通过代码来说明

function draw(){drawRowLine(x,250,100);tnumOfTranIO =parseInt($("#numOfTranIO").val());x+=100;//就是下一段的出示x值calcTranIO(x,tnumOfTranIO);//画第一个竖线,表示交易接口的setTimeout(function(){//画第一段竖线drawColUpLine(x,250,250-tranIOLenth);drawColDownLine(x,250,250-tranIOLenth);//画第一段横线,根据number},1300);setTimeout(function(){for(i=0;i<tnumOfTranIO;i++){                        //通过全局变量取出x和y坐标                       var zuobiao = tranIOZuoBiao[i];var zuobiaoX=zuobiao[0];var zuobiaoY=zuobiao[1];                       drawRowLine(zuobiaoX,zuobiaoY,500);}},3000);}
这个draw方法,首先调用drawRowLine来画第一条横线,其中x就是2.3里面所调用的代码记录的动态根据用户输入的字符长度来进行测算开始的横坐标

x = ctx.measureText(something).width+10;
接着,tnumOfTranIO存储了用户输入的个数

因为第一段横线长度写死了,为100,所以更新x坐标,为x+=100;

接着就是画第一个竖线,分为上线两条,从中间向上下两边延伸,

注意:这里不可以直接调用drawCOlLine这样的方法,要设置setTimeout来实现,因为不管是settimeout还是setinterval都有种异步的假象,它

将执行的方法存入到队列中执行,后面的函数会提前执行,所以,我们这里需要根据长度来测算时延,我这里设置了1300,就是大概第一段横线画完需要1300ms,也就是1.3s

画竖线的参数设置如上所示,长度设置为250-tranIOLenth是因为避免多于的线条


最后就是调用紧接着的几段画横线

同样的设置setTimeout方法以后,

通过循环来多次drawRowLine,正如前面所说的,这里是类似于异步,所以这些线都是一起画的效果

通过全局变量取出对应第i条线的起点坐标,在调用drawrow方法即可


Tips:因为这个我也是才学,还在摸索中,所以也及时和大家聊一聊这门技术,感觉学好了可以做很多事,包括动态制作页面元素,制作2d游戏等等,还是很有意思的~~

欢迎交流

2 0