搜索
首页web前端H5教程html5 Canvas画图教程(11)—使用lineTo/arc/bezierCurveTo画椭圆形_html5教程技巧

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

复制代码
代码如下:

function DrawEllipse(Canvas,O,OA,OB){
//画椭圆,例子:var B=new Array(150,150); DrawEllipse(hb,B,50,30);
with (Canvas){
var x=O[0]+OA;
var y=O[1];
moveTo(x,y);
for (var i=0;ivar ii=i*Math.PI/180;
var x=O[0]+OA*Math.cos(ii);
var y=O[1]-OB*Math.sin(ii);
lineTo(x,y);
}
}
}

这个方法的原理是,一个圆有360度,那么就用lineTo循环360次,画出每一度的线段,最终连成一个椭圆。其中需要用到三角函数正弦余弦进行计算。
注意,这个方法的第2个参数是个数组,即椭圆的圆心坐标.

思路很奇葩,而且画出的椭圆也比较平滑。但不值得大家使用——此方法每画一个椭圆,就要循环360次,只有画的椭圆稍微一多,对浏览器的性能就是个考验。
我们只用了解一下他的思路即可
2,使用arc画圆,然后把他缩放成一个椭圆
这个方法的原文在此,核心函数如下:

复制代码
代码如下:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = 0;
var centerY = 0;
var radius = 50;
// save state
context.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
context.restore()

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

不过有个折中的办法是始终把arc的半径设成100,然后,不够就放大,超过了就缩小。但是,还是不精确。
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, // 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, ym);
ctx.closePath();
ctx.stroke();
}

这个方法可以算是比较完美的了。他把一个椭圆分成了4条贝塞尔曲线,用他们连成了一个椭圆。最后宽度高度也比较精确,开销也较少。
但此方法依然有缺点。大家看那个kappa参数,有个很奇特的值,相信很多人在几何专家告诉你为什么他要取这个值之前,都不明白为什么非要取这个值——我到现在还是不知道。并且我有很强烈的想把他改一下看看有什么后果的冲动。

当然我这种类似强迫症患者的冲动并不能说成是此方法的缺点,他真正的缺点是——为什么要用4条贝塞尔曲线?我个人觉得,一个椭圆明显是由两条贝塞尔曲线组成的而不是4条。这个想法最终让我找到了最完美的画椭圆的方法。
 4,使用两条贝赛尔曲线画出椭圆
为了了解上一个方法能否精简,我专门注册了一个stackoverflow的帐号去提问,由于问题里有图片,积分不够不能传,我还迫不得已用勉勉强强的英语水平去回答老外的问题挣积分。但最终好运到了,回答一个问题就解决了我的积分问题。
我提的贝赛尔曲线和椭圆的关系的问题在此.
说实话,下面老外的回答我大部分没看懂,但幸亏他提供了一个代码示例页,让我明白了原理,在此对他表示再次的感谢。而根据他的解答,我找到的画椭圆的方法如下:

复制代码
代码如下:

//椭圆
CanvasRenderingContext2D.prototype.oval = function (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个方法画出椭圆。
如果你发现了更简单的方法,也请分享出来大家探讨吧。
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
H5:如何增强网络上的用户体验H5:如何增强网络上的用户体验Apr 19, 2025 am 12:08 AM

H5通过多媒体支持、离线存储和性能优化提升网页用户体验。1)多媒体支持:H5的和元素简化开发,提升用户体验。2)离线存储:WebStorage和IndexedDB允许离线使用,提升体验。3)性能优化:WebWorkers和元素优化性能,减少带宽消耗。

解构H5代码:标签,元素和属性解构H5代码:标签,元素和属性Apr 18, 2025 am 12:06 AM

HTML5代码由标签、元素和属性组成:1.标签定义内容类型,用尖括号包围,如。2.元素由开始标签、内容和结束标签组成,如内容。3.属性在开始标签中定义键值对,增强功能,如。这些是构建网页结构的基本单位。

了解H5代码:HTML5的基本原理了解H5代码:HTML5的基本原理Apr 17, 2025 am 12:08 AM

HTML5是构建现代网页的关键技术,提供了许多新元素和功能。1.HTML5引入了语义化元素如、、等,增强了网页结构和SEO。2.支持多媒体元素和,无需插件即可嵌入媒体。3.表单增强了新输入类型和验证属性,简化了验证过程。4.提供了离线和本地存储功能,提升了网页性能和用户体验。

H5代码:Web开发人员的最佳实践H5代码:Web开发人员的最佳实践Apr 16, 2025 am 12:14 AM

H5代码的最佳实践包括:1.使用正确的DOCTYPE声明和字符编码;2.采用语义化标签;3.减少HTTP请求;4.使用异步加载;5.优化图像。这些实践能提升网页的效率、可维护性和用户体验。

H5:网络标准和技术的发展H5:网络标准和技术的发展Apr 15, 2025 am 12:12 AM

Web标准和技术从HTML4、CSS2和简单的JavaScript演变至今,经历了显着的发展。 1)HTML5引入了Canvas、WebStorage等API,增强了Web应用的复杂性和互动性。 2)CSS3增加了动画和过渡功能,使页面效果更加丰富。 3)JavaScript通过Node.js和ES6的现代化语法,如箭头函数和类,提升了开发效率和代码可读性,这些变化推动了Web应用的性能优化和最佳实践的发展。

H5是HTML5的速记吗?探索细节H5是HTML5的速记吗?探索细节Apr 14, 2025 am 12:05 AM

H5不仅仅是HTML5的简称,它代表了一个更广泛的现代网页开发技术生态:1.H5包括HTML5、CSS3、JavaScript及相关API和技术;2.它提供更丰富、互动、流畅的用户体验,能在多设备上无缝运行;3.使用H5技术栈可以创建响应式网页和复杂交互功能。

H5和HTML5:网络开发中常用的术语H5和HTML5:网络开发中常用的术语Apr 13, 2025 am 12:01 AM

H5与HTML5指的是同一个东西,即HTML5。HTML5是HTML的第五个版本,带来了语义化标签、多媒体支持、画布与图形、离线存储与本地存储等新功能,提升了网页的表现力和交互性。

H5指的是什么?探索上下文H5指的是什么?探索上下文Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器