別のキャンバスガイド[4]:終わり

この部分で



[変換、



アニメーション

ピクセル操作]



変換



いくつかのメソッドを思い出してください



最初に、最後の章で言及した2つの方法を思い出す必要があります。

save-現在の状態をスタックの一番上に保存します

restore-スタックの先頭から状態を設定します

状態とは、変換マトリックス、描画領域、および次のプロパティ:strokeStyle、fillStyle、globalAlpha、lineWidth、lineCap、lineJoin、miterLimit、shadowOffsetX、shadowOffsetY、shadowBlur、shadowColor、globalCompositeOperation、font、textAlign、textBaselineです。



移動しましょう



translate(float x, float y)
      
      



-原点の現在位置を前の位置からxおよびyだけシフトします。

次の例を考えてみましょう。

 ctx.save() //  ctx.translate(100,100) //   ctx.textBaseline = 'top' ctx.font = "bold italic 30px sans-serif" ctx.strokeText(" ",0,0) //     (0;0),        ctx.restore() // ,     ,   
      
      





回しましょう





 rotate(float angle)
      
      



-横座標と縦座標を角度角度で回します。角度をラジアンで測定することも忘れないでください。角度を度からラジアンに変換するには、度をPiで乗算し、180で除算する必要があります:rad = deg * Math.PI // 180

たとえば、ctx.translate(100,100)の後に次の行を追加します。ctx.rotate(45 * Math.PI / 180)



減少/増加





 scale(float x, float y)
      
      



-x軸とy軸に新しいスケールを適用します。

たとえば、ctx.rotate(45 * Math.PI / 180)をctx.scale(0.65,1.5)に置き換えます

行列を掛ける



 transform(float m11, float m12, float m21, float m22, float dx , float dy)
      
      



-古い行列に新しい行列を掛けます。

マトリックスを適用





 setTransform(float m11, float m12, float m21, float m22, float dx , float dy)
      
      



-新しいマトリックスを適用します。たとえば、次のコードを見てください。

 var img = new Image(); img.onload = function(){ ctx.save() ctx.setTransform(1,0.5,0,1,1,1) ctx.drawImage(img,0,0,78,50) ctx.restore() } img.src = 'brick.jpg';
      
      





私はレンガの壁の写真を使用し、変形せん断しました

さらに、 Nutochkaトピックで変換について詳しく読むことができます。





作曲操作の種類





globalCompositeOperationプロパティは、合成操作のタイプを担当します。可能な値をすべてペイントできますが、 キャンバスのチートシートがあり、そこから画像の一部を表示する方が良いでしょう。 。





























GlobalAlphaプロパティ





globalAlphaプロパティ-実際、0 <= globalAlpha <= 1の場合にのみ、各画像の透明度に乗算される係数です。たとえば、次のコードを考えます。

 ctx.globalAlpha = 0.6; ctx.fillRect(0,0,100,100) ctx.fillRect(50,50,100,100)
      
      







アニメーション



requestAnimationFrame



以前のタイマーがアニメーションに使用されていた場合、特別なrequestAnimationFrame関数が表示され、トピックは既に説明されているため、azproductionから翻訳を読むことをお勧めします。



アニメーションの基本原理



アニメーションの基本原則は、古いフレームを消去して新しいフレームを描画することです。 古いフレームを消去する最も簡単な方法は、clearRect関数を使用することです。 たとえば、次のコードを考えて、最初にrequestAnimationFrame定義をコードに追加します。

 var x = 400, y = 300; (function loop(){ ctx.clearRect(0,0,800,600); ctx.beginPath(); ctx.arc(x++,y++,50,0,Math.PI*2,false); ctx.fill() requestAnimFrame(loop); })();
      
      





また、 トピックのアニメーションについては、 triciiから読むことができます。



1ゲーム!= 1キャンバス



キャンバスアクセラレーションに関するプレゼンテーションでこのルールを見て、これが最も単純なルールであることに気付きました。

各フレームで複雑な画像を描画する代わりに、この画像を仮想キャンバスに保存してからすべてのフレームで描画することができますが、すべてを仮想キャンバスに押し込む必要はなく、描画するために本当に複雑な形状(たとえば、テキストやグラデーション)を押し込むだけです) 例えば、私はjsperf.com小さなテストを行いましたが 、理想的ではありませんが、意味は明確だと思います。



ピクセルを操作する



キャンバスでは、高レベルのメソッドに加えて、ピクセルへの完全なアクセスもあります。これにより、すばらしいこと(フィルターなどを意味します)を実行でき、簡単なことを非常に迅速に描画できます。 ピクセルを操作するための特別なタイプのImageDataがあり、3つのプロパティwidth、height(説明する必要はないと思います)およびdata-rの配列、g、b、各ピクセルの値があります。

ピクセルデータの保存方法





前述のように、ピクセルデータは配列に格納されますが、配列内の要素の数はピクセル数x 4に等しくなります。すべての要素は0〜255の範囲の値を取ります。

アルファチャネルを含めると、0..255の値に保存されます。 この図は、4つの値r、g、bがセグメントを形成し、そのセグメントが1つのピクセルのパラメーターを格納する単一の分割不可能なセルであることを示しています。



空のImageDataを作成する



 ImageData = context.createImageData(int w, int h)
      
      



-幅がw、高さがhの空のImageDataを作成します。

 ImageData = context.createImageData(imageData)
      
      



-送信されたimageDataの幅と高さで空のImageDataを作成します。注:データはコピーされません。



ImageDataを使用する



 context.putImageData(imageData imgd, int x, int y)
      
      



-xyポイントからimageDataの幅と高さで領域内のキャンバスのピクセル配列を変更します。



簡単な例



しかし、十分な理論、ビジネスに取り掛かって、平滑化せずに関数y = x * xのグラフを描いてみましょう:

 var imgd = ctx.createImageData(800, 600); var x,y,segment,xround,yround; for (x=-40 ; x<=40 ; x+=0.01) { y = x*x; xround = ~~(x+0.5); yround = ~~(y+0.5); segment = ((-yround+400)*imgd.width + xround + 40)*4; imgd.data[segment+3] = 255; } ctx.putImageData(imgd, 0, 0);
      
      





パフォーマンスを比較するために、同様にjsperfでfillRectを使用して同様のコードを作成しましたが、 1つのポイントを描画するには、fillRectを使用する方が良いです。



ピクセル操作



 ImageData = context.createImageData(int x, int y, int w, int h)
      
      



-左上の頂点が(x; y)で、幅、高さw、hの長方形領域のキャンバスからのデータを含むimageDataオブジェクトを返します。 たとえば、写真の白い部分をハイライトしてみましょう。

 var img = new Image(); img.src = 'test.jpg'; //     img.onload = function(){ //netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); --      FireFox   ctx.drawImage(img, 0, 0, 160, 120); var imgd = ctx.getImageData(0, 0, 160, 120); // imageData for (var i=0 ; i<imgd.data.length ; i+=4) { imgd.data[i] = imgd.data[i+1] = imgd.data[i+2] = imgd.data[i] < 200 && imgd.data[i+1] < 200 && imgd.data[i+2] < 200 ? 0 : 255; //     } ctx.putImageData(imgd, 0, 0); //, ,     }
      
      






All Articles