Reputation: 526
here i have a program that draw a polygon on canvas. problem is it draw 1 polygon only.i cannot seems to solve the problem as why i am only able to draw 1 polygon. After i finish drawing my first shape the cursor move over canvas and nothing happens.
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="board">
<canvas id="canvas" width="300" height="300" style="border: 1px solid black;"></canvas>
<br /><br />
<input type="button" value="Save" onclick="save();" />
<input type="button" value="reset" onclick="reset(); " />
Couleur : <select id="color" onchange="changeColor(this.options[this.selectedIndex].value);">
<option value="red" selected="selected">Red</option>
<option value="blue" selected="selected">Blue</option>
<option value="green" selected="selected">green</option>
<option value="black" selected="selected">black</option>
<option value="yellow" selected="selected">yellow</option>
</select>
</p>
</div><!-- END board -->
</body>
</html>
<style>
body {
margin: 0;
}
#board {
margin: 0 auto;
width: 500px;
}
#myCanvas {
border: 3px dotted #000;
}
</style>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<script type="text/javascript">
var END_CLICK_RADIUS = 5;
//the max number of points of your poygon
var MAX_POINTS = 8;
var mouseX = 0;
var mouseY = 0;
var isStarted = false;
var points = null;
var canvas = null;
var ctx = null;
window.onload = function() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
changeColor("red");
canvas.addEventListener("click", function(e) {
var x = e.clientX-canvas.offsetLeft;
var y = e.clientY-canvas.offsetTop;
if(isStarted) {
//drawing the next line, and closing the polygon if needed
if(Math.abs(x - points[0].x) < END_CLICK_RADIUS && Math.abs(y - points[0].y) < END_CLICK_RADIUS) {
isStarted = false;
} else {
points[points.length] = new Point(x, y);
if(points.length >= MAX_POINTS) {
isStarted = false;
}
}
} else if(points == null) {
//opening the polygon
points = new Array();
points[0] = new Point(x, y);
isStarted = true;
}
}, false);
//we just save the location of the mouse
canvas.addEventListener("mousemove", function(e) {
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
}, false);
//refresh time
setInterval("draw();", 100);
}
//changes the color of the draw
function changeColor(color) {
ctx.strokeStyle = color;
}
//object representing a point
function Point(x, y) {
this.x = x;
this.y = y;
}
//resets the application
function reset() {
isStarted = false;
points = null;
}
//alerts the point list
function save() {
if(points == null) {
alert("nothing to save");
} else {
var s = "";
for(var a in points) {
//inversing y axis by (canvas.height - points[a].y)
s += "(" + points[a].x + "," + (canvas.height - points[a].y) + ")\n";
}
alert(s);
}
}
//draws the current chape
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
if(points != null && points.length > 0) {
ctx.moveTo(points[0].x, points[0].y);
for(i = 1 ; i < points.length ; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
if(isStarted) {
ctx.lineTo(mouseX, mouseY);
} else {
ctx.lineTo(points[0].x, points[0].y);
}
}
ctx.stroke();
}
</script>
Upvotes: 0
Views: 518
Reputation: 1871
Consider the data storage and the flow of your code.
A shape is an array of points which is built from click to click. After intervals of 100 milliseconds the shape so far is drawn. The shape is drawn by clearing the canvas and drawing all the points in the array so the only shape that can be drawn is the one stored in the points array.
The conditions for opening a new polygon are
isStarted is false
points == null
isStarted is set to false when the polygon is completed but points is not set to null.
PROBLEM setting points to null wipes out the shape just completed.
SOLUTION an array of shapes.
Also you do not need to draw at set intervals you can draw on the click of the mouse.
Try out the suggestion below.
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="board">
<canvas id="canvas" width="300" height="300" style="border: 1px solid black;"></canvas>
<br /><br />
<input type="button" value="Save" onclick="save();" />
<input type="button" value="reset" onclick="reset(); " />
Couleur : <select id="color" onchange="changeColor(this.options[this.selectedIndex].value);">
<option value="red" selected="selected">Red</option>
<option value="blue" selected="selected">Blue</option>
<option value="green" selected="selected">green</option>
<option value="black" selected="selected">black</option>
<option value="yellow" selected="selected">yellow</option>
</select>
</p>
</div><!-- END board -->
</body>
</html>
<style>
body {
margin: 0;
}
#board {
margin: 0 auto;
width: 500px;
}
#myCanvas {
border: 3px dotted #000;
}
</style>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<script type="text/javascript">
var END_CLICK_RADIUS = 5;
//the max number of points of your poygon
var MAX_POINTS = 8;
var mouseX = 0;
var mouseY = 0;
var isStarted = false;
var points = null;
var shapes=new Array();
var canvas = null;
var ctx = null;
window.onload = function() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
changeColor("red");
canvas.addEventListener("click", function(e) {
var x = e.clientX-canvas.offsetLeft;
var y = e.clientY-canvas.offsetTop;
if(isStarted) {
//drawing the next line, and closing the polygon if needed
if(Math.abs(x - points[0].x) < END_CLICK_RADIUS && Math.abs(y - points[0].y) < END_CLICK_RADIUS) {
isStarted = false;
points[points.length] = new Point(points[0].x, points[0].y); //stores closing point
shapes.push(points); //pushes the array points into the array shapes
} else {
points[points.length] = new Point(x, y);
if(points.length >= MAX_POINTS) {
isStarted = false;
points[points.length] = new Point(points[0].x, points[0].y); //stores closing point
shapes.push(points);
}
}
} else {
//opening the polygon
points = new Array();
points[0] = new Point(x, y);
isStarted = true;
}
draw();
}, false);
//we just save the location of the mouse
canvas.addEventListener("mousemove", function(e) {
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
}, false);
//refresh time
setInterval("draw();", 100);
}
//changes the color of the draw - CURRENTLY SAME FOR ALL SHAPES
function changeColor(color) {
ctx.strokeStyle = color;
}
//object representing a point
function Point(x, y) {
this.x = x;
this.y = y;
}
//resets the application
function reset() {
isStarted = false;
points = null;
}
//alerts the point list - NOTE UPDATE THIS FUNCTION TO SAVE ALL SHAPES
function save() {
if(points == null) {
alert("nothing to save");
} else {
var s = "";
for(var a in points) {
//inversing y axis by (canvas.height - points[a].y)
s += "(" + points[a].x + "," + (canvas.height - points[a].y) + ")\n";
}
alert(s);
}
}
//draws the current shape
function draw() {
var prevpoints;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
//draws polygon under construction
if(points != null && points.length > 0) {
ctx.moveTo(points[0].x, points[0].y);
for(i = 1 ; i < points.length ; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
if(isStarted) {
ctx.lineTo(mouseX, mouseY);
} else {
ctx.lineTo(points[0].x, points[0].y);
}
}
// draws previous shapes in any exist
for (var j = 0; j<shapes.length; j++) {
prevpoints=shapes[j];
ctx.moveTo(prevpoints[0].x, prevpoints[0].y);
for(i = 1 ; i < prevpoints.length ; i++) {
ctx.lineTo(prevpoints[i].x, prevpoints[i].y);
}
}
ctx.stroke();
}
</script>
NOTE I have made NO changes to the save function you will need to take into account that there are several shapes
Upvotes: 1