个性化阅读
专注于IT技术分析

如何使用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)
    };
}

即使用户缩放文档, 因为使用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的侦听器附加到该图像, 导航到”结果”选项卡并对其进行测试。

玩得开心

赞(0)
未经允许不得转载:srcmini » 如何使用JavaScript在单击或鼠标事件中从画布获取像素颜色

评论 抢沙发

评论前必须登录!