キャンバスで遊び中 - マウスカーソル下の色を表示


http://www.fujidig.com/misc/js/canvas/additive-color.html
getImageData や opera-2dgame の getPixel で色を取得できると知ったのでやったみた。
キャンバスで遊び中 - 光の三原色 - fujidigの雑記を改造。
あと Color クラスとか作った。どうみても車輪の再発明

var Color = function Color(r, g, b, a) {
	this.r = r & 255;
	this.g = g & 255;
	this.b = b & 255;
	this.a = a;
	if (typeof (this.a) == 'undefined') {
		this.a = 1;
	}
	if (this.a > 1) {
		this.a = 1;
	}
	if (this.a < 0) {
		this.a = 0;
	}
}

Color.prototype.toRGBAString = function toRGBAString() {
	return 'rgba('+this.r+','+this.g+','+this.b+','+this.a+')';
}

Color.prototype.toRGBString = function toRGBString() {
	return 'rgb('+this.r+','+this.g+','+this.b+')';
}

Color.prototype.toHexString = function toHexString() {
	return '#' + (0x1000000 | this.r << 16 | this.g << 8 | this.b).toString(16).slice(1);
}

Color.prototype.toString = function toString() {
	if (this.a == 1) {
		return this.toRGBString();
	} else {
		return this.toRGBAString();
	}
}

Color.parse = function parse(string) {
	var m;
	if (m = string.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/)) {
		if (m[1].length == 3) {
			var code = parseInt(m[1], 16);
			var r = code >> 8 & 15, g = code >> 4 & 15, b = code & 15;
			r |= r << 4, g |= g << 4, b |= b << 4;
			return new Color(r, g, b);
		}
		var code = parseInt(m[1], 16);
		return new Color(code >> 16 & 255, code >> 8 & 255, code & 255);
	}
	if (m = string.match(/^rgb\((\d+),(\d+),(\d+)\)$/)) {
		return new Color(parseInt(m[1], 10),
		                 parseInt(m[2], 10),
		                 parseInt(m[3], 10));
	}
	if (m = string.match(/^rgba\((\d+),(\d+),(\d+),(.*)\)$/)) {
		return new Color(parseInt(m[1], 10),
		                 parseInt(m[2], 10),
		                 parseInt(m[3], 10),
		                 parseFloat(m[4]));
	}
	return null;
}

var canvas = document.body.appendChild(document.createElement('canvas'));
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'lighter';
for( var i = 0; i < 3; i ++) {
	var rad = Math.PI*2/3*i;
	var x =  Math.sin(rad) * 33 + 100;
	var y = -Math.cos(rad) * 33 + 100;
	var radgrad = ctx.createRadialGradient(x, y, 0, x, y, 60);
	var color = [0,0,0];
	color[i] = 255;
	color[3] = 1;
	radgrad.addColorStop(0.6, 'rgba('+color.join(',')+')');
	color[3] = 0;
	radgrad.addColorStop(1.0, 'rgba('+color.join(',')+')');
	ctx.fillStyle = radgrad;
	ctx.fillRect(0,0,canvas.width,canvas.height);
}

var div = document.body.appendChild(document.createElement('div'));
canvas.addEventListener('mousemove',function(e){
	var x, y;
	if (typeof(e.offsetX) != 'undefined') {
		x = e.offsetX;
		y = e.offsetY;
	} else {
		x = e.pageX - this.offsetLeft;
		y = e.pageY - this.offsetTop;
	}
	var color;
	if (window.opera) {
		color = Color.parse(canvas.getContext('opera-2dgame').getPixel(x, y));
	} else {
		var data = ctx.getImageData(x, y, 1, 1).data;
		color = new Color(data[0], data[1], data[2], data[3] / 255);
	}
	while(div.lastChild) {
		div.removeChild(div.lastChild);
	}
	div.style.backgroundColor = color.toString();
	if ( (0.298912 * color.r + 0.586611 * color.g + 0.114478 * color.b) >= 128) {
		div.style.color = 'black';
	} else {
		div.style.color = 'white';
	}
	div.appendChild(document.createTextNode(x+', '+y+' : '+color));
},false);