2

我正在尝试开发可以在画布中呈现图像和文本的程序。我试图处理画布中的图像点击,但它适用于可调整的图像。

我的问题:您知道处理单击画布中图像的可见部分(不是透明部分)的解决方案或框架吗?

如果有人熟悉的话,我正在寻找 ActionScript hitTestObject 函数的 javascript 实现。

这是带有可调整命中文本的简单算法:http: //jsfiddle.net/V92Gn/298/

var hitted = e.clientX >= position.x && 
    e.clientX <= position.x + logoImg.width && 
    e.clientY >= position.y && 
    e.clientY <= position.y + logoImg.height;
4

2 回答 2

6

使用纯 JavaScript + canvas 的解决方案

对于命中目标与背景混合的情况,您可以做两件事:

  1. 创建一个单独的画布,堆叠在主画布的顶部,在其上绘制目标对象并对该画布进行测试。
  2. 创建一个屏幕外画布,其中包含隔离的目标对象并对其进行测试

在此示例中,我将使用离屏画布。

我们所做的基本上是通过创建一个与图像大小相同的屏幕外画布并在加载时在图像中绘制来复制图像。无论主画布上有什么,这将保护背景并保持透明:

在这里修改小提琴

/// create an off-screen canvas to hold image
var ocanvas = document.createElement('canvas');
var octx = ocanvas.getContext('2d');

logoImg.onload=function(){
    
    /// set off-screen canvas to same size as image
    ocanvas.width = this.width;
    ocanvas.height = this.height;
    octx.drawImage(this, 0, 0);

    ... rest of code

然后使用您现有的代码,但通过调整鼠标位置,我们可以使用hitted您使用的变量来首先检查我们是否在目标对象内。

$(canvas).on('mousemove', function(e) {
    
    /// correct mouse position so it becomes relative to canvas
    var r = canvas.getBoundingClientRect(),
        x = e.clientX - r.left,
        y = e.clientY - r.top;
    
     var hitted = x >= position.x && x <= position.x + logoImg.width &&
                  y >= position.y && y <= position.y + logoImg.height;

现在我们知道我们在矩形内,我们可以通过补偿对象位置从屏幕外画布中提取一个像素:

    if (hitted === true) {
        /// extract a single pixel at the adjusted position
        var pixel = octx.getImageData(x - position.x, y - position.y, 1, 1).data;

        /// set hitted again based on alpha value is 0 or not
        hitted = pixel[3] > 0;
    }

    ...

正如您在修改后的小提琴中看到的那样,我们仅在目标中的实际像素上将您使用的类更改为红色,无论它的背景是什么(单独绘制时)。

最后谈谈 CORS:在这种情况下,当您使用 DropBox 时,您可以通过crossOrigin在设置源之前激活图像对象上的属性来请求图像的 CORS 使用:

logoImg.crossOrigin = '';   /// this is the same as setting anonymous
logoImg.src="http://dl.dropbox.com/..."; 

由于 DropBox(和 ImgUr.com 等图像共享网站)支持 CORS 使用,它们将允许请求,因此我们可以从图像中提取像素。

但是,如果服务器不允许这样做,我们将无法执行此操作。为确保 CORS 正常,您应该在发布图像时将图像托管在与页面相同的域中。

于 2013-11-07T07:54:24.737 回答
-1

我建议使用EaselJS,它的 hitTest 方法类似于它在 Actionscript 中的工作方式:

myDisplayObject.hitTest(localX, localY);

在这里您可以找到一些展示该技术的演示: http: //shallaazm.com/createjs/easeljs/tutorials/HitTest/

于 2013-11-06T10:28:18.220 回答