预览加载中,请您耐心等待几秒...
1/4
2/4
3/4
4/4

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

在canvas中可以很方便的用arc方法画出圆形,本来圆形也可以看作是一个宽高相等的椭圆,但canvas中根本没有画椭圆的方法,我们要用其他方法来模拟。我们首先要明确画一个椭圆需要那些参数,基本的几何知识告诉我们,椭圆需要圆心坐标,宽度,高度——或者还有旋转角度,不过这个可以暂时不要,旋转是比较容易的。1,使用lineTo画椭圆你没有看错,lineTo这样一个纯粹用来画直线的方法居然可以用来画椭圆!?但他确实存在,不过写法实在是有些不可思议:复制代码代码如下:functionDrawEllipse(Canvas,O,OA,OB){//画椭圆,例子:varB=newArray(150,150);DrawEllipse(hb,B,50,30);with(Canvas){varx=O[0]+OA;vary=O[1];moveTo(x,y);for(vari=0;i<=360;i++){varii=i*Math.PI/180;varx=O[0]+OA*Math.cos(ii);vary=O[1]-OB*Math.sin(ii);lineTo(x,y);}}}这个方法的原理是,一个圆有360度,那么就用lineTo循环360次,画出每一度的线段,最终连成一个椭圆。其中需要用到三角函数正弦余弦进行计算。注意,这个方法的第2个参数是个数组,即椭圆的圆心坐标.思路很奇葩,而且画出的椭圆也比较平滑。但不值得大家使用——此方法每画一个椭圆,就要循环360次,只有画的椭圆稍微一多,对浏览器的性能就是个考验。我们只用了解一下他的思路即可2,使用arc画圆,然后把他缩放成一个椭圆这个方法的原文在此,核心函数如下:复制代码代码如下:varcanvas=document.getElementById('myCanvas');varcontext=canvas.getContext('2d');varcenterX=0;varcenterY=0;varradius=50;//savestatecontext.save();//translatecontextcontext.translate(canvas.width/2,canvas.height/2);//scalecontexthorizontallycontext.scale(2,1);//drawcirclewhichwillbestretchedintoanovalcontext.beginPath();context.arc(centerX,centerY,radius,0,2*Math.PI,false);//restoretooriginalstatecontext.restore()此方法用了一个我前面还没讲过的canvas函数,即scale,他能实现canvas的缩放。缩放有水平和垂直两个方向,代码中把canvas水平方向放大了,而垂直方向不变,so,原来arc画出的圆形就变成了一个椭圆。这个方法初看甚妙,代码少,而且原理浅显易懂。但分析一下就能发现他的明显缺点了,就是——不精确!比如我需要宽171高56的椭圆,此时我们如果把arc的半径定为28的话,那么后面就要为171/28/2这个蛋疼的不知所云的数字郁闷了。不过有个折中的办法是始终把arc的半径设成100,然后,不够就放大,超过了就缩小。但是,还是不精确。3,使用贝赛尔曲线bezierCurveTo自从觉得上面的缩放法不精确后,我就很想找到一个精确的画椭圆的方法,最后在stackoverflow上找到了:复制代码代码如下:functiondrawEllipse(ctx,x,y,w,h){varkappa=0.5522848;ox=(w/2)*kappa,//controlpointoffsethorizontaloy=(h/2)*kappa,//controlpointoffsetverticalxe=x+w,//x-endye=y+h,//y-endxm=x+w/2,//x-middleym=y+h/2;//y-middlectx.beginPath();ctx.moveTo(x,ym);ctx.bezierCurveTo(x,ym-oy,xm-ox,y,xm,y);ctx.bezierCurveTo(xm+ox,y,xe,ym-oy,xe,ym);ctx.bezierCurveTo(xe,ym+oy,xm+ox,ye,xm,ye);ctx.bezierCurveTo(xm-ox,ye,x,ym+oy,x,ym);ctx.closePath();ctx.stroke();}这个方法可以算是比较完美的了。他把一个椭圆分成了4条贝塞尔曲线,用他们连成了一个椭圆。最后宽度高度也比较精确,开销也较少。但此方法依然有缺点。大家看那个kapp