Reputation: 12711
Using the below code i'm able to draw lines with mouse points on the canvas. I need to detect when the drawing lines completes a shape and fill it with some color.
<script language="javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var worksheetCanvas = $('#worksheet-canvas');
var context = worksheetCanvas.get(0).getContext("2d");
var clicked = false;
// The array of stored lines
var storedLines = [];
// The object for the last stored line
var storedLine = {};
var mouse = {
x: -1,
y: -1
}
var parentOffset = $('#canvas-holder').parent().offset();
worksheetCanvas.click(function (e) {
clicked = true;
mouse.x = e.pageX - parentOffset.left;
mouse.y = e.pageY - parentOffset.top;
context.moveTo(mouse.x, mouse.y);
// Push last line to the stored lines
if (clicked) {
storedLines.push({
startX: storedLine.startX,
startY: storedLine.startY,
endX: mouse.x,
endY: mouse.y
});
}
// set last line coordinates
storedLine.startX = mouse.x;
storedLine.startY = mouse.y;
$(this).mousemove(function (k) {
// clear the canvas
context.clearRect(0, 0, 960, 500);
context.beginPath();
context.strokeStyle = "rgb(180,800,95)";
// draw the stored lines
for (var i = 0; i < storedLines.length; i++) {
var v = storedLines[i];
context.moveTo(v.startX, v.startY);
context.lineTo(v.endX, v.endY);
context.stroke();
}
context.moveTo(mouse.x, mouse.y);
context.lineTo(k.pageX - parentOffset.left, k.pageY - parentOffset.top);
context.stroke();
context.closePath();
})
})
});
</script>
</head>
<body>
<div id="canvas-holder">
<canvas id="worksheet-canvas" width="960" height="500" style="background:black;">
</canvas>
</div>
</body>
</html>
Upvotes: 1
Views: 2333
Reputation: 105015
[Edit after clarification by Poster]
This code will draw/continue a polyline to where ever a user clicks next.
If the user clicks back in the green circle where they started, the polylines are filled.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/qwd2a/
<!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>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<style>
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasMouseX;
var canvasMouseY;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var storedLines=[];
var startX=0;
var startY=0;
var radius=7;
ctx.strokeStyle="orange";
ctx.font = '12px Arial';
$("#canvas").mousedown(function(e){handleMouseDown(e);});
function handleMouseDown(e){
canvasMouseX=parseInt(e.clientX-offsetX);
canvasMouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
if(hitStartCircle(canvasMouseX, canvasMouseY)){
fillPolyline();
return;
}
storedLines.push({x:canvasMouseX,y:canvasMouseY});
if(storedLines.length==1){
startX=canvasMouseX;
startY=canvasMouseY;
ctx.fillStyle="green";
ctx.beginPath();
ctx.arc(canvasMouseX, canvasMouseY, radius, 0 , 2 * Math.PI, false);
ctx.fill();
}else{
var c=storedLines.length-2;
ctx.strokeStyle="orange";
ctx.lineWidth=3;
ctx.beginPath();
ctx.moveTo(storedLines[c].x,storedLines[c].y);
ctx.lineTo(canvasMouseX, canvasMouseY);
ctx.stroke();
}
}
function hitStartCircle(x,y){
var dx=x-startX;
var dy=y-startY;
return(dx*dx+dy*dy<radius*radius)
}
function fillPolyline(){
ctx.strokeStyle="red";
ctx.fillStyle="blue";
ctx.lineWidth=3;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.moveTo(storedLines[0].x,storedLines[0].y);
for(var i=0;i<storedLines.length;i++){
ctx.lineTo(storedLines[i].x,storedLines[i].y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
storedLines=[];
}
$("#clear").click(function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
storedLines=[];
});
}); // end $(function(){});
</script>
</head>
<body>
<p>Click to draw lines</p>
<p>Click back in the green circle to close+fill</p><br/>
<canvas id="canvas" width=300 height=300></canvas><br/>
<button id="clear">Clear Canvas</button>
</body>
</html>
[Previous answer based on less information]
It looks like you are trying to:
If I may suggest a couple of cleanups in your code:
This is a good way to get the mouse position on your canvas:
// before you begin listening for mouseclicks,
// get the canvas’ screen position into offsetX/offsetY
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
// then when a mousedown event occurs
// use e.clientX/Y (not e.pageX/Y) to get the mouse position on the canvas
canvasMouseX=parseInt(e.clientX-offsetX);
canvasMouseY=parseInt(e.clientY-offsetY);
When you are actually drawing the path with the context and storedLines:
Do context.fill() and context.stroke() -- if you don't fill(), you won't get color fill.
// close a path
context.closePath();
context.fillStyle=”blue”;
context.strokeStyle=”rgb(180,80,95)”;
context.fill();
context.stroke();
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/zYsQh/
<!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>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<style>
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasMouseX;
var canvasMouseY;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var storedLines=[];
ctx.strokeStyle="orange";
ctx.font = '12px Arial';
$("#canvas").mousedown(function(e){handleMouseDown(e);});
function handleMouseDown(e){
canvasMouseX=parseInt(e.clientX-offsetX);
canvasMouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
storedLines.push({x:canvasMouseX,y:canvasMouseY});
var count=storedLines.length;
var X=canvasMouseX-(count<10?4:7);
ctx.strokeStyle="orange";
ctx.fillStyle="black";
ctx.lineWidth=1;
ctx.beginPath();
ctx.arc(canvasMouseX, canvasMouseY, 8, 0 , 2 * Math.PI, false);
ctx.fillText(storedLines.length, X, canvasMouseY+4);
ctx.stroke();
}
$("#draw").click(function(){
ctx.strokeStyle="red";
ctx.fillStyle="blue";
ctx.lineWidth=3;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.moveTo(storedLines[0].x,storedLines[0].y);
for(var i=0;i<storedLines.length;i++){
ctx.lineTo(storedLines[i].x,storedLines[i].y);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
storedLines=[];
});
$("#clear").click(function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
storedLines=[];
});
}); // end $(function(){});
</script>
</head>
<body>
<p>Click to create storedLines[]</p>
<p>Then press the Draw button to fill the path</p><br/>
<canvas id="canvas" width=300 height=300></canvas><br/>
<button id="clear">Clear Canvas</button>
<button id="draw">Draw</button>
</body>
</html>
Upvotes: 3
Reputation: 5018
If your storedLines array consists of exact copy of all values in it then you have drawn a shape otherwise you haven't yet ...
Example:
You draw a triangle by drawing three lines
Line1 - (0,0) to (10,0)
Line2 - (10,0) to (5,10)
- Line3 - (5,10) to (0,0)
So that, all points has a copy of it.
Upvotes: 1