2011年6月13日月曜日

Canvasで絵を書いてみる

さて、メモを操作するようなアプリを考えていて
初めはHTMLでゴリゴリと思っていたんですけど、
四角を書いてそれを線で結びたかったのでCanvasを使って絵を書こうと思いました。
JavaScript部分にはjQueryを使います。

まずはHTML上にCanvasを宣言します。
  1. <body id="body">  
  2.   <canvas id="canvas"></canvas>  
  3. </body>  


Canvasを一杯使いたいのでCanvasの要素を取得してきて
それをbodyタグと同じ大きさにします。

  1. var $cvm = $('#canvas');  
  2. var width = $(document.body).width();  
  3. var height = $(document.body).height();  
  4. $cvm.attr("width", width);  
  5. $cvm.attr("height", height);  


ウィンドウのサイズ変更されたら、、、って考えなきゃだめですね。
TODOにしとこう!

でキャンバスの基本設定

  1. var ctx = $cvm[0].getContext('2d');  
  2. ctx.lineWidth = 1;  
  3. ctx.globalAlpha = 0.7;  
  4. ctx.globalCompositeOperation = "source-over";  


getElementById() から取得してgetContext("2d")でもできるのですが
せっかくjQueryを使用しているのでjQueryのオブジェクトから取得。

lineWidthは線の太さ、globalAlhaは透明度ですね。
globalAlhaを設定した場合、globalCompositeOperationを設定します。

このglobalCompositeOperationってのは
ココが分かりやすいです。
文章よりサンプルがわかりやすいかも。

さて四角を書くのですが、それに対してテキストを入れてみます。
  1. ctx.font =textHeight + 'px "ヒラギノ角ゴ Pro"';  
  2. // 表示するテキストの幅を取得する  
  3. var textWidth = ctx.measureText(item.text).width;  
  4. //Itemの幅を設定する  
  5. item.width = textWidth;  
  6. // テキストの背景を描画  
  7. ctx.fillStyle = "white";  
  8. ctx.fillRect(item.x, item.y, item.width,textHeight);  
  9.   
  10. //テキストを描画  
  11. ctx.textBaseline = "bottom";  
  12. ctx.fillStyle = "black";  
  13. ctx.fillText(item.text, item.x, item.y + textHeight);  


まずContextのfontに対して文字列の大きさ(高さの数値で変数化してます)を設定しています。
その後、テキストの横幅を測っています。ContextのmeasureTextで測ってます。
item.widthというものに残していますがitemはテキストのオブジェクト(描画位置とか持ってる)を
再描画用に持っているので、それに残してるってだけです。(矩形描画時に使ってます)
色をfillStyleで設定してfillRect()で矩形を描画します。

その後、textBaselineでテキストの位置を設定してfillStyleで文字の色を設定して
fillText()で描画を行います。これで矩形内に文字列を埋め込みます。

で要素間を結合したいので、その座標に関して線を引きます。
今回は「ベジエ曲線」という線を使って要素を結合したいと思います。

  1. ctx.beginPath();  
  2. var point = new bezierPoint(preItem,item);  
  3. ctx.moveTo(point.x1,point.y1);  
  4. ctx.bezierCurveTo(point.x2,point.y1,point.x1,point.y2,point.x2,point.y2);  
  5. ctx.strokeStyle="#440000";  
  6. ctx.stroke();  


まずbeginPath()を呼びます。
これは線を描画する際に「さぁ始めるぞ!」っていう事を意味します。
その後、bezirePoint()を呼んでいますが、これは独自処理で線を引くための座標を算出しています。
それで取得してきたpoint(独自のオブジェクト)を元にmoveTo()によって開始点を設定します。
そこからbezierCurveTo()を利用して、終点を設定します。
6個引数がありますが、4つ目までは曲線の付加情報ですね。(もうちょっと凝る予定ですけど)
で5,6の引数が曲線の終点になります。
でstorokeStyleで色を決定し、stroke()で線を描画します。

これをやると



こんな感じになります。

ひとまず少し前に記述していたEvernoteの要素をそのまま出してみました!

0 件のコメント: