ホームページ  >  記事  >  ウェブフロントエンド  >  html5 Canvas 描画チュートリアル (11) — lineTo/arc/bezierCurveTo を使用して oval_html5 を描画するチュートリアルのスキル

html5 Canvas 描画チュートリアル (11) — lineTo/arc/bezierCurveTo を使用して oval_html5 を描画するチュートリアルのスキル

WBOY
WBOYオリジナル
2016-05-16 15:50:051650ブラウズ

Canvasでは円弧法を使うと簡単に円を描くことができますが、本来円は幅と高さが等しい楕円とみなすことができますが、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;
moveTo(x,y); 0;ivar ii=i*Math.PI/180;
var x=O[0] OA*Math.cos(ii); [1]-OB* Math.sin(ii);
lineTo(x,y)
}
}
}


このメソッドの原理は次のとおりです。円が 360 度であることを確認します。次に、lineTo を使用して 360 回ループし、各度の線分を描画し、最後にそれらを接続して楕円を作成します。計算には三角関数のサインとコサインが必要です。
このメソッドの 2 番目のパラメーターは、楕円の中心座標である配列であることに注意してください。

このアイデアは非常に奇妙で、描画された楕円は比較的滑らかです。しかし、誰にとっても使用する価値があるわけではありません。このメソッドは、楕円を描画するたびに 360 回循環し、ブラウザのパフォーマンスのテストとして、楕円を少しだけ追加して描画します。
私たちは彼のアイデアを理解する必要があるだけです

2. 円弧を使用して円を描き、それを楕円に拡大縮小します

このメソッドの原文はここにあります。関数は次のとおりです:


コードをコピーします
コードは次のとおりです:
var Canvas = document.getElementById('myCanvas ');
var context = Canvas.getContext('2d');
var centerY = 0;
// 状態を保存
context.save();
// コンテキストを変換
context.translate(canvas.width / 2, Canvas.height / 2);水平に
context.scale( 2, 1);
// 楕円形に引き伸ばされる円を描画します
context.beginPath();
context.arc(centerX, centerY, radius, 0) , 2 * Math.PI, false );
// 元の状態に復元します
context.restore()


このメソッドは、これまで説明しなかった Canvas 関数を使用します。 、つまりスケール、ズームのキャンバスを実装できます。拡大縮小の方向は水平方向と垂直方向の2つあり、コードでは水平方向にはキャンバスが拡大されますが、垂直方向はそのままなので、円弧で描いた円は楕円になります。
このメソッドは一見すると非常に優れているように見え、コードも少なく、原理も理解しやすいです。しかし、分析すると、彼の明らかな欠点がわかります。それは、不正確さです。たとえば、幅 171、高さ 56 の楕円が必要です。円弧の半径を 28 に設定すると、171/28/2 という痛くて理解できない数字に落ち込むことになります。

しかし、妥協策として、円弧の半径を常に 100 に設定し、十分でない場合は拡大し、それを超える場合は縮小します。ただし、まだ正確ではありません。
3、ベジェ曲線 bezierCurveTo

上記のスケーリング方法が不正確だと感じたので、楕円を描く正確な方法を探したかったのですが、最終的に stackoverflow でそれを見つけました:



コードをコピー

コードは次のとおりです:
functiondrawEllipse(ctx, x, y , w, h) { var kappa = 0.5522848; ox = (w / 2) * kappa, // 制御点の水平オフセット
oy = (h / 2) * kappa, // 制御点オフセット垂直
xe = x w, // x 端
ye = y h, // y 端
xm = x w / 2, // x 中間
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); (xm - ox, ye, x, ym oy, x, ym);
ctx.closePath();


この方法は完璧であると考えられます。彼は楕円を 4 つのベジェ曲線に分割し、それらを接続して楕円を形成しました。最後に、幅と高さがより正確になり、オーバーヘッドが少なくなります。
しかし、この方法にはまだ欠点があります。カッパパラメータを見てください。これは非常に特殊な値です。幾何学の専門家がなぜこの値でなければならないのかを説明するまで、多くの人はなぜこの値でなければならないのか理解できないと思います。私にはまだわかりません。そして、それを変えて、その結果がどうなるかを見てみたいという強い衝動があります。

もちろん、強迫性障害患者に似た衝動がこの方法の欠点であるとは言えません。本当の欠点は、なぜ 4 つのベジェ曲線を使用するのかということです。個人的には、楕円は明らかに 4 つではなく 2 つのベジェ曲線で構成されていると感じます。このアイデアは最終的に、楕円を描くための完璧な方法を導き出しました。
4、2 つのベジェ曲線を使用して楕円を描画します。
前の方法が簡略化できるかどうかを理解するために、特別に stackoverflow アカウントを登録して質問しました。という質問には、移行するのに十分なポイントがなかったので、かろうじて十分な英語を使って外国人からの質問に答えてポイントを稼ぐ必要がありました。しかし、ついに幸運が訪れ、質問に答えることでポイントの問題が解決されました。
ベジェ曲線と楕円の関係について私が質問したのはこちらです
正直、以下の外国人の回答はほとんど理解できませんでしたが、幸いなことにコードサンプルページを提供していただいたので理解できました。 . 改めて感謝の意を表したいと思います。彼の答えによると、楕円を描くために私が見つけた方法は次のとおりです。

コードをコピー
コードは次のとおりです。次のように:

//Ellipse
CanvasRenderingContext2D.prototype.oval = function (x, y, width, height) {
var k = (width/0.75)/2,
w = 幅/ 2、
h = 高さ/2;
this.beginPath();
this.bezierCurveTo(x k, y-h, x k) , y h, x, y h );
this.bezierCurveTo(x-k, y h, x-h, x, y-h);
this.closePath();


この方法は正確で、必要なコードは少なく、奇妙な癖はありません。これを覚えておいてください。楕円を描くベジェ曲線の制御点の座標に対する楕円の幅の比率は次のとおりです:
ベジェ制御点 x=(楕円の幅/0.75)/2 これはすでにに反映されたコードにあります。

楕円を描くには、上記の 4 つの方法を試すことができます。
もっと簡単な方法を見つけたら、議論のために私たちと共有してください。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。