2014-03-25 21 views
0

我试图使用Canvas实现ColorPicker只是为了好玩。但我似乎失去了。因为我的浏览器在加载时由于所有这些循环而冻结了一段时间。 我加入这个脚本的结果的截图: enter image description here
使用JavaScript和Canvas的ColorPicker实现

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

你能提供一个jsfiddle链接与你所做的一切吗? – micnic

+0

嗨@micnic这里的codepen链接:http://cdpn.io/Ebghn – dragfire

回答

2

不是每个像素都调用fillRect,而是使用原始RGBA缓冲区可能效率更高。您可以使用context.getImageData获取一个,使用颜色值填充它,然后使用context.putImageData一次性将其放回。

请注意,您当前的代码覆盖每个单个像素255次,每个可能的蓝色值一次。每个像素的最终传递是255蓝色,所以在输出中看不到灰色和黑色。

寻找一种将所有可能的RGB值映射到二维图像的好方法并不是微不足道的,因为RGB是一个三维色彩空间。这样做有很多策略,但没有一个对任何可能的用例都是最佳的。您可以在AllRGB.com上找到针对此问题的一些创造性解决方案。其中一些可能适用于某些使用情况下的颜色选择器。

+0

我不明白...当没有来源获得各自的rgb值时,你将如何使用getImageData()? – dragfire

+0

@LucyJaa当你在一个空白的画布上做的时候,你会得到0,0,0,0的RGBA值(别忘了把alpha值设置为255或者结果是透明的)。或者,您可以使用createImageData创建一些空白图像数据。 – Philipp

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); 
}; 

http://codepen.io/anon/pen/vGcaF

+0

请解释这一行index =(y * 255 + x)* 4; @micnic – dragfire

+0

还有一个疑问...如果我改变画布的宽度和高度,会影响结果吗? – dragfire

+0

'形象。data'是一个带有'rgba'值的单维数组,你必须从x和y坐标获取和索引变换,以便不会有任何画布维度问题我更新了我的答案 – micnic

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]; 

下面是鼠标下绘制在画布上colorwheel并显示RGBA演示:

http://jsfiddle.net/m1erickson/94BAQ/

+0

棒极了! Muchos,muchos gracias!我真的很喜欢jsfiddle的回应,他们节省了很多时间搜索回复。 –