本文概述
如果你能够从画布的单个像素, 交互式颜色选择器等中提取颜色, 则可以创建许多实用程序。使用纯JavaScript而不使用任何类型的库, 此任务相对容易实现。
要从特定画布的像素中检索颜色, 我们将执行以下操作:
- 检索鼠标事件的位置。
- 使用坐标选择画布上的数据。
- 使用像素的RGBA数据。
让我们开始吧 !
检索事件中的鼠标位置
由于存在许多可能的错误以及用户可能要做的事情, 我们需要尽可能准确, 因此, 为了保证鼠标坐标是可靠的, 我们将根据画布的位置检索它们。
使用以下函数检索元素(在本例中为canvas)的位置, 它将DOM元素作为第一个参数。但是, 此函数将由将在内部获取点击位置的函数内部使用。
/**
* Return the location of the element (x, y) being relative to the document.
*
* @param {Element} obj Element to be located
*/
function getElementPosition(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
前一个方法返回作为文档中第一个参数(在这种情况下为画布)给出的元素的位置(具有x和y坐标的对象)。
现在我们可以获取画布的位置, 下面的方法将成为关心画布上单击位置(或附加到画布的另一个鼠标事件)的方法:
/**
* return the location of the click (or another mouse event) relative to the given element (to increase accuracy).
* @param {DOM Object} element A dom element (button, canvas, input etc)
* @param {DOM Event} event An event generate by an event listener.
*/
function getEventLocation(element, event){
// Relies on the getElementPosition function.
var pos = getElementPosition(element);
return {
x: (event.pageX - pos.x), y: (event.pageY - pos.y)
};
}
即使用户缩放文档, 因为使用getElementPosition可以提高getEventLocation函数的准确性, getEventLocation方法也会根据鼠标事件(单击, 鼠标移动等)返回坐标(x, y)。
在画布上绘制图像(测试目的)
本文假定你知道如何在画布上绘制图像, 或者你已经使用路径绘制了某些内容, 因此希望从像素等中检索颜色。但是, 如果你没有任何内容, 可以使用以下功能在画布上绘制图像(从base64或Internet URL):
var canvas = document.getElementById("canvas");
/**
* Draw an image (from your own domain or base64)
* @param {String} sourceurl
*/
function drawImageFromWebUrl(sourceurl){
var img = new Image();
img.addEventListener("load", function () {
// The image can be drawn from any source, the canvas will be filled with the image.
canvas.getContext("2d").drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
});
img.setAttribute("src", sourceurl);
}
注意:你可以根据需要绘制任何图像, 但是, 如果图像不是来自你自己的域(yourdomain.com, 并且图像来自otherdomain.com), 那么你将遇到”画布污染”的问题, 请阅读有关此问题的更多信息。因此, 在我们的示例中, 我们将使用base64字符串而不是Web图像。
根据位置检索像素数据
现在从像素中检索颜色, 我们将使用画布上下文中的getImageData方法, 并将根据单击位置(或任何鼠标事件)将其限制为1个像素(x1, y1)你想要的)事件。
以下代码段显示了如何在画布的click事件上从像素中检索颜色:
注意:如果需要, 可以改用jQuery事件侦听器, 仅确保提供事件变量。
var canvas = document.getElementById("canvas");
canvas.addEventListener("click", function(event){
// Get the coordinates of the click
var eventLocation = getEventLocation(this, event);
// Get the data of the pixel according to the location generate by the getEventLocation function
var context = this.getContext('2d');
var pixelData = context.getImageData(eventLocation.x, eventLocation.y, 1, 1).data;
// If transparency on the pixel , array = [0, 0, 0, 0]
if((pixelData[0] == 0) && (pixelData[1] == 0) && (pixelData[2] == 0) && (pixelData[3] == 0)){
// Do something if the pixel is transparent
}
// Convert it to HEX if you want using the rgbToHex method.
// var hex = "#" + ("000000" + rgbToHex(pixelData[0], pixelData[1], pixelData[2])).slice(-6);
}, false);
pixelData是一个UInt8ClampedArray, 具有4个项目([0] =>红色, [1] =>绿色, [2] =>蓝色, [3] => alpha(透明度))。
那就是, 根据需要操纵颜色并根据需要使用它。如果需要, 你甚至可以使用以下方法将RGBA转换为十六进制颜色:
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
在上面的代码起作用的情况下, 使用以下小提琴演奏。附带的示例将在画布上绘制base64图像, 然后将mousemove的侦听器附加到该图像, 导航到”结果”选项卡并对其进行测试。
玩得开心
评论前必须登录!
注册