photosynthesis
photosynthesis

Reputation: 2890

How to differentiate click and mousedown event in JavaScript?

I have a canvas, I want to draw dots when user clicked and draw a line when clicked and dragged.

In order to identify whether I should generate a line when mouse is moving on the canvas, I set a variable 'isDrawing' to tell if the user has clicked on the canvas before moving on it. I bind 'mousedown' event to the canvas and set 'isDrawing' to true when the event is triggered. If it is true I will start drawing a line, otherwise I will do nothing to this behavior. But the problem is when user clicked to draw dots, the 'isDrawing' is also set to true because the 'mousedown' event is triggered by the click. My question is how to differentiate the click and mousedown event so that when user just clicked somewhere the 'mousedown' event will not be triggered? thanks.

Upvotes: 2

Views: 1907

Answers (2)

Kai
Kai

Reputation: 1225

Here's an example using pure javascript small and compact: http://jsfiddle.net/kychan/2t97S/

function e(id) { return document.getElementById(id); }

var box = e('box'),
    ctx = box.getContext('2d'),
    w   = box.width,
    h   = box.height,
    mx  = 0,
    my  = 0
;

ctx.fillStyle = '#333';
ctx.fillRect(0,0,w,h);
ctx.fillStyle = '#FF0000';
ctx.strokeStyle= '#FF0000';

box.addEventListener('mousedown', function(e) {
    mx = e.pageX - box.offsetLeft,
    my = e.pageY - box.offsetTop;
}, false);

//    reduces dender.
function d(i,c) {
    return (c-10<i && c+10>i);
}
box.addEventListener('mouseup', function(e) {
    var nx = e.pageX - box.offsetLeft,
        ny = e.pageY - box.offsetTop;

    ctx.beginPath();
    if (d(mx,nx) && d(my,ny)) {
        ctx.arc(mx,my,1, 0, Math.PI*2, false);
    }else{
        ctx.moveTo(mx, my);
        ctx.lineTo(nx, ny);
    }
        ctx.closePath();
    ctx.stroke();
    mx=nx, my=ny;
}, false);

Upvotes: 1

markE
markE

Reputation: 105015

@Aaron has the start of a good idea...Add your dot in mouseup instead of mousedown.

In mouseup if the mouse has been dragged less than 5 total pixels then treat the mouseup as a click rather than a drag. (5 pixels is an example--adjust for your desired tolerances).

In mousemove, delay drawing your line until the mouse has been dragged at least 5 pixels.

Here's example code and a Demo: http://jsfiddle.net/m1erickson/ZTuKP/

<!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; }
    #canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();

    var isDown=false;
    var lastX,lastY;
    var dragHash;

    function handleMouseDown(e){
      e.preventDefault();
      e.stopPropagation();

      lastX=parseInt(e.clientX-offsetX);
      lastY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      dragHash=0;
      isDown=true;
    }

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

      if(dragHash<5){
          alert("It's a click...add a dot");
      }else{
          alert("You've been dragging");
      }

      // Put your mouseup stuff here
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){return;}
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here
      var dx=mouseX-lastX;
      var dy=mouseY-lastY;
      lastX=mouseX;
      lastY=mouseY;

      // accumulate the drag distance 
      // (used in mouseup to see if this is a drag or click)
      dragHash+=Math.abs(dx)+Math.abs(dy);

      if(dragHash>4){
          // it's a drag operation, draw the line
      }

    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});



}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Upvotes: 4

Related Questions