
Canvas+JavaScriptでグラデーションの画像を作った話
はじめに
こんな画像を作ってみたかったので、htmlのcanvasとjavascript(typescript)で作成しました。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>canvas test page</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
canvas要素をjavascriptで操作するため、idで名前を付けておきます。
javascriptはcanvasが読み込まれた後に実行されるようにしておきます。今回はcanvasの後にscriptでjavascriptを読み込むようにしました。
main.js
"use strict";
let rgb2hex = function (r, g, b) {
return "#" + ("000000" + (r * 256 * 256 + g * 256 + b).toString(16)).slice(-6);
};
let cvs = document.getElementById("canvas");
let ctx = cvs.getContext('2d');
cvs.width = 256;
cvs.height = 256;
for (let i = 0; i < 256; i++) {
for (let j = 0; j < 256; j++) {
ctx.fillStyle = rgb2hex(255 - i, 255 - j, Math.round((i + j) / 2));
ctx.fillRect(i, j, 1, 1); // 四角描写(x,y,w,h)
}
}
canvas上の色を色コード(#FFFFFFなど)で指定するため、rgbを色コードに変換する関数を作っています。0~255のRGBの値を基に0~65535の値を生成し、これをtoString(16)で16進数の文字列(0~FFFFFF)に変換。16進数の文字列の桁が足りない場合を考慮して、左に0を6つつけた後、slice(-6)で右から6文字を切り出しています。例えばR=0、G=1,B=2の場合、10進の値は0*256*256+1*256+2=258、16進の文字列は102、”000000102”の右から6文字を取って000102となります。
document.getElementByIdでキャンバス要素のIDを指定し、getContext('2D')でcanvasを操作する変数を作るまでがお作法。
canvasの縦と横幅を.widthと.heightで指定。
ctx.fillStypeで色を指定後、ctx.fillRectで四角を描写するので、fillRectを1ピクセルずつ指定するため(x,y,1,1)とし、x,yをfor文の二重ループで回します。各ピクセルの色を(r,g,b)=(255-x, 255-y, (x+y)/2)となるように記載。
main.ts
TypeScriptの記載は下記の通り
let rgb2hex = function(r:number, g:number, b:number):string {
return "#" + ("000000" + (r*256*256 + g*256 + b).toString(16)).slice(-6)
}
let cvs = <HTMLCanvasElement> document.getElementById( "canvas" ) ;
let ctx = <CanvasRenderingContext2D>cvs.getContext('2d');
cvs.width = 256;
cvs.height = 256;
for(let i:number = 0; i < 256; i++){
for(let j:number = 0; j < 256; j++){
ctx.fillStyle= rgb2hex(255-i,255-j,Math.round((i+j)/2));
ctx.fillRect( i, j, 1, 1 ); // 四角描写(x,y,w,h)
}
}