1. ホーム
  2. JavaScript

Canvasを使ったJavaScriptの描画

2022-02-19 21:42:54

Canvasを使ったJavaScriptの描画

    canvas 要素は、JavaScript でグラフィックを動的に描画するための領域をページ内に設定する役割を担っています。

I. 基本的な使い方

1. まず、描画領域のサイズを指定するために幅と高さを設定します。デフォルトでは透明になっています。getContext()メソッドで、描画コンテキストを取得する必要があります。

if(drawing.getcontext){ //check if the browser supports the canvas element
    var context=drawing.getContext("2d"); //Get the 2D context object
}

2. toDataURL()メソッドを使用して、画像のMIMEタイプのパラメータをアソートして、描画された画像を取得します。

var imgURL=drawing.toDataURL("image/png");

II. 2次元コンテキスト

1. 塗りつぶしとストローク

フィルは fillStyle プロパティを、ストロークは strokeStyle プロパティを使用します。プロパティの値(デフォルトは "#000000")には、文字列、グラデーションオブジェクト、またはパターンオブジェクトを使用できます。

context.strokeStyle="red"; //red stroke
context.fillStyle="#0000ff"; //blue fill

2. 矩形を描画する

fillRect() メソッド - 塗り付きの矩形、色は fillStyle プロパティで設定、塗りの透明度は rgba() フォーマットで設定できます。

strokeRect() メソッド - ボーダー付きの四角形で、色は fillStyle プロパティによって設定されます。

clearRect() メソッドは、キャンバス上の矩形領域をクリアするために使用されます。

これら3つのメソッドは、矩形を描くためによく使われるもので、いずれも4つのパラメータ(x,y,width,height)を持っています。

ストロークの線幅はlineWidthプロパティで制御します(値は整数です)。

線端の形状はlineCapプロパティで制御します(値:butt flat、round round、square)。

線の交差方法は lineJoin プロパティで制御します(値:ラウンドラウンド交差、ベベル対角交差、マイター対角結合)。

context.fillStyle="ff0000"; //rectangle fill is red
context.fillRect(10,10,50,50); //add a rectangle at (10,10) coordinates with width 50, height 50 and color fill
context.fillStyle="rgba(0,0,255,0.5)"; //set the rectangle to blue, 50% transparency
context.clearRect(40,40,10,10); //set a transparent rectangle with width and height of 10 at (40,40) coordinates

3. パスを描く

    2D描画では、パスを用いて複雑な形状や線を作成することができます。まずbeginPath()メソッドを呼び出して、新しいパスの描画を開始します。その後、以下のメソッドを呼び出すことでパスが作成されます。

arc(x, y, radius, startAngle, endAngle, counterclockwise): (x, y) を中心、半径 radius、開始角度と終了角度、反時計回りを真とした反時計回り。

arcTo(x1, y1, x2, y2, radius): 直前の点から (x2, y2) まで、そして (x1, y1) を通る弧を、与えられた半径 radius で描画する。 

bezierCurveTo(c1x, c1y, c2x, c2y, x, y): 前の点から (x, y) まで、 (c1x, c1y) と (c2x, c2y) を制御点とする曲線を描画します。 

lineTo(x, y): 直前の点から (x, y) までの直線を引く。

moveTo(x, y): 線を描かずに描画カーソルを (x, y) に移動させる。

quadraticCurveTo(cx, cy, x, y): (cx, cy) を制御点として、前の点から (x, y) まで二次曲線を描きます。

rect(x, y, width, height): 点 (x, y) からの矩形の幅と高さを設定し、このメソッドは矩形のパスを描画する。

closePath()を呼び出すと、パスの始点に接続する線が描かれる。

fill()メソッドを呼び出すと、fillStyleで塗りつぶすことができます。

stroke()メソッドを呼び出すと、strokeStyleを使用してパスを描画することができます。

clip()メソッドを呼び出すと、パス上にクリッピング領域を作成することができます。 

context.arc(100,100,99,0,2*Math.PI,false); //draw a circle with (100,100) as the center and a radius of 99
context.moveTo(100,100); //move the coordinates to (100,100)
context.lineTo(100,15); // draw a line from (100,100) to (100,15)
context.stroke(); //stroke the path

isPointInPath() は、パスが閉じられる前に、キャンバス上の点がパス上にあるかどうかを判断します。

4. テキストの描画

    fillText()メソッドはfillStyleプロパティを使ってテキストを描画し、strokeText()メソッドはstrokeStyleプロパティを使ってテキストをストロークします。これらは4つのパラメータ、テキスト文字列、x、y座標、最大ピクセル幅を取ります。これらは、テキスト文字列、x,y座標、最大ピクセル幅の4つの引数を取り、いずれも以下の3つのプロパティを持ちますが、基本的にはCSSと同じです。

font: テキストスタイル、サイズ、フォント、CSSと同じ

textAlign: テキストアライメント。値は "start", "end", "left", "right" そして "center" です。テキストの開始点には"start:x座標、終了点には"end"を使用することをお勧めします。

textBaseline: テキストのベースライン。値は "top: テキストの上部のy座標", "hanging", "middle", "alphabetic" です。

context.font="bold 16px Arial"; //bold, 16px size, Arial font
context.textAlign="center"; //x in the middle of the text (center-aligned)
context("hello",100,20); //write in (100,20): hello everyone

measureText()メソッドを使用すると、引数に計算対象のテキスト文字を指定し、テキストの幅を出力することができます。

var textwidth = context.measureText("Hello! ").width; //measure the width of the Hello! text px

5.トランスフォーム

    処理した画像は、transformをコンテクスト化することで、キャンバスに描画することができます。異なる変換マトリクスを使用すると、異なる結果が得られます。変換行列は以下の方法で変更することができます。
rotate(angle)。原点を中心に画像を角度ラジアン単位で回転させる。

scale(scaleX, scaleY): 画像を1/4に縮小する。

translate(x, y):原点を(x, y)に移動する。

transform(m1_1, m1_2, m2_1, m2_2, dx, dy): 変換行列に次の行列を掛けて直接修正します.

setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy): トランスフォーム行列をデフォルトの状態にリセットし、再度 transform() を呼び出します。

save()を呼び出すとスタック構造体に設定が保存され、restore()メソッドを呼び出すと前に保存した設定に戻ります。

6. 画像の描画

    画像は、drawImage()メソッドを用いて、3つの方法のいずれかでキャンバスに描画することができます。

context.drawImage(document.images[0],10,10); // pass the first image to the canvas, starting at (10,10)
context.drawImage(document.images[0],50,10,20,30); // start at (50,10), size 20*30 pixels
context.drawImage(image,0,0,30,30,40,0,15,15); //cut the image and position the cut part on the canvas


    画像をクリッピングするメソッド:context.drawImage(img,sx,sy,swidth,height,x,y,width,height)を使用します。

    このメソッドのパラメータは、順に、切り抜き開始点 (sx,sy) 切り抜き幅 高さ 画像を置く位置 (x,y) 画像幅 高さです。

7. シャドウ

   コンテキストの以下のプロパティは、シェイプやパスの影を設定します。

shadowColor: CSSカラーフォーマットによる影の色、デフォルトは黒

shadowOffsetX: X軸方向のシャドウオフセット、デフォルトは0

shadowOffsetY: Y軸のシャドウオフセット、デフォルトは0

shadowBlur: ぼかすピクセル数。デフォルトは0、つまりぼかしなし。 

context.shadowOffsetX=2; //shadow in x-direction is 2px
context.shadowOffsetY=2; //shadow in y direction is 2px
context.shadowBlur=1; //Blur value is 1
context.shadowColor="rgba(0,0,0,0.2)" //black shadow with 20% transparency

8. グラデーション

1. createLinearGradient() メソッドで、開始 (x,y) と終了 (x,y) のパラメータを指定して、新しい線形グラデーションを作成します。

   addColorStop()メソッドでカラースケールを指定:パラメータは①カラースケール(0~1)②カラー

var gradient = context.createLinearGradient(30,30,50,50); //fill from (30,30) to (50,50)
gradient.addColorStop(0,"white"); //start color is white
gradient.addColorStop(1,"black"); //the end color is black
context.fillStyle = gradient; //use gradient fill

2. createRadialGradient()メソッドを使用して、開始座標と円半径、終了座標と円半径の6つの引数で放射状グラデーションを作成します。

var gradient = context.createRadialGradient(30,30,10,30,30,30,20); // concentric circle gradient

9. モード

   パターンとは、グラフィックの塗りつぶしやストロークに使用できる、繰り返される画像のことです。HTML の <img> 要素と background-repeat 属性の値で、 "repeat", "repeat-x", "repeataty" と "no-repeat" が含まれます。

    パターンは (0,0) から繰り返され、塗りつぶしスタイルはキャンバスの領域の繰り返し画像を表示します。

pattern = context.createPattern(image,"repeat"); 
context.fillStyle = pattern; 

10. 画像データの利用

     画像のパラメータ(x,y,width,height)を指定して、getImageData()で元の画像データを取得します。dataは、画像の各ピクセルのデータを保持する配列です。各ピクセルは、赤、緑、青、透明度の値を表す4つの要素で保存されます。したがって、最初のピクセルのデータは、配列の0番目から3番目の要素に格納されます。

var data = imageData.data,
    red=data[0],
    green=data[1],
    blue=data[2],
    alpha=data[3]; //Get the red, green, blue and transparency of the first pixel of the image

11. コンポジット

    globalAlpha属性は、グローバルな透明度を設定するためのものです。

III. WebGL

    WebGLはCanvasのための3Dコンテキストです

1. 型付き配列

    型付き配列も配列の一種ですが、その要素には型固有の値が設定されます。 

ArrayBufferは、メモリ上に一定のバイト数を確保することができ、そのバイト数はbyteLengthプロパティで取得することができる。

var buffer = new ArrayBuffer(20); //allocate 20B of memory
var bytes = buffer.byteLength;    

1. 表示

ArrayBufferを使用して、ArrayBufferデータセグメントを抜粋するDataViewのような配列バッファビューを作成することができます。配列バッファは、そのbufferプロパティを通じて取得することもできます。

var view = new DataView(buffer,8,10); //Start at byte 8 and end at byte 18.
view.byteOffset; //byte offset 8 exists in byteOffset
view.byteLength; //byte length exists in byteLength

DataViewを読み書きする場合、対応するgetterとsetterメソッドを使用し、第1引数にバイトオフセットを指定します。setメソッドの第2引数に設定する番号を指定し、getの第2引数に小端末バイトオーダーを使用するかどうか指定します。

getInt8() setInt8() getUnit8() setUnit8()

getInt16(,) setInt16(,) getUnit16(,) SetUnit16(,) は、32ビット、またはFloat32、Float64も可能です。

2. 型付きビュー

    型付き配列にはいくつかの種類があり、それらはすべてDataViewを継承しています。

Int8Array。8 ビット 2 の補数 Uint8Array: 8 ビット符号なし整数 Int16Array: 16 ビット 2 の補数 Uint16Array: 16 ビット符号なし整数

Int32Array: 32 ビット 2 の補数 Uint32Array: 32 ビット符号なし整数 Float32Array: 32 ビット IEEE 浮動小数点数 Float64Array: 64 ビット IEEE 浮動小数点数

   コンストラクタを使用して、パラメータをインスタンス化します。ArrayBuffer オブジェクト、開始点のバイトオフセット(デフォルトは 0)、含めるべきバイト数。

var int16s = new Int16Array(buffer,9,10); //use a buffer from byte 9 to byte 18

II. WebGLのコンテキスト

   WebGL コンテキストを取得すると、通常、WebGL コンテキスト オブジェクトに gl という名前を付けて 3D 描画を開始することができます。getContext() の第 2 パラメータに渡すことで、WebGL コンテキストにいくつかのオプションを設定できます。このパラメータはそれ自体がオブジェクトであり、以下のプロパティを含むことができますが、通常は設定する必要はありません。

    alpha: コンテキストにアルファチャンネルバッファを作成する場合は true depth: 16 ビットの深さのバッファを使用する場合は true

    stencil: 8ビットステンシルバッファを使用する場合はtrue antialias: アンチエイリアスのデフォルト機構を使用する場合はtrue

    premultipliedAlpha: 描画バッファにプリマルチプライドアルファ値があるとき true reserveDrawingBuffer: 描画完了後に描画バッファを予約するとき true。

if(drawing.getContext){ // whether getContext is supported
    var gl = drawing.getContext("experimental-webg1"),{alpha:false}; //create the context
    if(gl){
    //use WebGL
} }

1. 定数

2. メソッドの命名。メソッド名のサフィックスには、引数の数(1〜4)と受け取るデータの種類(fは浮動小数点、iは整数、vは配列)が入ります。例えば、gl.uniform4fのようになります。

3. 3. clearColor(,,,) メソッドを使用して、赤、緑、青、透明度をパラメータとし、0から1までの値を持つ何らかの実色で、<canvas>をクリアします。

gl.clearColor(0,0,0,1); //clear the canvas with black

4. ビューポートと座標

viewport()メソッドを呼び出すと、x、y、width、height(<canvas>要素に対するビューポートの相対値)の4つのパラメータでビューポートサイズを変更することが可能です。

ビューポート座標の原点(0,0)は<canvas>要素の左下隅で、x軸とy軸の正の方向はそれぞれ右と上になります。

g1.viewport(0,0,drawing.width/2,drawing.height/2); //Viewport is in the lower left corner of the canvas 1/4

5. バッファー

    バッファの作成: gl.createBuffer() を呼び出し、gl.bindBuffer() を使用して WebGL コンテキストにバインドします。

var buffer = gl.createBuffer(); //create buffer
gl.bindBuffer(gl.ARRAY_BUFFER,buffer); //set buffer to the context's current buffer
gl.bufferData(fl.ARRAY_BUFFER,new Float32Array([0,0.5,1]},gl.STATIC_DRAW);


drawElements(gl.ELEMENT_ARRAY_BUFFER) でバッファの中身を出力することができます。

gl.bufferData()の最後の引数は、バッファの使用方法を指定するためのもので、以下の値を取ることができます。
gl.STATIC_DRAW: データは一度だけロードされ、複数のプロットで使用されます。    STREAM_DRAW: データは一度だけロードされ、複数のプロットで使用される。

6.エラー

WebGL の操作は一般にエラーを投げません。エラーの種類は gl.getError() メソッドを呼び出すことで知ることができます。

gl.NO_ERROR: はい、値は 0 です gl.INVALID_ENUM: WebGL 定数がメソッドに渡される必要があります gl.INVALID_VALUE: 符号なし数値があるところに負の値が渡された。 

gl.INVALID_OPERATION: 現在の状態では操作を完了できない gl.OUT_OF_MEMORY: メモリが不足している  

gl.CONTEXT_LOST_WEBGL: 外部イベント(デバイスの電源障害など)の干渉により、現在のWebGLコンテキストが失われました。

var errorCode = gl.getError();
while(errorCode){
    console.log("Error occurred:"+errorCode); // Call getError in a loop until it is correct
    errorCode = gl.getError();
}    

7. シェーダーには、バーテックスシェーダーとフラグメント(またはピクセル)シェーダーという2つの種類があります。バーテックスシェーダは、3D 頂点をレンダリングに必要な 2D 点に変換するために使用されます。フラグメントシェーダーは、描画される各ピクセルの色を正確に計算するために使用されます。これらのシェーダーは、GLSL(OpenGLシェーディング言語)を使用して記述されています。

8. シェーダーの書き方:GLSL言語

    各シェーダは main() メソッドを持ちます。 attribute (頂点シェーダ) と uniform (任意のシェーダに定数を渡す) は main メソッドの外部で定義されます。
main()メソッドは外部で定義されます。

attribute vec2 aVertexPosition; //vertex shader
void main(){
    gl_Positon = vec4(aVertexPosition,0.0,1.0); //transform 2D to 3D coordinates
}

9. シェーダープログラムの作成

    ページの <script> タグの中にシェーダーを入れ、そのタグに custom type 属性を指定するのが一般的です。

10. ドローイング

    WebGL では、点、線、三角形の 3 種類の図形しか描画できません。  配列バッファには gl.drawArrays() メソッドが、要素配列バッファには gl.drawElements() メソッドが使用されます。第1引数は描画する図形を示し、その値は

gl.POINTS: 各頂点は点である gl.LINES: これらの頂点間を線で結ぶ gl.LINE_LOOP: 頂点同士を結ぶ、アウトラインを描く

gl.LINE_STRIP: 頂点を結ぶが、最後の頂点は最初の頂点とつながっていない gl.TRIANGLES: 頂点間に三角形を描画する

gl.TRIANGLES_STRIP: 三角形の間に接続された頂点を持つ三角形 gl.TRIANGLES は三角形の間に接続されたエッジを持つ三角形を描画します。

11. テクスチャ

gl.createTexture()を呼び出して新しいテクスチャを作成し、そのテクスチャに画像をバインドします。

12. ピクセルの読み込み

ピクセル値を読み取る readPixels() メソッドは OpenGL の同名のメソッドと一点だけ異なり、最後の引数は型付き配列でなければならないことです。