[69-3] canvasにいろんな曲線を描こう(線のスタイルも)

前回は、<canvas>に四角形、多角形、円弧を描いてみました。
多角形は「パス(線)」で描きましたが、これは直線でしたね。

今回はいろいろな曲線を描いてみます。
Illustrator などで描く、コントロールポイントがある線です。
その応用で、直線と組み合わせて「角丸四角形」も作ってみました。
canvas でも Illustrator と同じように「線の太さ」「先端の形状」なども指定できます。

今回のサンプルはこちら。
クリックで別ウィンドウで開きます。

本日のINDEX
  1. 二次ベジェ曲線
    1. 二次ベジェ曲線の基本
    2. 角丸四角形を作ろう(二次ベジェ曲線の応用)
    3. ちなみに、円弧と直線でも角丸四角形を作れます(arcTo)
  2. 三次ベジェ曲線
    1. 三次ベジェ曲線の基本
    2. 花びらを描いてみた(三次ベジェ曲線の応用)
  3. 線の幅(太さ)の指定(lineWidth)
  4. 線の先端のスタイル(lineCap)
  5. 線の接合部分のスタイル(lineJoin)
  6. 接合部分が miter の場合、尖る部分を無効にする miterLimit

二次ベジェ曲線の基本

二次ベジェ曲線は「quadraticCurveTo(cpx, cpy, x, y);」で表します。
(quadratic は数学用語で「二次の...」という意味だそうです)

  1. beginPath(); で、描画の開始を宣言
  2. moveTo(x,y); で、サブパスの開始点をx,y座標(ピクセル)を指定
    ここまで前回の「多角形」と同じですね。
  3. quadraticCurveTo(cpx, cpy, x, y); で、二次ベジェ曲線を指定
    cpx, cpy は、コントロールポイント(cp)の x, y 座標。
    その後のx, y は終点の座標です。
  4. strokeStyle または fillStyle で、線 or 塗りの色指定をする
    *ここを省略すると、デフォルトの黒い線、または塗りになります。
  5. stroke(); または fill(); で、線 or 塗りで描画します

サンプルの二次ベジェ曲線のソースを見てみましょう。

左の図のように、コントロールポイントが1点なのが、二次ベジェ曲線です。

/* 二次ベジェ曲線_1本目 */
    ctx.beginPath();
    /* 始点の座標 */
    ctx.moveTo(30, 30);
    /* 二次ベジェ曲線(quadraticCurveTo(cpx, cpy, x, y)) */
    ctx.quadraticCurveTo(80, 130, 130, 30);
    /* 色指定無しで書き出すとデフォルトの黒になる */
    ctx.stroke();
     
/* 二次ベジェ曲線_2本目 */
    ctx.beginPath();
    ctx.moveTo(30, 100);
    ctx.quadraticCurveTo(130, 180, 130, 100);
    ctx.stroke();

角丸四角形を作ろう(二次ベジェ曲線の応用)

二次ベジェ曲線を使うと便利なのは
「角丸四角形」です。
角丸の二次ベジェ曲線と、直線とを、交互に描いていきます。

サンプルでは、左の図のように、x=150, y=40 の地点から、時計回りに描いています。

/* 二次ベジェ曲線と直線で、角丸四角形を描く */
    ctx.beginPath();
    ctx.moveTo(150, 40);
    /* 多角形の各頂点を二次ベジェ曲線の制御点に指定する */
    ctx.quadraticCurveTo(150, 30, 160, 30);
    ctx.lineTo(240, 30);
    ctx.quadraticCurveTo(250, 30, 250, 40);
    ctx.lineTo(250, 120);
    ctx.quadraticCurveTo(250, 130, 240, 130);
    ctx.lineTo(160, 130);
    ctx.quadraticCurveTo(150, 130, 150, 120);
    /* closePath で始点まで直線を引く */
    ctx.closePath();
    ctx.strokeStyle = '#FF7373';
    ctx.stroke();

ちなみに、円弧と直線でも角丸四角形を作れます(arcTo)

二次ベジェ曲線の話の途中ですが、円弧(正円)のサブパスを描くのに、
もう1つ「arcTo」というのがあって、こっちのほうが、自動で円を描いてくれるのでラクかも。

「arcTo(x1, y1, x2, y2, radius)」で表します。
「beginPath();」「moveTo(x,y);」で開始点を作っといてから指定を始め、
x1, y1 は1本目の補助線の終点。
x2, y2 は2本目の補助線の終点。radius は正円の半径です。

arcToは、1本目の補助線に接する点から、2本目の補助線に接する点までの円弧を描き、
1本目の補助線の、円弧が始まるまでの直線も描かれるので、これを連続して使うと角丸の多角形ができる、という理屈です。

「arcTo」を使って「角丸四角」を描いてみました。

サンプルでは、図のように、x=280, y=30 の地点から、時計回りに描いています。
直線と円弧を4回繰り返して、角丸四角を作っています。

この場合、2本目の補助線の終点(x2, y2)は、角丸四角の「辺」のどの場所でもいいんですが、
円弧の終わる地点にしています。(半径を足すだけで計算しやすかったので)

/* ちなみに、円弧と直線で、角丸四角形を描く */
    ctx.beginPath();
    ctx.moveTo(280, 30);
    /* 直線に接する円弧を描く(arcTo(x1, y1, x2, y2, radius)) */
    ctx.arcTo(370, 30, 370, 40, 10);
    ctx.arcTo(370, 130, 360, 130, 10);
    ctx.arcTo(270, 130, 270, 120, 10);
    ctx.arcTo(270, 30, 280, 30, 10);
    ctx.fillStyle = '#ff9';
    ctx.globalAlpha = 0.5;/*塗りだけ透明度50%にする*/
    ctx.fill();
    ctx.globalAlpha = 1;/*透明度を100%に戻す*/
    ctx.strokeStyle = '#FFBF00';
    ctx.lineWidth = 5;
    ctx.stroke();

三次ベジェ曲線の基本

三次ベジェ曲線は「bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);」で表します。
(Bezier curve はそのまま三次ベジェ曲線を指します)

  1. beginPath(); で、描画の開始を宣言
  2. moveTo(x,y); で、サブパスの開始点をx,y座標(ピクセル)を指定
  3. bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y); で、三次ベジェ曲線を指定
    cpx1, cpy1 は、1つ目のコントロールポイント(cp)の x, y 座標。
    cpx2, cpy2 は、2つ目のコントロールポイント(cp)の x, y 座標。
    x, y は終点の座標です。
  4. strokeStyle または fillStyle で、線 or 塗りの色指定をする
    *ここを省略すると、デフォルトの黒(#000)い線、または塗りになります。
  5. stroke(); または fill(); で、線 or 塗りで描画します

サンプルの三次ベジェ曲線のソースを見てみましょう。

コントロールポイントが2点あるのが、三次ベジェ曲線です。

/* 三次ベジェ曲線_1本目 */
    ctx.beginPath();
    ctx.moveTo(400, 30);
    ctx.bezierCurveTo(415, 100, 485, 100, 500, 30);
    ctx.lineWidth = 1;
    ctx.strokeStyle = '#00D900';
    ctx.stroke();
 
/* 三次ベジェ曲線_2本目 */
    ctx.beginPath();
    ctx.moveTo(400, 110);
    ctx.bezierCurveTo(450, 160, 450, 60, 500, 110);
    ctx.strokeStyle = '#4DD2FF';
    ctx.stroke();

花びらを描いてみた(三次ベジェ曲線の応用)

三次ベジェ曲線を2回連続して描いて、
花びらのようなパスを作ってみました。
(画像のクリックでサンプルが開きます)
Illustrator のように、けっこう自由に描くことができます。

ただし、Illustrator のようなハンドルが出るわけじゃないので、大変ですけど。笑。
私はまず Illustratorでカタチを作って、コントロールポイントの座標を調べながら JavaScriptを書きました。

/* 三次ベジェ曲線_応用_花びらを描く */
    ctx.beginPath();
    ctx.moveTo(539, 128);
    ctx.bezierCurveTo(536, 62, 593, 13, 658, 71);
    ctx.bezierCurveTo(624, 128, 568, 67, 539, 128);

サンプルファイルのほうに、指定の全文があります。
ここでは、線形グラデーションで塗っています。(グラデーションの詳細は後日)

線の幅(太さ)の指定(lineWidth)

線の太さのデフォルトは、1pxです。
太さを変更したい場合は「lineWidth」を使います。

クリックでサンプルが開きます。

左の図のように、太さを10px にしたければ
lineWidth = 10;
20px にしたければ
lineWidth = 20;
と、ピクセルで指定します。

/* 線幅10ピクセルの指定 */
    ctx2.lineWidth = 10;
    ctx2.beginPath();
    ctx2.moveTo(30, 40);
    ctx2.lineTo(190, 40);
    ctx2.stroke();

線の先端のスタイル(lineCap)

線の先端のスタイルのデフォルトは、「butt」です。
「butt」は、線の先端に何も付けません。(ぶった切った先端って雰囲気の butt です)
「round」は、先端を中心点にした正円で丸めます。
「square」は、先端を中心点にした正方形で四角くします。
先端のスタイルを変更したい場合は「lineCap」を使います。

クリックでサンプルが開きます。

左の図のように、
先端のスタイルを丸くしたければ
lineCap = round;
四角くしたければ
lineCap = square;
と指定します。

    ctx2.lineWidth = 20;
    /* ↑ 1度線幅を指定すると、以降全部この幅になります */
    
/* 3本目 'butt'(初期値。始点、終点でぶつ切り) */
    ctx2.beginPath();
    ctx2.moveTo(30, 80);
    ctx2.lineTo(190, 80);
    ctx2.lineCap = 'butt';
    ctx2.stroke();
/* 4本目 'round'(始点、終点を中心点にした円でまとめる) */
    ctx2.beginPath();
    ctx2.moveTo(30, 110);
    ctx2.lineTo(190, 110);
    ctx2.lineCap = 'round';
    ctx2.stroke();
/* 53本目 'square'(始点、終点を中心点にした正方形でまとめる) */
    ctx2.beginPath();
    ctx2.moveTo(30, 140);
    ctx2.lineTo(190, 140);
    ctx2.lineCap = 'square';
    ctx2.stroke();

線の接合部分のスタイル(lineJoin)

線と線の接合部分(角)のデフォルトスタイルは「miter」です。
「miter」は、線の外側のラインをそのまま延長させて尖らせます
「round」は、角を正円で丸くします。
「bevel」は、角に線幅が1辺の正方形を置くかんじで、直線で面取りします。
接合部分のスタイルを変更したい場合は「lineJoin」を使います。

クリックでサンプルが開きます。

左の図のように、角を丸くしたければ
lineJoin = 'round';
角を斜めに面取りしたければ
lineJoin = 'bevel';
と指定します。

/* 線の接合部分のスタイル(lineJoin) */
    /* 'miter'(初期値。角が尖っている) */
    ctx2.beginPath();
    ctx2.moveTo(305, 25);
    ctx2.lineTo(245, 25);
    ctx2.lineTo(245, 85);
    ctx2.lineJoin = 'miter'; /* この指定省略しても同じ */
    ctx2.stroke();
    /* 'round'(丸く面取りする) */
    ctx2.beginPath();
    ctx2.moveTo(340, 55);
    ctx2.lineTo(280, 55);
    ctx2.lineTo(280, 115);
    ctx2.lineJoin = 'round';
    ctx2.stroke();
    /* 'bevel'(直線で面取りする) */
    ctx2.beginPath();
    ctx2.moveTo(375, 85);
    ctx2.lineTo(315, 85);
    ctx2.lineTo(315, 145);
    ctx2.lineJoin = 'bevel';
    ctx2.stroke();
}

接合部分が miter の場合、尖る部分を無効にする miterLimit

接合部分が miter の場合、角が鋭角であるほど、生成される三角形が長くなります。
あまりにも長くなりすぎるのを防ぐために、miterLimit という設定があります。

miterLimit はデフォルトが 10.0 です。
マイター限界は「 lineWidth ÷ 2 × miterLimit」。

線幅 (lineWidth) が 20pxなら、デフォルトのマイター限界は 100pxになり、 それを越えなければ尖った三角形は生成されます。

クリックでサンプルが開きます。

サンプルの一番下のパスでは、
miterLimit を2.0に指定したので、
miter 限界長は 20pxになり、それを越えるため三角形は生成されません。
(bevel と同じ角になります。)

/* miterLimit を指定 */
    ctx3.beginPath();
    ctx3.moveTo(0, 170);
    ctx3.lineTo(200, 195);
    ctx3.lineTo(0, 220);
    ctx3.lineJoin = 'miter';
    ctx3.miterLimit = 2.0;
    ctx3.stroke();
}

次回予告

今回やった内容は、Illustrator などで描けばメッチャ速い。
ちょっと飽きてきました。
でも、基礎ですからね、やっとかないと…。

次回は画像を canvas に描画してみます。これはオモシロイよ(笑)。
画像をロードして「drawImage()」というメソッドでかき出します。
画像のトリミングや、図形によるクリッピングもできます。

関連記事
この記事をはてなブックマークに追加

やる気を保つためにランキングに参加しています。
応援してくださると すっごいやる気を出します! (笑)

初心者にも使いやすい(と思う)レンタルサーバー

最近よく「レンタルサーバーはどこがいい?」とご質問が来ます。
自分でも使っていてオススメなのはミニバード。管理画面がわかりやすくていい感じす。
仕事で使ってるロリポップもわかりやすい管理画面で、初めてでもすんなり使えると思います。
両方とも、なんといっても料金が安いです。初めてだとなるべく安いほうがイイですからね。

それよりちょっと料金は高いけど、高スペックでコスパが良く、信頼性も高いサーバといえば、やはりさくらのレンタルサーバと、XSERVER(エックスサーバー)だと思う。この2つは老舗でユーザーも多いので、質問する場がたくさんあり、初心者の方でもイケるだろうと思います。

レンタルサーバーは、たくさんあり過ぎて迷いますよね。近いうちに、初心者にも良さげなサーバーについて記事にまとめます。*記事をアップしたらココにもリンクを貼ります。

スポンサーリンク

コメントの投稿

スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
07 | 2017/08 | 09
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
Archive
RSS Link
Profile

yuki★hata

Author : yuki★hata
せめて月1回の更新をめざします~。

メールフォームはこちら

スポンサーリンク
スポンサーリンク
Copyright © ほんっとにはじめてのHTML5とCSS3 All Rights Reserved.