Html5画布任意形状

时间:2013-11-06 08:19:51

标签: javascript canvas hittest

我正在尝试开发可以在画布中渲染图像和文本的程序。我试图在画布上处理点击图像,但它适用于可直接图像。

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

如果有人熟悉,我正在寻找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;

2 个答案:

答案 0 :(得分:6)

使用纯JavaScript + canvas

的解决方案

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

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

    在这个例子中,我将使用离屏画布。

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

    Modified fiddle here

    /// 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没问题,您应该在发布时将图像托管在与页面相同的域中。

答案 1 :(得分:0)

我建议使用EaselJS,其具有与在Actionscript中的工作方式类似的hitTest方法:

myDisplayObject.hitTest(localX, localY);

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