ホームページ > 記事 > ウェブフロントエンド > キャンバスゲーム開発学習その3:複雑な形状の描画
ベジェ曲線と二次曲線
次に紹介するパスはベジェ曲線です。ベジェ曲線は、二次および三次形状の形をとることができ、一般に複雑で規則的な形状を描画するために使用されます。
quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below) bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
上記の 2 行のコードの違いを右の図に示します。どちらにも開始点と終了点 (図の青い点) がありますが、2次ベジェ曲線には 1 つ (赤色) の制御点 (ポイント) しかありませんが、3 次ベジェ曲線には 2 つあります。パラメータ x と y は終点の座標、cp1x と cp1y は最初の制御点の座標、cp2x と cp2y は 2 番目の制御点です。
ベクトル描画ソフトウェア Adobe Illustrator のような即座の視覚的なフィードバックがないため、2 次および 3 次ベジェ曲線の操作は非常に困難です。複雑なグラフィックを描画するために使用する方が面倒だからです。しかし、時間があれば、そして最も重要なのは忍耐力があれば、複雑なグラフィックでも描くことができます。以下に単純な規則的なグラフを描いてみましょう。これらの例は比較的単純です。私たちが描くのは完全なグラフです。
// Quadratric curves example ctx.beginPath(); ctx.moveTo(75,25); ctx.quadraticCurveTo(25,25,25,62.5); ctx.quadraticCurveTo(25,100,50,100); ctx.quadraticCurveTo(50,120,30,125); ctx.quadraticCurveTo(60,120,65,100); ctx.quadraticCurveTo(125,100,125,62.5); ctx.quadraticCurveTo(125,25,75,25); ctx.stroke();
計算により、二次曲線の 1 つの制御点から、対応する 3 次曲線の 2 つの制御点が得られるため、2 次曲線を 3 次曲線に変換することは可能ですが、その逆はできません。 2次ベジェ曲線への変換は、3次方程式の3次項がゼロの場合にのみ可能です。通常、複数の二次曲線を使用して、細分アルゴリズムを通じて 3 次ベジェ曲線を近似できます。
// Bezier curves example ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fill();
長方形のパス長方形
長方形を直接描画できる上記の 3 つのメソッドに加えて、長方形のパスを描画する rect メソッドもあります。
rect(x, y, width, height)
4 つのパラメータを受け入れます。x と y は左上隅の座標、width と height は幅と高さです。これが呼び出されると、moveTo メソッドがパラメータ (0,0) を指定して自動的に呼び出されるため、開始座標は初期原点に戻されます。
包括的な例
例全体で最も注目すべきは、roundedRect 関数の使用と fillStyle 属性の設定です。カスタム関数は、複雑なグラフィックスの描画をカプセル化するのに非常に役立ちます。この例でカスタム関数を使用すると、コードの約半分が節約されます。 fillStyle 属性の使用については、次の例で詳しく説明します。ここでは、塗りつぶしの色をデフォルトの黒から白に変更し、黒に戻すために使用されます。
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); roundedRect(ctx,12,12,150,150,15); roundedRect(ctx,19,19,150,150,9); roundedRect(ctx,53,53,49,33,10); roundedRect(ctx,53,119,49,16,6); roundedRect(ctx,135,53,49,33,10); roundedRect(ctx,135,119,25,49,10); ctx.beginPath(); ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false); //chiensexu 本来是true呵呵,反了 ctx.lineTo(31,37); ctx.fill(); for(i=0;i<8;i++){ ctx.fillRect(51+i*16,35,4,4); } for(i=0;i<6;i++){ ctx.fillRect(115,51+i*16,4,4); } for(i=0;i<8;i++){ ctx.fillRect(51+i*16,99,4,4); } ctx.beginPath(); ctx.moveTo(83,116); ctx.lineTo(83,102); ctx.bezierCurveTo(83,94,89,88,97,88); ctx.bezierCurveTo(105,88,111,94,111,102); ctx.lineTo(111,116); ctx.lineTo(106.333,111.333); ctx.lineTo(101.666,116); ctx.lineTo(97,111.333); ctx.lineTo(92.333,116); ctx.lineTo(87.666,111.333); ctx.lineTo(83,116); ctx.fill(); ctx.fillStyle = "white"; ctx.beginPath(); ctx.moveTo(91,96); ctx.bezierCurveTo(88,96,87,99,87,101); ctx.bezierCurveTo(87,103,88,106,91,106); ctx.bezierCurveTo(94,106,95,103,95,101); ctx.bezierCurveTo(95,99,94,96,91,96); ctx.moveTo(103,96); ctx.bezierCurveTo(100,96,99,99,99,101); ctx.bezierCurveTo(99,103,100,106,103,106); ctx.bezierCurveTo(106,106,107,103,107,101); ctx.bezierCurveTo(107,99,106,96,103,96); ctx.fill(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(101,102,2,0,Math.PI*2,true); ctx.fill(); ctx.beginPath(); ctx.arc(89,102,2,0,Math.PI*2,true); ctx.fill(); } function roundedRect(ctx,x,y,width,height,radius){ ctx.beginPath(); ctx.moveTo(x,y+radius); ctx.lineTo(x,y+height-radius); ctx.quadraticCurveTo(x,y+height,x+radius,y+height); ctx.lineTo(x+width-radius,y+height); ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); ctx.lineTo(x+width,y+radius); ctx.quadraticCurveTo(x+width,y,x+width-radius,y); ctx.lineTo(x+radius,y); ctx.quadraticCurveTo(x,y,x,y+radius); ctx.stroke(); }
上記は、キャンバス ゲーム開発学習の 3 番目の部分です: 複雑な形状の描画 詳細については、PHP 中国語 Web サイト (www.php.cn) に注目してください。