HTML5 Canvasで基本論理ゲート記号を描いてみた
MIL(軍事)規格の論理ゲート記号(もどき)をHTML5のcanvas要素に描いてみた。今回は、ORゲート、ANDゲート、NOTゲートの3つの基本論理ゲートだけを描いた。
ORゲートを描く
まずはORゲートを描いてみた。出来上がりは次のとおり。
ORゲートのためのHTMLとJavaScriptのソースコードは次のとおり。
<!DOCTYPE html> <html lang="ja"> <head> <title>HTML5 Canvasで論理ゲート記号を描く</title> </head> <body> <div style="text-align: center"> <canvas id="orGateSymbol" width="100" height="50"> あなたのブラウザはcanvas要素に対応していません。 </canvas> </div> <script> //特定のcanvas要素を取得して変数に代入 var canvas = document.getElementById("orGateSymbol"); //2次元描画コンテキストを取得して変数に代入 var context = canvas.getContext("2d"); //translate(x,y)メソッドで図形を平行移動できる context.translate(0, 0); //scale()メソッドで図形を上下左右に伸縮できる context.scale(1,1); /* ORゲートの本体部分の輪郭線を描く */ //輪郭線の太さ context.lineWidth = 2; //輪郭線の色 context.strokeStyle = 'black'; //パス(軌道)を初期化 context.beginPath(); //輪郭線を描き始める座標 context.moveTo(12,2); //本体上辺の輪郭曲線を2次ベジェ曲線を使って context.quadraticCurveTo(52,2,57,22); //本体下辺の輪郭曲線を2次ベジェ曲線を使って context.quadraticCurveTo(47,42,12,40); //本体左辺の輪郭曲線を2次ベジェ曲線を使って context.quadraticCurveTo(24,22,12,2); //closePath()メソッドでパスを閉じる context.closePath(); //stroke()メソッドで描画 context.stroke(); /* 本体に付属する3つの直線を描く */ //直線の太さ context.lineWidth = 1; //パス(軌道)を初期化 context.beginPath(); /*右端尾部の直線*/ //描き始める座標 context.moveTo(57,22); //直線の終点座標 context.lineTo(72,22); /*左端頭部の上側の直線*/ context.moveTo(0,10); context.lineTo(17,10); /*左端頭部の下側の直線*/ context.moveTo(0,32); context.lineTo(17,32); //パスを閉じずに描画 context.stroke(); </script> </body> </html>
canvas要素にはid属性と幅属性と高さ属性を指定した。幅と高さが小さすぎると描画されたオブジェクトがcanvas要素の枠内からはみ出して見えなくなってしまうので、最初は大きめに指定しておいたほうがよいかもしれない。
canvas要素に対応していないウェブ・ブラウザもしくはウェブ・ブラウザがJavaScriptを無効にしている場合は「あなたのブラウザはcanvas要素に対応していません」と表示させるようにした。
document.getElementById()メソッドでHTMLのcanvas要素を取得してcanvasという変数に代入した。同様にしてgetContext()メソッドで2Dのレンダリングコンテキストを取得してcontextという変数に代入した。この2文はHTML5 CanvasのAPIを利用する際に最初に記述するおまじないみたいなもの。
contextという変数名はハンガリー記法によってctxと略して記されていることも多い。
document.getElementById()メソッドの引数であるorGateSymbolは、HTMLソースのcanvas要素のid属性に対応付けられている。そのため、両者は同じ名前にする必要がある。
translate(x,y)メソッドはオブジェクトを平行移動させることができる。HTML5 Canvasの座標系は左上隅を原点(0,0)に置いている。左のx軸は原点から右横への直線距離、y軸は原点から下への直線距離。translate()メソッドの引数をxとy共に0としたのはここでは平行移動させないため。しかし回路図を描く際に必要になってくるメソッド。
scale(x,y)メソッドはオブジェクト全体の伸縮を行うためのもの。第1引数がx軸方向の伸縮度、第2引数がy軸方向の伸縮度。1が何も伸縮しない状態となり、1以上になると伸びて1以下になると縮まる。
次にORゲートの本体の輪郭線を描く。
lineWidthプロパティに線の太さを表わす値を代入。
strokeStyleプロパティには図形の輪郭線の色やグラデーションやパターンを指定できるが、ここでは輪郭線の色を表わす"black"という色名だけを代入した。色の指定方法としてこの他にカラー・コードがある。
次にbeginPath()メソッドを使ってパスの初期化を行った。パスとは、通り道、進路、軌道のこと。パスの初期化によってこれまでのパスの指定が
そしてmoveTo(x,y)メソッドによって輪郭線の描き始めの点となる座標をxとyの順に指定。
ORゲート本体の輪郭線である3辺の曲線は、quadraticCurveTo(x,y,x,y)メソッドを利用して2次ベジェ曲線でもって描いた。このメソッドは4つの引数を持っている。第1引数と第2引数で1辺の曲線を引っ張る制御点の座標位置をxとyの順に指定し、第3引数と第4引数でベジェ曲線の終点となる座標位置を指定するようになっている。第1引数と第2引数による制御点に向かって引っ張られる程度に応じてベジェ曲線の曲がり具合が決まる仕組み。
closePath()メソッドによってパスをここで一端閉じた。そしてstroke()メソッドを使って描画した。storoke()メソッドによってレンダリングしないかぎり、描いたものは表示されないことに要注意。
次にORゲートの本体のまわりにくっついている3つの直線を指定した。この直線の太さは本体の輪郭線の太さよりも細くしたいため、lineWidthプロパティに改めて値を代入しておいた。
beginPath()メソッドでパスを初期化し、moveTo(x,y)メソッドで描き始めの座標を決め、lineTo(x,y)メソッドで直線の終点を指定。3つの直線を描いてパスを閉じずにstroke()メソッドでレンダリング。
これでORゲートは描き終わった。
ANDゲートを描く
次にANDゲートのシンボルを描いてみた。出来上がりは次のとおり。
ANDゲートのためのHTMLとJavaScriptのソースコードは次のとおり。
<!DOCTYPE html> <html lang="ja"> <head> <title>HTML5 Canvasで論理ゲート記号を描く</title> </head> <body> <div style="text-align: center"> <canvas id="andGateSymbol" width="100" height="50"> あなたのブラウザはcanvas要素に対応していません。 </canvas> </div> <script> var canvas = document.getElementById("andGateSymbol"); var context = canvas.getContext("2d"); //translate(x,y)メソッドで図形を平行移動できる context.translate(0, 0); //図形を上下左右に伸縮 context.scale(1,1); /* ANDゲート本体部分の輪郭線を描く */ context.lineWidth = 2; context.strokeStyle = 'black'; context.beginPath(); //輪郭線の描き始めの座標 context.moveTo(17,3); //上の直線部分の終点座標 context.lineTo(38,3); //bezierCurveTo()メソッドで右横の曲線部分を context.bezierCurveTo(62,3,62,43,38,43); //下の直線部分の終点座標 context.lineTo(17,43); //左の直線部分の終点座標 context.lineTo(17,3); context.closePath(); context.stroke(); /* 付属する3つの直線を描く */ context.lineWidth = 1; context.beginPath(); //尾部の直線 context.moveTo(57,23); context.lineTo(72,23); //頭部の上側の直線 context.moveTo(0,11); context.lineTo(17,11); //頭部の下側の直線 context.moveTo(0,35); context.lineTo(17,35); //パスを閉じずに描画 context.stroke(); </script> </body> </html>
ANDゲートのためのHTMLソースはcanvas要素のid属性の名前だけがORゲートと異なるだけ。大事なのは、canvas要素のid属性とJavaScriptコード内のdocument.getElementById()メソッドの引数とが一致していること。canvas要素を同じHTMLソース内に複数置く場合、canvas要素のid属性が重複しないようにする必要もある。
ANDゲート本体の輪郭線は4つの辺からなる。その内の一辺では3次ベジェ曲線を使った。
3次ベジェ曲線はbezierCurveTo(x,y,x,y,x,y)メソッドによって描くことができる。その引数は6つある。最初のx,yが第1制御点、次のx,yが第2制御点、3番目のx,yがベジェ曲線の終点の座標となる。
ベジェ曲線についての幾何学的理論のことはよく分からないので、数値をいろいろと変えて試す作業を手探りで繰り返した。
その他の描き方についてはORゲートと同じ要領。ただし形が異なるので座標もいくらか異なる。
NOTゲートを描く
NOTゲートの出来上がりは次のとおり。
NOTゲートのためのHTMLとJavaScriptのソースコードは次のとおり。
<!DOCTYPE html> <html lang="ja"> <head> <title>HTML5 Canvasで論理ゲート記号を描く</title> </head> <body> <div style="text-align: center"> <canvas id="notGateSymbol" width="100" height="50"> あなたのブラウザはcanvas要素に対応していません。 </canvas> </div> <script> var canvas = document.getElementById("notGateSymbol"); var context = canvas.getContext("2d"); //translate(x,y)メソッドで図形を平行移動できる context.translate(0, 0); //図形を上下左右に伸縮 context.scale(1,1); /* NOTゲート本体の三角形の輪郭線を描く */ context.lineWidth = 2; context.strokeStyle = 'black'; context.beginPath(); //三角形を描く context.moveTo(15,3); context.lineTo(15,27); context.lineTo(35,15); context.lineTo(15,3); context.closePath(); context.stroke(); /* 尾部にくっついている円の輪郭線を描く */ context.beginPath(); //円を描くためのarc(x,y,)メソッドを使う context.arc(38,15,3,(Math.PI/180)*0, (Math.PI/180)*360); context.closePath(); context.stroke(); /* 本体に付属している3つの直線を描く */ context.lineWidth = 1; context.beginPath(); context.moveTo(42,15); context.lineTo(57,15); context.moveTo(0,15); context.lineTo(15,15); //パスを閉じずに描画 context.stroke(); </script> </body> </html>
NOTゲートの形とORゲートの形やANDゲートの形との違いは、円が加わっているところ。
円弧を描くためにarc()メソッドを使ってみた。その第1引数とその第2引数とで円の中心位置となる座標をxとyの順に指定する。第3引数には円の半径を指定する。第4引数には描き始める点を弧度法(ラジアン)でもって指定する。第5引数には描き終わる点を弧度法でもって指定する。
度数法の値から弧度法の値へ変換する公式は次のとおり。x度、yラジアンの場合。
この計算結果を浮動小数点数で指定する必要はなく、この公式をarc()メソッドの引数としてそのまま指定してやればいいので、始点のラジアンは(Math.PI/180)*0
とし、終点のラジアンは(Math.PI/180)*360
として完全な円を描くようにした。JavaScriptでは円周率をMath.PIと記す。
arc()メソッドの第6引数はオプションになっている。円弧を描く方向を反時計回りのときにはtrueと指定する必要があるが、省略したときにはデフォルト値のfalseとなり、円弧が時計回りに描かれる。
以上、3つの基本論理ゲートのシンボルをHTML5 CanvasのAPIを利用して描いてみた。その他の論理ゲートや論理回路図の描き方についてはまたの機会に。
コメント
コメントを投稿