鼠标是在画布上的用户绘制区域

时间:2013-06-22 20:34:41

标签: html5 canvas mouseevent detection

基本上,用户上传图片然后可以在上面绘画,并保存结果。然后,另一个用户可以查看照片,如果他们点击与绘画相同的区域,则会发生一些事情。 因此,用户1可以通过在照片上绘图来使用户2的区域可点击。

现在上传位很好,并且在tutorialexample的帮助下进行绘画我已经被忽略了。但是定义可点击的区域有点困难。对于像矩形这样容易的东西,我做了一个example

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');


 var button = new Object();
    button.x = 50;
    button.y = 50;
    button.width = 50;
    button.height = 50;
    button.rgb = "rgb(0, 0, 255)";
    function drawbutton(buttonobject)
    {
        context.fillStyle = buttonobject.rgb;
        context.fillRect (buttonobject.x, buttonobject.y, buttonobject.width, buttonobject.height);
        context.strokeRect(buttonobject.x, buttonobject.y, buttonobject.width, buttonobject.height);
    }
    drawbutton(button);


    function checkIfInsideButtonCoordinates(buttonObj, mouseX, mouseY)
    {
        if(((mouseX > buttonObj.x) && (mouseX < (buttonObj.x + buttonObj.width))) && ((mouseY > buttonObj.y) && (mouseY < (buttonObj.y + buttonObj.height))))
            return true;
        else
            return false;
    }

    $("#myCanvas").click(function(eventObject) {
        mouseX = eventObject.pageX - this.offsetLeft;
        mouseY = eventObject.pageY - this.offsetTop;

        if(checkIfInsideButtonCoordinates(button, mouseX, mouseY))
        {
            button.rgb = "rgb(0, 255, 0)";
            drawbutton(button);
        } else {
            button.rgb = "rgb(255, 0, 0)";
            drawbutton(button);
        }
    });

但是当谈到其他形状如圆圈,或者只是有人扼杀页面时,您会如何检测?

有人认为我使用了已编辑的图层,使其隐藏,并检测到蓝色的像素颜色from here,但这限制了照片的颜色使用,我不完全确定如何实现它。还有其他想法吗?

编辑:

我在经过一些修补后想出了圆圈,使用毕达哥拉斯定理来判断鼠标坐标是否小于半径,但这假定圆心为0,0,那么然后用圆圈实际中心偏移鼠标。 example

function checkIfInsideButtonCoordinates(buttonObj, mouseX, mouseY) {
actualX = mouseX - buttonObj.x
actualY = mouseY - buttonObj.y
mousesqX = actualX * actualX
mousesqY = actualY * actualY
sqR = buttonObj.r * buttonObj.r
sqC = mousesqX + mousesqY

if (sqC < sqR) return true;
    else return false;
}

1 个答案:

答案 0 :(得分:1)

以下是如何测试用户#2是否在用户#1的画作中

创建第二个用于测试用户#2是否在用户#1画作中的画布。

命中测试画布与绘图画布的大小相同,但它只包含用户#1的绘画......而不是图像。

当用户#1正在绘画时,也会在热门画布上绘制他们的画作。

enter image description here

当用户#1完成绘画时,从命中画布中保存所有绘画。

您至少有两种方法可以从热门画布中保存用户#1的画作:

  • 序列化重新创建用户#1绘制的形状/路径所需的所有画布命令。
  • 使用canvas.toDataURL将命中画布保存为图像。

当用户#2点击时,检查命中画布上的相应像素是否已填充或是否透明(alpha> 0)。

    // getImageData for the hit-test canvas (this canvas just contains user#1's paintings)
    imageDataData=hitCtx.getImageData(0,0,hit.width,hit.height).data;

    // look at the pixel under user#2's mouse
    // return true if that pixel is filled (not transparent) 
    function isHit(x,y){
        var pixPos=(x+y*hitWidth)*4+3; 
        return( imageDataData[pixPos]>10)
    }

这是代码和小提琴:http://jsfiddle.net/m1erickson/etA5a/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:15px; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var hit=document.getElementById("hit");
    var hitCtx=hit.getContext("2d");
    var user2=document.getElementById("user2");
    var ctx2=user2.getContext("2d");

    var canvasOffset=$("#user2").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    var imageDataData;
    var hitWidth=hit.width;

    var img=document.createElement("img");
    img.onload=function(){

        // left canvas: image+user#1 paintings
        ctx.globalAlpha=.25;
        ctx.drawImage(img,0,0);
        ctx.globalAlpha=1.00;
        scribble(ctx,"black");

        // mid canvas: just user#1 paintings (used for hittests)
        scribble(hitCtx,"black");

        // right canvas: user#2
        ctx2.drawImage(img,0,0);

        imageDataData=hitCtx.getImageData(0,0,hit.width,hit.height).data;

    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";


    function scribble(context,color){
        context.beginPath();
        context.moveTo(70,2);
        context.lineTo(139,41);
        context.lineTo(70,41);
        context.closePath();
        context.rect(39,54,22,30);
        context.arc(73,115,3,0,Math.PI*2,false);
        context.fillStyle=color;
        context.fill();
    }


    function handleMouseMove(e){
      var mouseX=parseInt(e.clientX-offsetX);
      var mouseY=parseInt(e.clientY-offsetY);

      // If user#2 has a hit on user#1's painting, mid-canvas turns red
      var color="black";
      if(isHit(mouseX,mouseY)){ color="red"; }
      scribble(hitCtx,color);
    }


    function isHit(x,y){
        var pixPos=(x+y*hitWidth)*4+3; 
        return( imageDataData[pixPos]>10)
    }


    $("#user2").mousemove(function(e){handleMouseMove(e);});


}); // end $(function(){});
</script>

</head>

<body>
    <p>Left: original image with user#1 painting</p>
    <p>Mid: user#1 painting only (used for hit-testing)</p>
    <p>Right: user#2 (move mouse over hit areas)</p>
    <canvas id="canvas" width=140 height=140></canvas>
    <canvas id="hit" width=140 height=140></canvas>
    <canvas id="user2" width=140 height=140></canvas><br>
</body>
</html>