如何使用JavaScript在单击或鼠标事件中从画布获取像素颜色

本文概述

  • 检索事件中的鼠标位置
  • 在画布上绘制图像(测试目的)
  • 根据位置检索像素数据
如果你能够从画布的单个像素, 交互式颜色选择器等中提取颜色, 则可以创建许多实用程序。使用纯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)}; }

【如何使用JavaScript在单击或鼠标事件中从画布获取像素颜色】即使用户缩放文档, 因为使用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 clickvar eventLocation = getEventLocation(this, event); // Get the data of the pixel according to the location generate by the getEventLocation functionvar context = this.getContext('2d'); var pixelData = http://www.srcmini.com/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的侦听器附加到该图像, 导航到” 结果” 选项卡并对其进行测试。
玩得开心

    推荐阅读