首頁 web前端 H5教程 HTML5 Canvas中繪製橢圓的4種方法_html5教學技巧

HTML5 Canvas中繪製橢圓的4種方法_html5教學技巧

May 16, 2016 pm 03:47 PM
canvas html5 繪製橢圓

概述

HTML5中的Canvas並沒有直接提供繪製橢圓的方法,以下是對幾種繪製方法的總結。各種方法各有優缺,視情況選用。各方法的參數相同:

1.context為Canvas的2D繪圖環境對象,
2.x為橢圓中心橫座標,
3.y為橢圓中心縱座標,
4.a為橢圓橫半軸長,
5.b為橢圓縱半軸長。

參數方程式法

該方法利用橢圓的參數方程來繪製橢圓

複製代碼
代碼如下:

//-----------用參數方程式繪製橢圓---------------------
//函數的參數x,y為橢圓中心;a,b分別為橢圓橫半軸、
//縱半軸長度,不可同時為0
//此方法的缺點是,當lineWidth較寬,橢圓較扁時
//橢圓內部長軸端較為尖銳,不平滑,效率較低
function ParamEllipse(context, x, y, a, b)
{
//max等於1除以長軸值a和b中的較大者
//i每次循環增加1/max,表示度數的增加
//這樣可以使得每次循環所繪製的路徑(弧線)接近1像素
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x a, y); //從橢圓的左端點開始繪製
for (var i = 0; i {
//參數方程式為x = a * cos(i), y = b * sin(i),
//參數為i,表示度數(弧度)
context.lineTo(x a * Math.cos(i), y b * Math.sin(i));
}
context.closePath();
context.stroke();
};

均勻壓縮法

這種方法利用了數學中的均勻壓縮原理將圓進行均勻壓縮為橢圓,理論上為能夠得到標準的橢圓.下面的代碼會出現線寬不一致的問題,解決辦法看5樓simonleung的評論。

複製程式碼
程式碼如下:

//------------均勻壓縮法繪製橢圓--------------------
//其方法是用arc方法繪製圓,結合scale進行
//橫軸或縱軸方向縮放(均勻壓縮)
//這種方法繪製的橢圓的邊離長軸端越近越粗,長軸端點的線寬是正常值
//邊離短軸越近、橢圓越扁越細,甚至產生間斷,這是scale導致的結果
//這種缺點某些時候是優點,例如在表現環的立體效果(行星光環)時
//對於參數a或b為0的情況,這種方法不適用
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//選擇a、b中的較大者作為arc方法的半徑參數
var r = (a > b) ? a : b;
var ratioX = a / r; //橫軸縮放比
var ratioY = b / r; //縱軸縮放比
context.scale(ratioX, ratioY); //進行縮放(均勻壓縮)
context.beginPath();
//從橢圓的左端點開始逆時針繪製
context.moveTo((x a) / ratioX, y / ratioY);
context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI);
context.closePath();
context.stroke();
context.restore();
};

三次貝塞爾曲線法一

    三次貝塞爾曲線繪製橢圓在實際繪製時是近似,理論上也是近似。 但因為其效率較高,在電腦向量圖形學中,常用於繪製橢圓,但是具體的理論我不是很清楚。 近似程度在於兩個控制點位置的選取。這個方法的控制點位置是我自己試驗得出,精確度還可以.

複製程式碼
程式碼如下:

//---------使用三次貝塞爾曲線模擬橢圓1---------------------
//此方法也會產生當lineWidth較寬,橢圓較扁時,
//長軸端較尖銳,不平滑的現象
function BezierEllipse1(context, x, y, a, b)
{
//關鍵是bezierCurveTo中兩個控制點的設定
//0.5和0.6是兩個關鍵係數(在本函數中為試驗而得)
var ox = 0.5 * a,
oy = 0.6 * b;

context.save();
context.translate(x, y);
context.beginPath();
//從橢圓縱軸下端開始逆時針方向繪製
context. moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy, ox, -b, 0, -b);
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
context.bezierCurveTo(-a, oy, -ox, b, 0, b);
context.closePath();
context.stroke();
context.restore();

};

三次貝塞爾曲線法二

這種方法是從StackOverFlow中一個貼文的回覆中改變而來,精確度較高,也是通常用來繪製橢圓的方法.

複製程式碼
程式碼如下:

//---------使用三次貝塞爾曲線模擬橢圓2------- --------------
//此方法也會產生當lineWidth較寬,橢圓較扁時
//,長軸端較尖銳,不平滑的現象
//此方法比前一個貝塞爾方法精確度高,但效率稍差
function BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848 ,
ox = a * k, // 水平控制點偏移
oy = b * k; // 垂直控制點偏移

ctx.beginPath();
//從橢圓的左端點開始順時針繪製四條三次貝塞爾曲線
ctx.moveTo(x - a, y);
ctx.bezierCurveTo x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x ox, y - b, x a, y - oy, x a, y);
ctx.bezierCurveTo(x a, y oy, x ox, y b, x, y b);
ctx.bezierCurveTo(x - ox, y b, x - a, y oy, x - a, y);
ctx.closePath();
ctx.stroke();
};

光柵法

這種方法可以根據Canvas能夠操作像素的特點,利用圖形學中的基本演算法來繪製橢圓。 例如中點畫橢圓演算法等。

其中一個例子是園友「豆豆狗」的部落格文章「HTML5 Canvas 提高班(一) —— 光柵圖形學(1)中點畫圓演算法」。這種方法由於比較“原始”,靈活性大,效率高,精度高,但要實現一個有使用價值的繪製橢圓的函數,比較複雜。例如,要當線寬改變時,演算法就複雜一些。雖然是畫圓的演算法,但畫橢圓的演算法與之類似,可以參考下。

總結
 
基本上所有的方法都不可能達到100%精確,因為受顯示器解析度的限制。

其實最好的方法應該是arc() scale()。 canvas繪圖庫KineticJS就是用的這種方法。

在其他繪圖軟體中,不像HTML5的canvas那樣提供固有的arc() scale()方法,通常用貝塞爾曲線模擬近似橢圓,無論是幾條貝塞爾曲線都是近似而已。關於用貝塞爾曲線模擬橢圓,可以參考這份資料:Drawing an elliptical arc using polylines, quadratic or cubic Bezier curves

由於arc() scale()是瀏覽器已經實現的方法,理論上精度最高,所以從效率、精確度和簡單易用程度來講,都是最佳的。

在用arc() scale()繪製完橢圓後,context.stroke()和 context.restore()兩個方法呼叫的先後順序不同,產生的結果會很有意思的。通常應該先restore()再stroke()。

Demo

下面是除光柵法之外,幾個繪製橢圓函數的演示,演示程式碼如下:

複製程式碼
複製程式碼程式碼如下:

function execDraw()
{
//解決Chrome下的線寬小於等於1的問題
context.lineWidth = 1.1;
context.StrokeStyle="black"
ParamEl (context, 130、80、50、50); // 圓
ParamEllipse(context, 130, 80, 100, 20); // 橢圓
EvenCompEllipse(context, 130, 200, 50, 500); // 圓
EvenCompEllipse(context, 130, 200, 100, 20); // 橢圓
BezierEllipse1(context, 470, 80, 50, 50); // 圓
Bezier,Ellipse 17(Ellipse,Ellipse) 80, 100, 20); // 橢圓
BezierEllipse2(context, 470, 200, 50, 50); // 圓
BezierEllipse2(context, 470, 200, 100, 20); > //偵測相似性(重疊的程度)
ParamEllipse(context, 300, 450, 250, 50);
context.strokeStyle = "yellow";
BezierEllipse1(context, 300, 50, 25050, 25050, 300, 50, 25050, 25050, 300, 50, 25050, , 50);
context.tripStyle = "blue";
BezierEllipse2(context, 300, 450, 250, 50);
};

functionclearCavnas()
{
context.clearRect(0, 0, 600, 600);
};
// ]]>








注意,要成功運行程式碼,需要支援HTML5的Canvas的瀏覽器。
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

在 HTML 中移動文字 在 HTML 中移動文字 Sep 04, 2024 pm 04:45 PM

HTML 中的文字移動指南。在這裡我們討論一下marquee標籤如何使用語法和實作範例。

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

See all articles