1. ImageDataオブジェクトの限界

ImageDataオブジェクトでは,回転や拡大縮小などの変形をすることが出来ません。そのため,回転や拡大を表現する場合は,ピクセル単位で計算して描画した画像を用意する必要があるようでした。しかし,Matlabのように行列計算を簡単に実現できないJavaScript環境では,実現が難しく感じていました。

以下のウェブサイトの情報を用いることで,この問題を解決できそうです。通常のcanvas要素の他に,ブラウザに描画しないcanvas要素をもう一つ用意しておき,そこにイメージデータとして配置し,それをリソースとしてdrawImageするという方法です。

JavascriptでImageData拡大縮小

この方法のもう一つの魅力的な点は,renderFunctionのループを回す前にイメージデータを用意しておき,ループ内では参照だけをするという方法が使えるところです。

2.描画しないCanvas要素の作成

「Script」に描画しないcanvas要素を作成します。ブラウザの表示領域の大きさを取得します。

新しいcanvas要素はctx2とします。

// canvasInvisibleに描画
canvasInvisible=document.createElement('canvas');
canvasInvisible.width=document.documentElement.clientWidth;
canvasInvisible.height=document.documentElement.clientHeight;
ctx2 = canvasInvisible.getContext('2d');

ctx2にImageObjectを作成します。今回は縞刺激を作成しました。

var imgData=ctx2.createImageData(200,200);
var imgd = imgData.data;
for (x=0; x<imgData.width;x+=1){
  for (y=0; y<imgData.height;y+=1){
    var i = (y * imgData.width + x) * 4;
    imgd[i+0]=Math.floor(Math.sin(x/4)*127+128);
    imgd[i+1]=Math.floor(Math.sin(x/4)*127+128);
    imgd[i+2]=Math.floor(Math.sin(x/4)*127+128);
    imgd[i+3]=255;
  }
}
ctx2.putImageData(imgData,0,0);

ガボール刺激を作成するときに使用する刺激です(詳しい説明は別のチュートリアルで)。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f29a6cf5-2de0-41e5-a7d7-4497b8d55369/Untitled.png

次は,レンダー関数内で回転角度を決める「rotate」と「drawImage」メソッドを使用します。

this.options.renderFunction = (t, canvas, ctx, obj) => {
  // このレンダー関数を使うことでcanvasに図形を描くことが出来ます。
  // t: timestamp この関数が呼び出された時刻
  // canvas: canvasオブジェクトへのレファレンス
  // ctx: 描画するコンテンツの情報(一番重要)
  // obj: 現在描画されているcanvasへの参照
  ctx.rotate( 45 * Math.PI / 180 ) ;	// 回転を実行
  ctx.drawImage(canvasInvisible, -imgData.width/2,-imgData.height/2);
}

これで,以下のように45度傾いた刺激が提示されます。