我正在尝试使用Canvas实现ColorPicker只是为了好玩。但我似乎输了。由于所有这些for循环,我的浏览器在加载时会冻结一段时间。
我正在添加此脚本结果的屏幕截图:
window.onload = function(){
colorPicker();
}
function colorPicker(){
var canvas = document.getElementById("colDisp"),
frame = canvas.getContext("2d");
var r=0,
g=0,
b= 0;
function drawColor(){
for(r=0;r<255;r++){
for(g=0;g<255;g++){
for(b=0;b<255;b++){
frame.fillStyle="rgb("+r+","+g+","+b+")";
frame.fillRect(r,g,1,1);
}
}
}
}
drawColor();
目前,我只想要一个关于冻结问题的解决方案,使用更好的算法,并且它不显示黑色和灰色。 请有人帮助我。
答案 0 :(得分:2)
不是为每个像素调用fillRect,而是使用原始RGBA缓冲区可能效率更高。您可以使用context.getImageData获取一个,使用颜色值填充,然后使用context.putImageData将其重新放回去。
请注意,您当前的代码会覆盖每个单个像素255次,每个可能的蓝色值一次。每个像素的最终传递是255蓝色,因此您在输出中看不到灰色和黑色。
找到将所有可能的RGB值映射到二维图像的好方法并非易事,因为RGB是一个三维色彩空间。这样做有很多策略,但对于任何可能的用例,没有一个是最佳的。您可以在AllRGB.com找到针对此问题的一些创意解决方案。其中一些可能适合某些用例的颜色选择器。
答案 1 :(得分:2)
如果要在鼠标下获取像素的rgba,则必须使用context.getImageData。
getImageData返回一个像素数组。
var pixeldata=context.getImageData(0,0,canvas.width,canvas.height);
每个像素由4个连续的数组元素定义。
所以如果你有一个带有getImageData的像素数组:
// first pixel defined by the first 4 pixel array elements
pixeldata[0] = red component of pixel#1
pixeldata[1] = green component of pixel#1
pixeldata[2] = blue component of pixel#1
pixeldata[4] = alpha (opacity) component of pixel#1
// second pixel defined by the next 4 pixel array elements
pixeldata[5] = red component of pixel#2
pixeldata[6] = green component of pixel#2
pixeldata[7] = blue component of pixel#2
pixeldata[8] = alpha (opacity) component of pixel#2
所以如果你有一个mouseX和mouseY那么你可以得到r,g,b,鼠标下的值,如下所示:
// get the offset in the array where mouseX,mouseY begin
var offset=(imageWidth*mouseY+mouseX)*4;
// read the red,blue,green and alpha values of that pixel
var red = pixeldata[offset];
var green = pixeldata[offset+1];
var blue = pixeldata[offset+2];
var alpha = pixeldata[offset+3];
这是一个在画布上绘制色轮并在鼠标下显示RGBA的演示:
答案 2 :(得分:1)
一种方法,使用.createImageData()
:
window.onload = function() {
var canvas = document.getElementById("colDisp");
var frame = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
var imagedata = frame.createImageData(width, height);
var index, x, y;
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
index = (x * width + y) * 4;
imagedata.data[index + 0] = x;
imagedata.data[index + 1] = y;
imagedata.data[index + 2] = x + y - 255;
imagedata.data[index + 3] = 255;
}
}
frame.putImageData(imagedata, 0, 0);
};