HTML5 Canvasで角丸四角を描いて、グラーデーションで塗り潰してみた

シェアする

Canvasでチャートを作成していた時に、背景やらグラフの帯やらで角丸四角をたくさん描画する必要があったので、共通化して1つの関数にまとめましたので紹介していきます。

スポンサーリンク

サンプル

作ろうとしているものがこちらになります。
「サイズ」「色」等のパラメータを変更すると、角丸四角が生成されるので試してみてください。

これより、このサンプルの実装方法について紹介していきます。

各種ファイルを準備

以下のようにファイルを準備します。


┣ index.html
┗ js
    ┗ main.js

index.htmlの記述

index.htmlは以下のように記述しておきます。
【index.html】


<html>
<head>
    <meta charset="utf-8">
    <script src="js/main.js"></script>
</head>
<body>
    <div>
        <canvas id="chart" height="400" width="600"></canvas>
    </div>
</body>
</html>

jQueryとCanvas描画用ファイルmain.jsを読み込ませ、canvasタグの設置をします。
今回はcanvasの「height」を「400」、「width」を「600」に設定しています。

main.jsの記述

まず下準備として以下のコードを入れておきます。
【main.js】


window.onload = function() {
    chartbuild();
};

function chartbuild() {
    
    var canvas = document.getElementById('chart');
    if (canvas.getContext) {

        var context = canvas.getContext('2d');
        
    }
}

ページが読み込まれた後に、chartbuild()の中の処理が行われます。
このchartbuild()の中に必要なコードを追加していきます。

描画の基本設定

こんな描画をします

角丸四角を描画するときの設定をします。


        //角丸四角の基本変数定義
        var x = 100;  //左上の頂点x座標
        var y = 100;  //左上の頂点y座標
        var w = 300;  //横の長さ
        var h = 150;  //縦の長さ
        var r = 20;  //角丸の半径
        var color = "#a9a9a9";  //塗りつぶし色

角丸四角の描画

では実際に描画をする関数がこちら


        function drawsq(x,y,w,h,r,color) {
            context.beginPath();
            context.lineWidth = 1;
            context.strokeStyle = color;
            context.fillStyle = color;
            context.moveTo(x,y + r);  //←①
            context.arc(x+r,y+h-r,r,Math.PI,Math.PI*0.5,true);  //←②
            context.arc(x+w-r,y+h-r,r,Math.PI*0.5,0,1);  //←③
            context.arc(x+w-r,y+r,r,0,Math.PI*1.5,1);  //←④
            context.arc(x+r,y+r,r,Math.PI*1.5,Math.PI,1);  //←⑤
            context.closePath();  //←⑥
            context.stroke();  //←⑦
            context.fill();  //←⑧
        }

上記の描画の流れを軽く説明します。
①でmoveTo()の引数の座標にパスをセット。(左上の直線のスタート位置)
②で左下の円弧を描いていますが、そこでarc()の動作に一つポイントがあり、直前にパスがある場合は、そのパスと弧の始点を直線で繋ぐサブパスが作成されるというものです。
※①moveTo()の座標から左下の円弧の始点までを直線で結ぶサブパスが作成され、そこから左下の円弧の始点から終点までのサブパスが作成されます。
③で右下の弧を描いていますが、②の時と同様に、②の弧の終点と③の弧の始点を直線で結ぶサブパスが作成され、続けて右下の円弧の始点から終点までサブパスが作成されます。
残りも同じように描いていき、反時計回りに1周していきます。
⑥でサブパスを閉じ、⑦でこれまで作成したサブパスの通りに線を描画します。
⑧で、⑦で囲った部分に対して色を塗りつぶしています。

arc()について詳細をもっと知りたい方はこちらを参考にしてください

これまでのコードをマージ

これまでのコードをmain.jsにマージして、ページ読み込み時に描画する処理を入れると以下のようになります。


function chartbuild() {
    
    var canvas = document.getElementById('chart');
    if (canvas.getContext) {

        var context = canvas.getContext('2d');

        //角丸四角の基本変数定義
        var x = 100;  //左上の頂点x座標
        var y = 100;  //左上の頂点y座標
        var w = 300;  //横の長さ
        var h = 150;  //縦の長さ
        var r = 20;  //角丸の半径
        var color = "#a9a9a9";  //塗りつぶし色
        
        reset();

        function reset() {
            context.clearRect(0,0,canvas.width,canvas.height);
            drawsq(x,y,w,h,r,color);
        }
        
        function drawsq(x,y,w,h,r,color) {
            context.beginPath();
            context.lineWidth = 1;
            context.strokeStyle = color;
            context.fillStyle = color;
            context.moveTo(x,y + r);
            context.arc(x+r,y+h-r,r,Math.PI,Math.PI*0.5,true);
            context.arc(x+w-r,y+h-r,r,Math.PI*0.5,0,1);
            context.arc(x+w-r,y+r,r,0,Math.PI*1.5,1);
            context.arc(x+r,y+r,r,Math.PI*1.5,Math.PI,1);       
            context.closePath();
            context.stroke();
            context.fill();
        }
        
    }
}

「reset()」でcanvasの領域をクリアしてから、「drawsq()」に設定した値を引数で渡して描画させています。

グラデーションをつけてみる

先ほどの基本設定と描画の関数に少し追加して、グラデーションをつけてみましょう。
今回実装するのは「線形グラデーション」です。

このように、設定した2点間で色が変化していくグラデーションです。

グラデーション設定を追加

基本設定部分に以下を追加します。
今回は2色で実装します。


        //角丸四角の基本変数定義
        var x = 100;  //左上の頂点x座標
        var y = 100;  //左上の頂点y座標
        var w = 300;  //横の長さ
        var h = 150;  //縦の長さ
        var r = 20;  //角丸の半径
        var color = "#0404B4";  //塗りつぶし色
        var color2 = "#819FF7";  //塗りつぶし色2

「color2」を追加しました。

描画関数に追加

drawsq()を以下のように修正します。


        function drawsq(x,y,w,h,r,color,color2) {
            var r_color;
            r_color = context.createLinearGradient(x,y+h,x,y);  //←①
            r_color.addColorStop(0,color);  //←②
            r_color.addColorStop(1,color2);  //←③
            context.beginPath();
            context.lineWidth = 3;
            context.strokeStyle = r_color;  //←④
            context.fillStyle = r_color;  //←⑤
            context.moveTo(x,y + r);
            context.arc(x+r,y+h-r,r,Math.PI,Math.PI*0.5,true);
            context.arc(x+w-r,y+h-r,r,Math.PI*0.5,0,1);
            context.arc(x+w-r,y+r,r,0,Math.PI*1.5,1);
            context.arc(x+r,y+r,r,Math.PI*1.5,Math.PI,1);       
            context.closePath();
            context.stroke();
            context.fill();
        }

引数が一つ増えました。関数を呼ぶ時にも注意してください。
追加した「r_color」がグラデーション後の色になります。この「r_color」に設定を追加していきます。
①でグラデーションの色の変化の方向を設定しています。
「createLinearGradient(X1,Y1,X2,Y2)」は、線形グラデーションを作成するときの関数です。
ざっくり説明すると、始点(X1,Y1)から終点(X2,Y2)に向けて色が変化します。

今回はしたから上に向けて変化させたいので、角丸四角の左下の頂点と左上の頂点を設定しています。

②と③で始点と終点の色を設定しています。
「addColorStop(offset,color)」
offsetは①で設定した始点と終点を「0.0~1.0」とした場合、どの場所に色を持ってくるかを設定します。
colorはそのときの色です。

今回は角丸四角の底辺部分の色を「#0404B4」、一番上の部分を「#819FF7」にしてグラデーションをかけたいので、「0」と「1」の末端と先端に設定しています。

最後に④と⑤で、「r_color」をセットして準備完了です。

まとめ

今回紹介したものでも、場所、大きさ、丸みの大きさ、色、グラデーションを変化させられるので使いまわせると思います。
arc()やstroke()を深く理解すれば、もう少しいじって片側だけ丸い四角とか自由に図形が描けるようになると思います。

サンプルプロジェクト

以下に今回作成したプロジェクトのサンプルを上げておきます。

ブログ本文では解説していませんが、フォームの値を変更するとチャートに即時反映されるコードもサンプルには入っております。

Contribute to ChatLune/blog-javascript-CanvasDrawSq development by creating an account on GitHub.

飲食業界からIT業界に転身してきて現在2年目です。PHPの経験がメインとなります。これまで自分がPHPを扱ってきた上で、モヤモヤしてきたことをメインに記事にしていきますのでよろしくお願いいたします。

スポンサーリンク

シェアする

フォローする