[69-3] Canvasに曲線を描こう(線のスタイルも)
最終更新日:2019年02月06日 (初回投稿日:2014年04月15日)
前回は、<canvas>に四角形、多角形、円弧を描いてみました。
→ [69-2] Canvasに基本的な図形を描こう
多角形は直線で描きましたね。
今回はいろいろな曲線を描いてみます。
Illustrator などで描く「コントロールポイント」がある曲線です。
その応用で、直線と組み合わせて「角丸四角形」も作ってみました。
Canvas でも Illustrator と同じように「線の太さ」や「先端の形状」なども指定できます。
今回のサンプルはこちら。
クリックで別ウィンドウで開きます。
二次ベジェ曲線の基本
二次ベジェ曲線は quadraticCurveTo(cpx, cpy, x, y);
二次ベジェ曲線は「quadraticCurveTo(cpx, cpy, x, y);」で表します。
quadratic は数学用語で「二次の...」という意味だそうです。
- beginPath(); で、描画の開始を宣言
- moveTo(x,y); で、サブパスの開始点をx,y座標(ピクセル)を指定
ここまで前回の「多角形」と同じですね。 - quadraticCurveTo(cpx, cpy, x, y); で、二次ベジェ曲線を指定
cpx, cpy は、コントロールポイント(cp)の x, y 座標。
その後のx, y は終点の座標です。 - strokeStyle または fillStyle で、線 or 塗りの色指定をする
*ここを省略すると、デフォルトの黒い線、または塗りになります。 - 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);
三次ベジェ曲線は「bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);」で表します。
Bezier curve はそのまま三次ベジェ曲線の意味です。
- beginPath(); で、描画の開始を宣言
- moveTo(x,y); で、サブパスの開始点をx,y座標(ピクセル)を指定
- bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y); で、三次ベジェ曲線を指定
cpx1, cpy1 は、1つ目のコントロールポイント(cp)の x, y 座標。
cpx2, cpy2 は、2つ目のコントロールポイント(cp)の x, y 座標。
x, y は終点の座標です。 - strokeStyle または fillStyle で、線 or 塗りの色指定をする
*ここを省略すると、デフォルトの黒(#000)い線、または塗りになります。 - 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() で書き出します。
画像のトリミングや、図形によるクリッピングもできます。
- 関連記事
-
- [69-9] Canvasでグラフィックスの変形をしよう(拡大・回転・移動・反転など)
- (ちょっとメモ)Canvasで便利な javaScriptライブラリ
- [69-8] Canvasでテキストを描画しよう
- [69-7] Canvas上の重なった描画領域を指定しよう (globalCompositeOperationプロパティ)
- [69-6] Canvasにマウスの動きに合わせて描画しよう (クリックやマウスムーブとの組み合わせと Math.random)
- [69-5] Canvasにグラデーションやパターン、シャドウを指定しよう
- [69-4] Canvasに画像を描画しよう(トリミングやクリッピングも)
- [69-3] Canvasに曲線を描こう(線のスタイルも)
- [69-2] Canvasに基本的な図形を描こう
- [69-1] canvas要素でグラフィックスを表示する領域を作ろう
- [68] 動画や音声に字幕やキャプションを表示しよう track要素
- [67]「mediagroup属性」でメディア要素を同期させよう
- [66] 音声をプラグイン無しで組み込もう audio要素・source要素
- [65] 動画をプラグイン無しで組み込もう video要素・source要素
- [64] プラグインで再生されるコンテンツを組み込もう embed要素
初心者にも使いやすい(と思う)レンタルサーバー
「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、
スターサーバーや ロリポップ!
です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。
ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー
は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。
スポンサーリンク