このページの本文へ

PROGRAMMING 古籏一浩のJavaScriptラボ第32回

HTML5とjQueryでブラウザーがペイントツールに!

2010年04月26日 11時00分更新

古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

スライダーでブラシサイズを変更

 色を選べるようになったのでだいぶお絵かきツールらしくなりました。今度は、ブラシサイズを選択できるようにしましょう。サイズの指定方法はいろいろ考えられますが、ここではスライダーUIを使います。

 はじめに、ブラシサイズを保持する変数(今回は「brushSize」としました)を用意します。


var brushSize = 1;


 スライダーは、この連載でも過去に紹介したjQuery UIのUI部品「スライダーウィジェット」(Slider Widget)を利用します(関連記事)。


 スライダーを表示する領域(コンテナ)を用意します。


<div id="slider"></div>


 次に、スライダーの範囲とスライダーがドラッグされた時の処理を記述します。jQuery UIのスライダーウィジェットは、slider()で利用でき、引数にスライダーの範囲と処理の内容を指定します。

 スライダーの最小値はmin、最大値はmax、デフォルトの値はvalueで設定します。ここでは、最大サイズ(max)を100に、デフォルトサイズ(value)を1にしました。

 スライダーがドラッグされた場合の処理はslideに、関数(イベントハンドラ)として記述します。関数にはイベントオブジェクトとスライダーオブジェクトが渡されます。スライダーの値はvalueに入っているので、brushSize変数にvalueを代入するとスライダーの位置に応じた値がブラシサイズとして設定されます。あとは、線を描くときにbrushSize変数の値をlineWidthに入れると、実際の線の幅を変更できます。ここまでのスライダーの処理は以下のようになります。


    $("#slider").slider({
        min: 0,
        max: 100, // ブラシの最大サイズ
        value : 1,  // 最初のブラシサイズ
        slide : function(evt, ui){
            brushSize = ui.value; // ブラシサイズを設定
        }
    });


 ただし、このままだとブラシサイズを変更したときに線の両端や連結部分が角ばってしまい、あまり美しくありません。一般的なお絵かきツールのように、角や連結部分を丸くしておきましょう。連結部分はlineJoinに"round"の文字を、角はlineCapに"round"を設定するとを丸くできます。


context.lineJoin= "round";
context.lineCap = "round";


fig6-1
スライダーで設定したブラシサイズで絵を描ける

サンプル06[HTML]


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>シンプルペイント</title>
        <link rel="stylesheet" href="css/jquery-ui-1.7.2.custom.css" type="text/css" media="all">
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
        <script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script>
        <script type="text/javascript" src="js/base64.js"></script>
        <script type="text/javascript" src="js/canvas2image.js"></script>
        <script type="text/javascript" src="js/draw.js"></script>
    </head>
    <body>
    <canvas id="myCanvas" width="640" height="480">
        HTML5 Canvasに対応したブラウザーを使用してください。
    </canvas>
    <div id="menu">
        <div id="slider"></div>
        <br>
        <button onclick="saveData()">保存</button>
    </div>
    <div id="colorPalet">
        <div id="black"></div>
        <div id="blue"></div>
        <div id="red"></div>
        <div id="magenta"></div>
        <div id="green"></div>
        <div id="cyan"></div>
        <div id="yellow"></div>
        <div id="white"></div>
    </div>
</body>
</html>



サンプル06[JavaScript:draw.js]


var drawFlag = false;
var oldX = 0;
var oldY = 0;
var brushSize = 1;
var colorList = {
    "black"   : "rgba(0,0,0,1)",
    "blue"    : "rgba(0,0,255,1)",
    "red"     : "rgba(255,0,0,1)",
    "magenta" : "rgba(255,0,255,1)",
    "green"   : "rgba(0,255,0,1)",
    "cyan"    : "rgba(0,255,255,1)",
    "yellow"  : "rgba(255,255,0,1)",
    "white"   : "rgba(255,255,255,1)"
}
var penColor = "rgba(255,0,0,1)";
window.addEventListener("load", function(){
    var can = document.getElementById("myCanvas");
    can.addEventListener("mousemove", draw, true);
    can.addEventListener("mousedown", function(e){
        drawFlag = true;
        oldX = e.clientX;
        oldY = e.clientY;
    }, true);
    can.addEventListener("mouseup", function(){
        drawFlag = false;
    }, true);
    // カラーパレット初期化
    $("#colorPalet div").click(function(e){
        penColor = colorList[this.id];
    });
    // ブラシサイズの設定を行うスライダー
    $("#slider").slider({
        min: 0,
        max: 100, // ブラシの最大サイズ
        value : 1,  // 最初のブラシサイズ
        slide : function(evt, ui){
            brushSize = ui.value; // ブラシサイズを設定
        }
    });
}, true);
// 描画処理
function draw(e){
    if (!drawFlag) return;
    var x = e.clientX;
    var y = e.clientY;
    var can = document.getElementById("myCanvas");
    var context = can.getContext("2d");
    context.strokeStyle = penColor;
    context.lineWidth = brushSize;
    context.lineJoin= "round";  // 連結部分を丸にする
    context.lineCap = "round";
    context.beginPath();
    context.moveTo(oldX, oldY);
    context.lineTo(x, y);
    context.stroke();
    context.closePath();
    oldX = x;
    oldY = y;
}
// 保存処理 (Canvas2Image)
// http://www.nihilogic.dk/labs/canvas2image/
function saveData(){
    var can = document.getElementById("myCanvas");
    Canvas2Image.saveAsPNG(can);    // PNG形式で保存
}

Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く