caleb531 / jcanvas

A jQuery plugin that makes the HTML5 canvas easy to work with.
https://projects.calebevans.me/jcanvas/
MIT License
626 stars 192 forks source link

How to make eraser with mouse #117

Closed shariful2011 closed 11 years ago

shariful2011 commented 11 years ago

I want to erase any drawing using mouse which are created using mouse also. How to do so? I created drawing using drawLine, drawRect etc.

caleb531 commented 11 years ago

You can try using the clearCanvas() method which, in addition to clearing the entire canvas, accepts x, y, width, and height properties so you can clear only a portion of the canvas.

http://calebevans.me/projects/jcanvas/docs/clearCanvas/#clear-a-section

-Caleb

shariful2011 commented 11 years ago

I tried as following without any luck: function eraser(){ // Cache canvas element $canvas = $("canvas"); // Run code on mousedown $canvas.mousedown(function(event) { $canvas.clearCanvas({x:event.offsetX, y:event.offsetY, width:$("#linewidth").html(), height:$("#linewidth").html()}); }); }

caleb531 commented 11 years ago

The values for the width and height properties (in the call to clearCanvas) should be numbers, not strings.

-Caleb

shariful2011 commented 11 years ago

Still no success, it draws black line instead clear: function eraser(){ // Cache canvas element $canvas = $("canvas"); // Run code on mousedown $canvas.mousedown(function(event) { $canvas.clearCanvas({x:event.offsetX, y:event.offsetY, width:parseInt($("#linewidth").html()), height:parseInt($("#linewidth").html())}); }); }

caleb531 commented 11 years ago

You need to convert your html() method calls from strings to numbers using the parseFloat() function.

width:parseFloat($("#linewidth").html()), height:parseFloat($("#linewidth").html())});
shariful2011 commented 11 years ago

Still not success. Why its drawing line instead clear? Am I doing correct way?

caleb531 commented 11 years ago

Perhaps it's because the mousedown event (that's drawing the black line segments) is still bound to the canvas. Therefore, you probably need to add some flag for detecting when you're erasing, so it doesn't erase and draw at the same time.

-Caleb

shariful2011 commented 11 years ago

Though its clearing but on mouse move it redraw the line. Below is my code for drawLine and erase: function drawpencil(){ // Cache canvas element $canvas = $("#can" + vcurrentpage + "");//$("canvas"); // Run code on mousedown $canvas.mousedown(function(event) { if (!draggable && !erasing) {
// Create line layer $canvas.drawLine({ layer: true, strokeStyle: $("#colorselect").val(), strokeWidth: $("#linewidth").html(), x1: event.offsetX, y1: event.offsetY, // Store data on layer data: { pressed: true, joints: 1 }, cursors: { // Show pointer on hover mouseover: "pointer", // Show 'move' cursor on mousedown mousedown: "move", // Revert cursor on mouseup mouseup: "pointer" } });

        // Get last layer
        layer = $canvas.getLayer(-1);

    }   
});

// Run code on mousemove
$canvas.mousemove(function(event) {
  // If user's mouse is down
  if (typeof layer.data != 'undefined'){
      if (layer && layer.data.pressed && !draggable && !erasing) {
        // Increment number of joints
        layer.data.joints += 1;
        // Add to line path
        layer['x' + layer.data.joints] = event.offsetX;
        layer['y' + layer.data.joints] = event.offsetY;
        $canvas.drawLayers();
      }
  }
});

// Run code on mouseup
$canvas.mouseup(function(event) {
  // Is user's mouse is down
  if (typeof layer.data != 'undefined'){
      if (layer && layer.data.pressed === true) {
        // Stop drag
        layer.data.pressed = false;
      }
  }
});

}

function eraser(){ // Cache canvas element $canvas = $("canvas"); // Run code on mousedown $canvas.mousedown(function(event) { $canvas.clearCanvas({x:event.offsetX, y:event.offsetY, width:parseInt($("#linewidth").html()), height:parseInt($("#linewidth").html())}); }); }

caleb531 commented 11 years ago

Oh, I think I see now.

The issue is that the line path you're creating when you mousedown on the canvas is a jCanvas layer. jCanvas layers are redrawn periodically (including when you move the mouse on the canvas).

At this point, you would have to rethink your approach, because if the line segments you draw cannot be layers, then you have to somehow draw what's been previously been drawn on the canvas.

For what it's worth, check out an app I made a while back, called Painter. It doesn't use jCanvas layers at all, but rather, it captures each state of the canvas as PNG images, and then reapplies them when drawing (hence previous drawings remain). If you'd like, you can send me an email and I'll be happy to share the code with you.

-Caleb