秋なので Canvas に絵を描いてみた

朝夕はすごく涼しくなりましたね。むしろ寒いくらいです。もうすっかり秋ですね。秋だけに、絵を描いてみたくなりました。ただし、使うキャンバスは絵画用じゃなく、HTML5 のものですけど。

線を引くところから初めて、画像を表示するまで、一通り試したコードがこちら。

<!DOCTYPE html>
<html>
    <head>
        <title>Canvas Sample</title>
    </head>
    <body>
        <h1>Canvas Sample</h1>

        <div>
            <h2>線で矩形を描く</h2>
            <canvas id="strokeRect" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("strokeRect");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.beginPath();
                    ctx.moveTo(20, 20);
                    ctx.lineTo(120, 20);
                    ctx.lineTo(120, 120);
                    ctx.lineTo(20, 120);
                    ctx.closePath();
                    ctx.stroke();
                })();
            </script>
        </div>

        <div>
            <h2>線で矩形を描く(塗りつぶし)</h2>
            <canvas id="fillRect" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("fillRect");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.beginPath();
                    ctx.moveTo(20, 20);
                    ctx.lineTo(120, 20);
                    ctx.lineTo(120, 120);
                    ctx.lineTo(20, 120);
                    ctx.closePath();
                    ctx.fill();
                })();
            </script>
        </div>

        <div>
            <h2>矩形を描く</h2>
            <canvas id="strokeRect2" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("strokeRect2");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.strokeRect(20, 20, 100, 100);
                })();
            </script>
        </div>

        <div>
            <h2>矩形を描く(塗りつぶし)</h2>
            <canvas id="fillRect2" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("fillRect2");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.fillRect(20, 20, 100, 100);
                })();
            </script>
        </div>

        <div>
            <h2>円を描く</h2>
            <canvas id="strokeArc" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("strokeArc");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.beginPath();
                    ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
                    // arc は strokeRect と違って線が引かれないので、
                    // stroke を呼び出す必要あり
                    ctx.stroke();
                })();
            </script>
        </div>

        <div>
            <h2>円を描く(塗りつぶし)</h2>
            <canvas id="fillArc" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("fillArc");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.beginPath();
                    ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
                    // arc は fillRect と違って線が引かれないので、
                    // fill を呼び出す必要あり
                    ctx.fill();
                })();
            </script>
        </div>

        <div>
            <h2>線の色を指定する</h2>
            <canvas id="strokeStyle" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("strokeStyle");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.strokeStyle = "rgb(255, 0, 0)";
                    ctx.beginPath();
                    ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
                    ctx.stroke();
                })();
            </script>
        </div>

        <div>
            <h2>塗りつぶす色を指定する</h2>
            <canvas id="fillStyle" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("fillStyle");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    ctx.fillStyle = "rgb(255, 0, 0)";
                    ctx.beginPath();
                    ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
                    ctx.fill();
                })();
            </script>
        </div>

        <div>
            <h2>縦方向のグラデーション</h2>
            <canvas id="verticalLinearGradient" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("verticalLinearGradient");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    // グラデーション領域の作成
                    var grad = ctx.createLinearGradient(0, 0, 0, 140);
                    // グラデーションに使う色を指定
                    grad.addColorStop(0, "rgb(255, 0, 0)");
                    grad.addColorStop(0.5, "rgb(0, 255, 0)");
                    grad.addColorStop(1, "rgb(0, 0, 255)");
                    // グラデーションで塗りつぶす
                    ctx.fillStyle = grad;
                    ctx.fillRect(0, 0, 140, 140);
                })();
            </script>
        </div>
        
        <div>
            <h2>横方向のグラデーション</h2>
            <canvas id="horizontalLinearGradient" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("horizontalLinearGradient");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    // グラデーション領域の作成
                    var grad = ctx.createLinearGradient(0, 0, 140, 0);
                    // グラデーションに使う色を指定
                    grad.addColorStop(0, "rgb(255, 0, 0)");
                    grad.addColorStop(0.5, "rgb(0, 255, 0)");
                    grad.addColorStop(1, "rgb(0, 0, 255)");
                    // グラデーションで塗りつぶす
                    ctx.fillStyle = grad;
                    ctx.fillRect(0, 0, 140, 140);
                })();
            </script>
        </div>

        <div>
            <h2>円形のグラデーション</h2>
            <canvas id="radialGradient" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("radialGradient");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    // グラデーション領域の作成
                    var grad = ctx.createRadialGradient(70, 70, 0, 70, 70, 70);
                    // グラデーションに使う色を指定
                    grad.addColorStop(0, "rgb(255, 0, 0)");
                    grad.addColorStop(0.5, "rgb(0, 255, 0)");
                    grad.addColorStop(1, "rgb(0, 0, 255)");
                    // グラデーションで塗りつぶす
                    ctx.fillStyle = grad;
                    ctx.beginPath();
                    ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
                    ctx.fill();
                })();
            </script>
        </div>

        <div>
            <h2>画像を表示</h2>
            <canvas id="drawImage" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("drawImage");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    var img = new Image();
                    // 画像の読み込みが終わってから表示する
                    img.onload = function() {
                        ctx.drawImage(img, 0, 0);
                    };
                    // 確実に onload が発生するようにタイムスタンプをくっつける
                    img.src = "sample1.png?" + new Date().getTime();
                })();
            </script>
        </div>

        <div>
            <h2>画像を表示(トリミング)</h2>
            <canvas id="drawImage2" width="140" height="140"></canvas>
            <script type="text/javascript">
                (function(){
                    var canvas = document.getElementById("drawImage2");
                    if (!canvas || !canvas.getContext) {
                        return false;
                    }
                    var ctx = canvas.getContext("2d");
                    var img = new Image();
                    // 画像の読み込みが終わってから表示する
                    img.onload = function() {
                        ctx.drawImage(img,
                                      50, 50, 30, 30,   // 元画像の(30,30)の座標から幅15×高さ15で切り取り
                                      10, 10, 100, 100);// (10,10)の座標から幅100×高さ100で表示
                    };
                    // 確実に onload が発生するようにタイムスタンプをくっつける
                    img.src = "sample2.png?" + new Date().getTime();
                })();
            </script>
        </div>
    </body>
</html>

canvas 要素からコンテキストを取得し、それを使って描画する、というのが基本的な流れ。

ブラウザで表示したときのスクリーンショットも貼っておきます。
f:id:griefworker:20111018200627p:image
絵というよりも図形といった方が適切な気がしますけど、大目に見てください。

それにしても、Canvas は画像を表示するだけでなく、トリミングまでできるので、なかなかパワフルです。ゲームとか実装してみたいですね。