一.Canvas の基本用法##
canvas は中国語で「画布」を意味し、<canvas> は HTML5 の新要素で、IE9+ がサポートしています
canvas 要素のデフォルトサイズは 300px * 150px で、最もシンプルなコードは透明な矩形��画布を生成します。例えば:
<canvas>
浏览器不支持 canvas
</canvas>
ブラウザがサポートしている場合、300px * 150px の透明ブロックは表示されません(透明なので、要素を検査することで見つかります)。ブラウザがサポートしていない場合、置換テキスト「浏览器不支持 canvas」が表示されます。例えば IE8 など。
画布があれば、何か描いてみたいものです。しかし canvas にとって最も簡単なのは直線を描くことではなく、空心/实心の矩形を描くことです。例えば:
<canvas id="my_canvas"> 浏览器不支持 canvas </canvas>
<script type="text/javascript">
var canvas = document.getElementById('my_canvas');
if(canvas.getContext){
var ctx = canvas.getContext('2d');//获取 2d 上下文
ctx.strokeStyle = '#f00';//边框设置为红色
ctx.lineWidth = 3;//线宽设置为 3px
ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';//填充半透明蓝色
ctx.strokeRect(0, 0, 50, 50);//描边
ctx.fillRect(0, 0, 50, 50);//填充
}
</script>
結果はこのようになります:
二.四角を描く、円を描く、線を描く##
矩形は上記ですでに描きました。コンテキストオブジェクトの描边と填充メソッドを使用しました。これ以外にも矩形に関するメソッドが 1 つあります:clearRect() パラメータの意味は同じで、矩形ブロックをくり抜く作用があります(透明色で指定領域を填充)
円を描くのは少し面倒です。例えば、中心が (30, 30)、半径が 20 の円を描く場合:
ctx.beginPath();//创建路径
ctx.arc(30,30,20,0,Math.PI*2,true);//设置弧线路径
ctx.closePath();//闭合路径
ctx.stroke();//描边
ctx.fill();//填充
arc(x, y, radius, startAngle, endAngle, counterclockwise) メソッドは弧線を描くために使用され、(x, y) を中心、radius を半径、startAngle と endAngle をそれぞれ開始角度と終了角度として表します。最後のパラメータは、前の 2 つの角度値が時計回りか反時計回りかを表し、false は時計回りを表します。
線を描くのは円を描くより簡単です((30, 30) から 50px の横線を描く):
ctx.beginPath();//创建路径
ctx.moveTo(30, 30);//把起点移动到 (30, 30)
ctx.lineTo(80, 30);//设置路径连接两点
ctx.closePath();//闭合路径
ctx.stroke();//绘制
線や弧が描ければ、三角形や五角形も問題ありません。上記で使用したパスメソッド 외에도、以下のメソッドがあります:
-
arcTo(x1, y1, x2, y2, radius):前の点から弧線を描き始め、(x2, y2) で終了し、指定された半径 radius で (x1, y1) を通ります
-
bezierCurveTo(c1x, c1y, c2x, c2y, x, y):ベジエ曲線、前の点から曲線を描き始め、(x, y) で終了し、(c1x, c1y) と (c2x, c2y) を制御点とします
-
quadraticCurveTo(cx, cy, x, y):二次ベジエ曲線、前の点から二次曲線を描き始め、(x, y) で終了し、(cx, cy) を制御点とします
-
rect(x, y, width, height):矩形パスを描画
パスを設定した後、fill() メソッドで填充するか、stroke() メソッドで描边できます。また、clip() メソッドを使用して下の描画を制限できます(PS の選択範囲に相当、詳細は W3School を参照)
三.画像を描く##
この機能は間違いなく最も重要です。シンプルな図形描画はあまり実用的ではありません(座標で肖像画を描いてみてください)
###1.画像のインポート##
- HTMLImageElement または別の canvas 要素への参照をソースとして取得するか、URL を提供して画像を使用できます
画像ソースは img、video、canvas 要素の参照にできます。もちろん、その場で作成した new Image() でも構いませんが、新しい Image オブジェクトの load イベントハンドラ内で参照する必要があることに注意してください。否则、画像が読み込み完了していないため、一部のブラウザでエラーが発生する可能性があります。もちろん、Base64 エンコードで画像ソースを使用することもできます。
- drawImage() 関数を使用して画像を画布に描画
-
drawImage(image, x, y):シンプルで明確な良いメソッド
-
drawImage(image, x, y, width, height):スケーリングをサポート
-
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):トリミングをサポート(大きな画像から小さな部分を切り出す、詳細は MDN を参照)
###2.画像のエクスポート##
これはもちろん画像操作よりも重要です。画布で長時間描いた後、それを画像としてエクスポートするにはどうすればよいでしょうか
canvas.toDataURL():画像 URL を返します。URL を直接 img の src に割り当てるだけで表示できます。通常の画像アドレスと同じように、どのようにでも使用できます。ただし注意が必要です:
-
画像は他のドメインから来てはいけません。ええ、そうです、またクロスドメインセキュリティ制限です。他のドメインから来た場合、toDataURL() メソッドはエラーをスローします
-
toDataURL メソッドは canvas のものであり、上記でずっと使用している ctx コンテキストオブジェクトのものではないことをよく確認してください。また、メソッド名の大文字小文字も特殊です
###3.画像操作##
canvas最も強力な機能は画像データを取得することです。画布上の各ポイントの色情報を取得できます。canvas がなければできますか?できません。したがって、シンプルな画像処理は現在 js で搞定でき、バックエンド関数の参加は必要ありません。
例えば、上文のスクリーンショットにシンプルな反色処理を行います:
var canvas = document.getElementById('my_canvas');
if(canvas.getContext){
var ctx = canvas.getContext('2d');//获取 2d 上下文
//画图
var img = document.images[0];
ctx.drawImage(img, 0, 0);
//获取 ImageData
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imgData.data;//获取 rgba(ImageData 的 data 属性是每个像素点的 rgba 值)
//反色
var r, g, b, a;
for(var i = 0, len = data.length;i < len; i+=4){
//取色
r = data[i];
g = data[i+1];
b = data[i+2];
//a = data[i+3];//反色不需要透明度
//反色
data[i] = 255 - r;
data[i+1] = 255 - g;
data[i+2] = 255 - b;
}
imgData.data = data;//写回图像数据
ctx.putImageData(imgData, 0, 0);//显示结果
}
処理効果は非常に素晴らしく、下図の通りです:
小さな問題に注意が必要です。Chrome は drawImage でローカル画像を描画することを許可していません。そのため、上記の結果は FF 下のものです。Ajax をテストするときも類似の問題に遭遇しました。FF は一般にクロスドメインセキュリティを制限する際にローカルリソースを制限しませんが、Chrome は制限します。サーバー上の同源リソースについては、このような差異は存在しません。
四.Canvas のさらなる機能##
グラデーション、パターン填充、線制御、影、回転、変形、スケーリング、合成、アニメーションなどのさらなる内容は、参考資料の MDN チュートリアルを参照してください
参考資料###
-
MDN チュートリアル:非常に素晴らしいチュートリアル
-
《JavaScript 高級程序设计》:図書館に返したくない良い本


コメントはまだありません