htmlCanvas画图教程—使用

上传人:豆浆 文档编号:19096927 上传时间:2017-11-18 格式:DOC 页数:4 大小:32.50KB
返回 下载 相关 举报
htmlCanvas画图教程—使用_第1页
第1页 / 共4页
htmlCanvas画图教程—使用_第2页
第2页 / 共4页
htmlCanvas画图教程—使用_第3页
第3页 / 共4页
htmlCanvas画图教程—使用_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《htmlCanvas画图教程—使用》由会员分享,可在线阅读,更多相关《htmlCanvas画图教程—使用(4页珍藏版)》请在金锄头文库上搜索。

1、在 canvas 中可以很方便的用 arc 方法画出圆形,本来圆形也可以看作是一个宽高相等的椭圆,但 canvas 中根本没有画椭圆的方法,我们要用其他方法来模拟。我们首先要明确画一个椭圆需要那些参数,基本的几何知识告诉我们,椭圆需要圆心坐标,宽度,高度或者还有旋转角度,不过这个可以暂时不要,旋转是比较容易的。 1,使用 lineTo 画椭圆 你没有看错,lineTo 这样一个纯粹用来画直线的方法居然可以用来画椭圆!?但他确实存在,不过写法实在是有些不可思议: 复制代码代码如下:function DrawEllipse(Canvas,O,OA,OB) /画椭圆,例子:var B=new Arr

2、ay(150,150); DrawEllipse(hb,B,50,30); with (Canvas) var x=O0+OA; var y=O1; moveTo(x,y); for (var i=0;i=360;i+) var ii=i*Math.PI/180; var x=O0+OA*Math.cos(ii); var y=O1-OB*Math.sin(ii); lineTo(x,y); 这个方法的原理是,一个圆有 360 度,那么就用 lineTo 循环 360 次,画出每一度的线段,最终连成一个椭圆。其中需要用到三角函数正弦余弦进行计算。 注意,这个方法的第 2 个参数是个数组,即椭圆

3、的圆心坐标. 思路很奇葩,而且画出的椭圆也比较平滑。但不值得大家使用此方法每画一个椭圆,就要循环 360 次,只有画的椭圆稍微一多,对浏览器的性能就是个考验。 我们只用了解一下他的思路即可 2,使用 arc 画圆,然后把他缩放成一个椭圆 这个方法的原文在此,核心函数如下: 复制代码代码如下:var canvas = document.getElementById(myCanvas); var context = canvas.getContext(2d); var centerX = 0; var centerY = 0; var radius = 50; / save state conte

4、xt.save(); / translate context context.translate(canvas.width / 2, canvas.height / 2); / scale context horizontally context.scale(2, 1); / draw circle which will be stretched into an oval context.beginPath(); context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); / restore to original state c

5、ontext.restore() 此方法用了一个我前面还没讲过的 canvas 函数,即 scale,他能实现 canvas的缩放。缩放有水平和垂直两个方向,代码中把 canvas 水平方向放大了,而垂直方向不变,so,原来 arc 画出的圆形就变成了一个椭圆。 这个方法初看甚妙,代码少,而且原理浅显易懂。但分析一下就能发现他的明显缺点了,就是不精确!比如我需要宽 171 高 56 的椭圆,此时我们如果把arc 的半径定为 28 的话,那么后面就要为 171/28/2 这个蛋疼的不知所云的数字郁闷了。 不过有个折中的办法是始终把 arc 的半径设成 100,然后,不够就放大,超过了就缩小。但是

6、,还是不精确。 3,使用贝赛尔曲线 bezierCurveTo 自从觉得上面的缩放法不精确后,我就很想找到一个精确的画椭圆的方法,最后在 stackoverflow 上找到了: 复制代码代码如下:function drawEllipse(ctx, x, y, w, h) var kappa = 0.5522848; ox = (w / 2) * kappa, / control point offset horizontal oy = (h / 2) * kappa, / control point offset vertical xe = x + w, / x-end ye = y + h,

7、 / y-end xm = x + w / 2, / x-middle ym = y + h / 2; / y-middle ctx.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,

8、ym); ctx.closePath(); ctx.stroke(); 这个方法可以算是比较完美的了。他把一个椭圆分成了 4 条贝塞尔曲线,用他们连成了一个椭圆。最后宽度高度也比较精确,开销也较少。 但此方法依然有缺点。大家看那个 kappa 参数,有个很奇特的值,相信很多人在几何专家告诉你为什么他要取这个值之前,都不明白为什么非要取这个值我到现在还是不知道。并且我有很强烈的想把他改一下看看有什么后果的冲动。 当然我这种类似强迫症患者的冲动并不能说成是此方法的缺点,他真正的缺点是为什么要用 4 条贝塞尔曲线?我个人觉得,一个椭圆明显是由两条贝塞尔曲线组成的而不是 4 条。这个想法最终让我找到了

9、最完美的画椭圆的方法。4,使用两条贝赛尔曲线画出椭圆 为了了解上一个方法能否精简,我专门注册了一个 stackoverflow 的帐号去提问,由于问题里有图片,积分不够不能传,我还迫不得已用勉勉强强的英语水平去回答老外的问题挣积分。但最终好运到了,回答一个问题就解决了我的积分问题。 我提的贝赛尔曲线和椭圆的关系的问题在此. 说实话,下面老外的回答我大部分没看懂,但幸亏他提供了一个代码示例页,让我明白了原理,在此对他表示再次的感谢。而根据他的解答,我找到的画椭圆的方法如下: 复制代码代码如下:/椭圆 CanvasRenderingContext2D.prototype.oval = functi

10、on (x, y, width, height) var k = (width/0.75)/2, w = width/2, h = height/2; this.beginPath(); this.moveTo(x, y-h); this.bezierCurveTo(x+k, y-h, x+k, y+h, x, y+h); this.bezierCurveTo(x-k, y+h, x-k, y-h, x, y-h); this.closePath(); return this; 此方法既精确,又代码少,而且也没有奇怪的难懂的地方。只需要记住这一点,椭圆的宽度与画出椭圆的贝赛尔曲线的控制点的坐标比例如下: 贝塞尔控制点 x=(椭圆宽度/0.75)/2 这一点已经在代码中体现了。 大家可自行试验上面的 4 个方法画出椭圆。 如果你发现了更简单的方法,也请分享出来大家探讨吧。本文转载自奇优网 http:/www.qiyo.cc原文网址 http:/www.qiyo.cc/web/HTML5/2013/0323/2659.html

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 经济/贸易/财会 > 综合/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号